This file is indexed.

/usr/bin/git-branchmove is in chiark-scripts 5.0.2.

This file is owned by root:root, with mode 0o755.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
#!/bin/bash
#
# Moves a branch to or from the current git tree to or from
# another git tree
#
# usage:   git-branchmove get|put REMOTE PATTERN

set -e
set -o posix

fail () { echo >&2 "git-branchmove: $*"; exit 16; }
badusage () { fail "bad usage: $*"; }

if [ $# -lt 3 ]; then badusage "too few arguments"; fi

op="$1"; shift
case "$op" in get|put) ;; *) badusage "unknown operation \`$op'"; esac

remote="$1"; shift

# Plan of attack:
#  determine execute-sh runes for src and dst trees
#  list affected branches on source
#  check that source branches are not checked out
#  list affected branches on destination and moan if any nonequal overlap
#  transfer src->dst refs/heads/BRANCH:refs/heads/BRANCH
#  transfer and merge reflog(s) xxx todo
#  delete src refs

case "$remote" in
*:*)	remoteurl="$remote" ;;
[/.]*)	remoteurl="$remote" ;;
*)	remoteurl="$(
		git config remote."$remote".pushurl ||
		git config remote."$remote".url ||
		fail "no pushurl or url defined for remote $remote"
		)"
	remotename="$remote"
esac

remote_spec="$(perl -e '
    $_ = $ARGV[0];
    if (m#^ssh://([^:/]+)(?:\:(\w+))?#) {
	print "$'\''|ssh ";
	print " -p $3" if $2;
        print "$1\n";
    } elsif (m#^([-+_.0-9a-zA-Z\@]+):(?!//|:)#) {
        print "$'\''|ssh $1\n";
    } elsif (m#^[/.]#) {
        print "$_|sh -c $1\n";
    } else {
        die "git-branchmove: unsupported remote url \`$_'\''\n";
    }
' "$remoteurl")"

remote_path="${remote_spec%%|*}"
remote_rune="${remote_spec#*|}"

case $op in
get)
	src_rune="$remote_rune"
	src_path="$remote_path"
	dst_rune="sh -c"
	dst_path=.
	updatemsg="git-branchmove: moved to $remote ($remoteurl)"
	push_fetch=fetch
	;;
put)
	dst_rune="$remote_rune"
	dst_path="$remote_path"
	src_rune="sh -c"
	src_path=.
	updatemsg="git-branchmove; moved to `hostname -f` by `whoami`"
	push_fetch=push
	;;
esac

on_src () { $src_rune "set -e; cd $src_path; $*"; }
on_dst () { $dst_rune "set -e; cd $dst_path; $*"; }


#----- fetch the current refs from both sides -----

branch_pats=''
for branch_pat in "$@"; do
	branch_pats+=" '[r]efs/heads/$branch_pat'"
done

get_branches_rune='
	git for-each-ref --format="%(refname)=%(objectname)" '"$branch_pats"'
'

src_branches=( $(
	on_src '
		printf H
		git symbolic-ref -q HEAD || test $? = 1
		echo " "
		'"$get_branches_rune"'
	'	
))

src_head="${src_branches[0]}"
unset src_branches[0]
: "${src_branches[@]}"

case "$src_head" in
H) ;; # already detached
*)
	src_head="${src_head#H}"
	for check in "${src_branches[@]}"; do
		case "$check" in
		"$src_head"=*)
			fail "would delete checked-out branch $src_head"
			;;
		esac
	done
	;;
esac


if [ "${#src_branches[@]}" = 0 ]; then
	echo >&2 "git-branchmove: nothing to do"
	exit 1
fi

dst_branches=( $(on_dst "$get_branches_rune") )
: "${dst_branches[@]}"


#----- check for nonequal overlaps -----

ok=true
for dst_check in "${dst_branches[@]}"; do
	dst_ref="${dst_check%=*}"
	for src_check in "${src_branches[@]}"; do
		case "$src_check" in
		"$dst_check")	;;
		"$dst_ref"=*)
			ok=false
			echo >&2 "src: $src_check   dst: $dst_check"
			;;
		esac
	done
done

$ok || fail "would overwrite some destination branch(es)"


#----- do the transfer -----

refspecs=()
for src_xfer in "${src_branches[@]}"; do
	src_ref="${src_xfer%=*}"
	refspecs+=("$src_ref:$src_ref")
done

case "$op" in
put)	git push "$remote" "${refspecs[@]}"	;;
get)	git fetch "$remote" "${refspecs[@]}"	;;
*)	fail "unknown $op ???"			;;
esac


#----- delete the refs on the source -----

(
	printf "%s\n" "$updatemsg"
	for src_rm in "${src_branches[@]}"; do printf "%s\n" "$src_rm"; done
) | on_src '
	read updatemsg
	while read src_rm; do
		src_ref="${src_rm%=*}"
		src_obj="${src_rm##*=}"
		git update-ref -m "$updatemsg" -d "$src_ref" "$src_obj"
		echo "moved: $src_ref"
	done
'

#----- update the remote tracking branches -----

if [ "x$remotename" != x ]; then
	for src_rm in "${src_branches[@]}"; do
		src_ref="${src_rm%=*}"
		src_obj="${src_rm##*=}"

		case "$src_ref" in
		refs/heads/*) ;;
		*) continue ;;
		esac

		branch="${src_ref#refs/heads/}"
		track_ref="refs/remotes/$remotename/$branch"
		case $op in
		get)	git update-ref -d "$track_ref"	;;
		put)	git update-ref "$track_ref" "$src_obj" ;;
		*)	fail "unknown $op ???"
		esac
	done
fi

echo "git-repomove: moved ${#src_branches[@]} branches."