2f5f469bc4
Due to historical reasons, the backend scriptlets for "git rebase" are structured a bit unusually. As originally designed, dot-sourcing them from "git rebase" was sufficient to invoke the specific backend. However, it was later discovered that some shell implementations (e.g. FreeBSD 9.x) misbehaved by continuing to execute statements following a top-level "return" rather than returning control to the next statement in "git rebase" after dot-sourcing the scriptlet. To work around this shortcoming, the whole body of git-rebase--$backend.sh was made into a shell function git_rebase__$backend, and then the very last line of the scriptlet called that function. A more normal architecture is for a dot-sourced scriptlet merely to define functions (thus acting as a function library), and for those functions to be called by the script doing the dot-sourcing. Migrate to this arrangement by moving the git_rebase__$backend call from the end of a scriptlet into "git rebase" itself. While at it, remove the large comment block from each scriptlet explaining this historic anomaly since it serves no purpose under the new normalized architecture in which a scriptlet is merely a function library. Signed-off-by: Wink Saville <wink@saville.com> Helped-by: Junio C Hamano <gitster@pobox.com> Helped-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
165 lines
3.5 KiB
Bash
165 lines
3.5 KiB
Bash
# This shell script fragment is sourced by git-rebase to implement
|
|
# its merge-based non-interactive mode that copes well with renamed
|
|
# files.
|
|
#
|
|
# Copyright (c) 2010 Junio C Hamano.
|
|
#
|
|
|
|
prec=4
|
|
|
|
read_state () {
|
|
onto_name=$(cat "$state_dir"/onto_name) &&
|
|
end=$(cat "$state_dir"/end) &&
|
|
msgnum=$(cat "$state_dir"/msgnum)
|
|
}
|
|
|
|
continue_merge () {
|
|
test -d "$state_dir" || die "$state_dir directory does not exist"
|
|
|
|
unmerged=$(git ls-files -u)
|
|
if test -n "$unmerged"
|
|
then
|
|
echo "You still have unmerged paths in your index"
|
|
echo "did you forget to use git add?"
|
|
die "$resolvemsg"
|
|
fi
|
|
|
|
cmt=$(cat "$state_dir/current")
|
|
if ! git diff-index --quiet --ignore-submodules HEAD --
|
|
then
|
|
if ! git commit ${gpg_sign_opt:+"$gpg_sign_opt"} $allow_empty_message \
|
|
--no-verify -C "$cmt"
|
|
then
|
|
echo "Commit failed, please do not call \"git commit\""
|
|
echo "directly, but instead do one of the following: "
|
|
die "$resolvemsg"
|
|
fi
|
|
if test -z "$GIT_QUIET"
|
|
then
|
|
printf "Committed: %0${prec}d " $msgnum
|
|
fi
|
|
echo "$cmt $(git rev-parse HEAD^0)" >> "$state_dir/rewritten"
|
|
else
|
|
if test -z "$GIT_QUIET"
|
|
then
|
|
printf "Already applied: %0${prec}d " $msgnum
|
|
fi
|
|
fi
|
|
test -z "$GIT_QUIET" &&
|
|
GIT_PAGER='' git log --format=%s -1 "$cmt"
|
|
|
|
# onto the next patch:
|
|
msgnum=$(($msgnum + 1))
|
|
echo "$msgnum" >"$state_dir/msgnum"
|
|
}
|
|
|
|
call_merge () {
|
|
msgnum="$1"
|
|
echo "$msgnum" >"$state_dir/msgnum"
|
|
cmt="$(cat "$state_dir/cmt.$msgnum")"
|
|
echo "$cmt" > "$state_dir/current"
|
|
git update-ref REBASE_HEAD "$cmt"
|
|
hd=$(git rev-parse --verify HEAD)
|
|
cmt_name=$(git symbolic-ref HEAD 2> /dev/null || echo HEAD)
|
|
eval GITHEAD_$cmt='"${cmt_name##refs/heads/}~$(($end - $msgnum))"'
|
|
eval GITHEAD_$hd='$onto_name'
|
|
export GITHEAD_$cmt GITHEAD_$hd
|
|
if test -n "$GIT_QUIET"
|
|
then
|
|
GIT_MERGE_VERBOSITY=1 && export GIT_MERGE_VERBOSITY
|
|
fi
|
|
test -z "$strategy" && strategy=recursive
|
|
# If cmt doesn't have a parent, don't include it as a base
|
|
base=$(git rev-parse --verify --quiet $cmt^)
|
|
eval 'git-merge-$strategy' $strategy_opts $base ' -- "$hd" "$cmt"'
|
|
rv=$?
|
|
case "$rv" in
|
|
0)
|
|
unset GITHEAD_$cmt GITHEAD_$hd
|
|
return
|
|
;;
|
|
1)
|
|
git rerere $allow_rerere_autoupdate
|
|
die "$resolvemsg"
|
|
;;
|
|
2)
|
|
echo "Strategy: $strategy failed, try another" 1>&2
|
|
die "$resolvemsg"
|
|
;;
|
|
*)
|
|
die "Unknown exit code ($rv) from command:" \
|
|
"git-merge-$strategy $cmt^ -- HEAD $cmt"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
finish_rb_merge () {
|
|
move_to_original_branch
|
|
if test -s "$state_dir"/rewritten
|
|
then
|
|
git notes copy --for-rewrite=rebase <"$state_dir"/rewritten
|
|
hook="$(git rev-parse --git-path hooks/post-rewrite)"
|
|
test -x "$hook" && "$hook" rebase <"$state_dir"/rewritten
|
|
fi
|
|
say All done.
|
|
}
|
|
|
|
git_rebase__merge () {
|
|
|
|
case "$action" in
|
|
continue)
|
|
read_state
|
|
continue_merge
|
|
while test "$msgnum" -le "$end"
|
|
do
|
|
call_merge "$msgnum"
|
|
continue_merge
|
|
done
|
|
finish_rb_merge
|
|
return
|
|
;;
|
|
skip)
|
|
read_state
|
|
git rerere clear
|
|
msgnum=$(($msgnum + 1))
|
|
while test "$msgnum" -le "$end"
|
|
do
|
|
call_merge "$msgnum"
|
|
continue_merge
|
|
done
|
|
finish_rb_merge
|
|
return
|
|
;;
|
|
show-current-patch)
|
|
exec git show REBASE_HEAD --
|
|
;;
|
|
esac
|
|
|
|
mkdir -p "$state_dir"
|
|
echo "$onto_name" > "$state_dir/onto_name"
|
|
write_basic_state
|
|
rm -f "$(git rev-parse --git-path REBASE_HEAD)"
|
|
|
|
msgnum=0
|
|
for cmt in $(git rev-list --reverse --no-merges "$revisions")
|
|
do
|
|
msgnum=$(($msgnum + 1))
|
|
echo "$cmt" > "$state_dir/cmt.$msgnum"
|
|
done
|
|
|
|
echo 1 >"$state_dir/msgnum"
|
|
echo $msgnum >"$state_dir/end"
|
|
|
|
end=$msgnum
|
|
msgnum=1
|
|
|
|
while test "$msgnum" -le "$end"
|
|
do
|
|
call_merge "$msgnum"
|
|
continue_merge
|
|
done
|
|
|
|
finish_rb_merge
|
|
|
|
}
|