3 print_usage () { cat <<'END'
5 to move repository directory, cd to anywhere and
6 cvs-repomove --move local-repo module hostname remote-repo
7 cvs-repomove --move src-hostname src-repo module dst-hostname dst-repo
8 to adjust CVS/Root afterwards, in each working directory
9 cvs-repomove automatically update **/CVS/Root
13 # Copyright 2004-2006 Ian Jackson <ian@chiark.greenend.org.uk>
15 # This script and its documentation (if any) are free software; you
16 # can redistribute it and/or modify them under the terms of the GNU
17 # General Public License as published by the Free Software Foundation;
18 # either version 3, or (at your option) any later version.
20 # chiark-named-conf and its manpage are distributed in the hope that
21 # it will be useful, but WITHOUT ANY WARRANTY; without even the
22 # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
23 # PURPOSE. See the GNU General Public License for more details.
25 # You should have received a copy of the GNU General Public License along
26 # with this program; if not, consult the Free Software Foundation's
27 # website at www.fsf.org, or the GNU Project website at www.gnu.org.
30 # We do things in the following order:
32 # 0. Check things @/..moving-to none/..moved-to
33 # 1. Rename src repo to prevent commits etc. ..moving-to none/..moved-to
34 # 2. Make temporary copy at destination ..moving-to ..tmp
35 # 3. Install temporary copy at destination ..moving-to @
36 # 4. Move aside src repo ..moved-to @
38 fail () { echo >&2 "error: $1"; exit 8; }
39 bad_usage () { echo >&2 "bad usage: $1"; print_usage >&2; exit 12; }
43 while [ $# -gt 0 ]; do
46 --help) print_usage; exit 0 ;;
48 -*) bad_usage "unknown option $1" ;;
59 "moving a module with \`..' in its name is not supported" ;;
61 "moving a subdirectory is not supported" ;;
63 "moving a module whose name starts with \`-' is not supported" ;;
69 /*|.*|-*) fail "bad hostname $dsthost" ;;
73 check_remote_path () {
75 *[^0-9a-zA-Z/._+,-]*) fail \
76 "pathname may not contain metacharacters, sorry" ;;
82 check_hostname "$srchost"
83 check_hostname "$dsthost"
84 check_remote_path "$srcrepo/$module"
85 check_remote_path "$dstrepo/$module"
89 *) bad_usage "destination repo path must be absolute" ;;
92 printf "moving module %s from %s:%s to %s:%s\n" \
93 "$module" "$srchost" "$srcrepo" "$dsthost" "$dstrepo"
95 mn "checking existing repository"
96 "$CVS_RSH" "$srchost" bash -ec "'
97 ls -d -- $srcrepo/CVSROOT >/dev/null
100 dstrepotrans="$(printf '%s\n' "$dstrepo" | tr / :)"
101 movingto="moving-to-$dsthost:$dstrepotrans"
102 resume="$("$CVS_RSH" "$srchost" bash -ec "'
103 if test -d $srcrepo/$module..$movingto; then
104 echo >&2 \" resuming previous attempt at a move\"
106 if test -d $srcrepo/$module; then
107 echo >&2 \"but $srcrepo/$module exists too\"
112 ls -d -- $srcrepo/$module >/dev/null
115 previously=\"$(ls -d -- $srcrepo/$module..moved-to-* 2>/dev/null)\"
117 if [ \"x\$previously\" != x ]; then
118 echo >&2 \" btw, module was once before moved away from here\"
119 mv -- \"\$previously\" \
120 \"\${previously/..moved-to-/..previously-\$(date +%s)-moved-to-}\"
125 mn "checking dst repository"
126 "$CVS_RSH" "$dsthost" bash -ec "'
128 ls -d CVSROOT >/dev/null
129 if test -d $dstrepo/$module; then
130 echo >&2 module already exists in destination repo
133 for f in $module..*; do
136 echo \" btw, module was previously at destn repo\"
138 \"\${f/..moved-to-/..previously-\$(date +%s)-moved-to-}\"
142 echo \" nb: possibly-stale temp/partial copy \$f\"
147 echo >&2 \"error: found unexpected subdir \$f\"
155 "$CVS_RSH" "$srchost" bash -ec "'
156 mv -- $srcrepo/$module $srcrepo/$module..$movingto
160 mn "transferring repo data"
161 tmpid="tmp-$(uname -n).$(date +%s)"
162 "$CVS_RSH" "$srchost" bash -ec "'
163 tar -c -C $srcrepo/$module..$movingto -f - .
164 '" | "$CVS_RSH" "$dsthost" bash -ec "'
166 mkdir $module..$tmpid
168 tar --no-same-owner -xf -
170 test "${PIPESTATUS[*]}" = "0 0"
172 mn "confirming move at destination repo"
173 "$CVS_RSH" "$dsthost" bash -ec "'
175 mv $module..$tmpid $module
178 mn "confirming move at source repo"
179 "$CVS_RSH" "$srchost" bash -ec "'
180 mv -- $srcrepo/$module..$movingto \
181 $srcrepo/$module..moved-to-$dsthost:$dstrepotrans
183 echo "module moved successfully"
186 compute_fqdn_data () {
187 fqdn_data="$(adnshost -s - "$1" 2>/dev/null || true)"
191 module="$(cat CVS/Repository)"
192 oldroot="$(cat CVS/Root)"
195 printf "checking/updating repo for %s\n" "$module"
196 compute_fqdn_data "$(uname -n)"
197 our_fqdn_data="$fqdn_data"
200 mn "chasing geese at $goose"
203 remotehost="${goose%%:*}"
205 check_hostname "$remotehost"
206 check_remote_path "$path/$module"
208 compute_fqdn_data "$remotehost"
209 if [ "x$fqdn_data" = "x$our_fqdn_data" -a \
210 "x$fqdn_data" != x ]; then
216 fail "unknown remote repository string $goose"
223 fail "unknown repository string $goose"
228 if test -d $module; then echo good; exit 0; fi
229 if ls -d $module..moved-to-* 2>/dev/null; then exit 0; fi
233 new_goose_info="$("$CVS_RSH" "$remotehost" \
234 bash -ec "'$check'")"
236 new_goose_info="$( bash -ec "$check")"
238 case "$new_goose_info" in
243 echo >&2 "trail went cold at $goose"
247 goose="$(printf '%s\n' \
248 "${new_goose_info#*..moved-to-}" | \
249 tr : / | sed -e 's,/,:,')"
253 if [ "x$goose" = "x$oldroot" ]; then
254 echo 'repo has not moved - nothing to do'
257 mn "found new repo, adjusting working tree"
258 cvs-adjustroot "$oldroot" "$goose"
259 echo 'working tree adjustment completed'
264 srchost="$(hostname -f)"; srcrepo="$1"
266 dsthost="$3"; dstrepo="$4"
267 elif [ $# = 5 ]; then
268 srchost="$1"; srcrepo="$2"
270 dsthost="$4"; dstrepo="$5"
272 bad_usage "--move needs hostname(s) and paths"
276 [ "$#" = 0 ] || bad_usage "without --move, give no arguments"