LF='
'
-OK_TO_SKIP_PRE_REBASE=
-RESOLVEMSG="
+ok_to_skip_pre_rebase=
+resolvemsg="
When you have resolved this problem run \"git rebase --continue\".
If you would prefer to skip this patch, instead run \"git rebase --skip\".
To restore the original branch and stop rebasing run \"git rebase --abort\".
"
-unset newbase
-strategy=recursive
+unset onto
+strategy=
strategy_opts=
do_merge=
merge_dir="$GIT_DIR"/rebase-merge
rebase_root=
force_rebase=
allow_rerere_autoupdate=
+# Non-empty if a rebase was in progress when 'git rebase' was invoked
+in_progress=
+# One of {am, merge, interactive}
+type=
+# One of {"$GIT_DIR"/rebase-apply, "$GIT_DIR"/rebase-merge}
+state_dir=
+# One of {'', continue, skip, abort}, as parsed from command line
+action=
read_state () {
- if test -d "$merge_dir"
+ if test "$type" = merge
then
- state_dir="$merge_dir"
- prev_head=$(cat "$merge_dir"/prev_head) &&
- end=$(cat "$merge_dir"/end) &&
- msgnum=$(cat "$merge_dir"/msgnum)
- else
- state_dir="$apply_dir"
+ onto_name=$(cat "$state_dir"/onto_name) &&
+ end=$(cat "$state_dir"/end) &&
+ msgnum=$(cat "$state_dir"/msgnum)
fi &&
head_name=$(cat "$state_dir"/head-name) &&
onto=$(cat "$state_dir"/onto) &&
}
continue_merge () {
- test -n "$prev_head" || die "prev_head must be defined"
test -d "$merge_dir" || die "$merge_dir directory does not exist"
unmerged=$(git ls-files -u)
then
echo "You still have unmerged paths in your index"
echo "did you forget to use git add?"
- die "$RESOLVEMSG"
+ die "$resolvemsg"
fi
cmt=`cat "$merge_dir/current"`
then
echo "Commit failed, please do not call \"git commit\""
echo "directly, but instead do one of the following: "
- die "$RESOLVEMSG"
+ die "$resolvemsg"
fi
if test -z "$GIT_QUIET"
then
test -z "$GIT_QUIET" &&
GIT_PAGER='' git log --format=%s -1 "$cmt"
- prev_head=`git rev-parse HEAD^0`
- # save the resulting commit so we can read-tree on it later
- echo "$prev_head" > "$merge_dir/prev_head"
-
# onto the next patch:
msgnum=$(($msgnum + 1))
echo "$msgnum" >"$merge_dir/msgnum"
hd=$(git rev-parse --verify HEAD)
cmt_name=$(git symbolic-ref HEAD 2> /dev/null || echo HEAD)
msgnum=$(cat "$merge_dir/msgnum")
- end=$(cat "$merge_dir/end")
eval GITHEAD_$cmt='"${cmt_name##refs/heads/}~$(($end - $msgnum))"'
- eval GITHEAD_$hd='$(cat "$merge_dir/onto_name")'
+ 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
eval 'git-merge-$strategy' $strategy_opts '"$cmt^" -- "$hd" "$cmt"'
rv=$?
case "$rv" in
;;
1)
git rerere $allow_rerere_autoupdate
- die "$RESOLVEMSG"
+ die "$resolvemsg"
;;
2)
echo "Strategy: $rv $strategy failed, try another" 1>&2
- die "$RESOLVEMSG"
+ die "$resolvemsg"
;;
*)
die "Unknown exit code ($rv) from command:" \
}
run_pre_rebase_hook () {
- if test -z "$OK_TO_SKIP_PRE_REBASE" &&
+ if test -z "$ok_to_skip_pre_rebase" &&
test -x "$GIT_DIR/hooks/pre-rebase"
then
"$GIT_DIR/hooks/pre-rebase" ${1+"$@"} ||
is_interactive "$@" && exec git-rebase--interactive "$@"
+if test -d "$apply_dir"
+then
+ type=am
+ state_dir="$apply_dir"
+elif test -d "$merge_dir"
+then
+ if test -f "$merge_dir"/interactive
+ then
+ type=interactive
+ interactive_rebase=explicit
+ else
+ type=merge
+ fi
+ state_dir="$merge_dir"
+fi
+test -n "$type" && in_progress=t
+
+total_argc=$#
while test $# != 0
do
case "$1" in
--no-verify)
- OK_TO_SKIP_PRE_REBASE=yes
+ ok_to_skip_pre_rebase=yes
;;
--verify)
- OK_TO_SKIP_PRE_REBASE=
+ ok_to_skip_pre_rebase=
;;
- --continue)
- test -d "$merge_dir" -o -d "$apply_dir" ||
- die "No rebase in progress?"
-
- git update-index --ignore-submodules --refresh &&
- git diff-files --quiet --ignore-submodules || {
- echo "You must edit all merge conflicts and then"
- echo "mark them as resolved using git add"
- exit 1
- }
- read_state
- if test -d "$merge_dir"
- then
- continue_merge
- while test "$msgnum" -le "$end"
- do
- call_merge "$msgnum"
- continue_merge
- done
- finish_rb_merge
- exit
- fi
- git am --resolved --3way --resolvemsg="$RESOLVEMSG" &&
- move_to_original_branch
- exit
- ;;
- --skip)
- test -d "$merge_dir" -o -d "$apply_dir" ||
- die "No rebase in progress?"
-
- git reset --hard HEAD || exit $?
- read_state
- if test -d "$merge_dir"
- then
- git rerere clear
- msgnum=$(($msgnum + 1))
- while test "$msgnum" -le "$end"
- do
- call_merge "$msgnum"
- continue_merge
- done
- finish_rb_merge
- exit
- fi
- git am -3 --skip --resolvemsg="$RESOLVEMSG" &&
- move_to_original_branch
- exit
- ;;
- --abort)
- test -d "$merge_dir" -o -d "$apply_dir" ||
- die "No rebase in progress?"
-
- git rerere clear
- read_state
- case "$head_name" in
- refs/*)
- git symbolic-ref HEAD $head_name ||
- die "Could not move back to $head_name"
- ;;
- esac
- git reset --hard $orig_head
- rm -r "$state_dir"
- exit
+ --continue|--skip|--abort)
+ test $total_argc -eq 1 || usage
+ action=${1##--}
;;
--onto)
test 2 -le "$#" || usage
- newbase="$2"
+ onto="$2"
shift
;;
-M|-m|--m|--me|--mer|--merg|--merge)
esac
strategy_opts="$strategy_opts $(git rev-parse --sq-quote "--$newopt")"
do_merge=t
+ test -z "$strategy" && strategy=recursive
;;
-s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
--strateg=*|--strategy=*|\
done
test $# -gt 2 && usage
-if test $# -eq 0 && test -z "$rebase_root"
-then
- test -d "$merge_dir" -o -d "$apply_dir" || usage
- test -d "$merge_dir" -o -f "$apply_dir"/rebasing &&
- die 'A rebase is in progress, try --continue, --skip or --abort.'
-fi
+test -n "$action" && test -z "$in_progress" && die "No rebase in progress?"
-# Make sure we do not have $apply_dir or $merge_dir
-if test -z "$do_merge"
-then
- if mkdir "$apply_dir" 2>/dev/null
- then
- rmdir "$apply_dir"
- else
- echo >&2 '
-It seems that I cannot create a rebase-apply directory, and
-I wonder if you are in the middle of patch application or another
-rebase. If that is not the case, please
- rm -fr '"$apply_dir"'
-and run me again. I am stopping in case you still have something
-valuable there.'
+case "$action" in
+continue)
+ git update-index --ignore-submodules --refresh &&
+ git diff-files --quiet --ignore-submodules || {
+ echo "You must edit all merge conflicts and then"
+ echo "mark them as resolved using git add"
exit 1
+ }
+ read_state
+ if test -d "$merge_dir"
+ then
+ continue_merge
+ while test "$msgnum" -le "$end"
+ do
+ call_merge "$msgnum"
+ continue_merge
+ done
+ finish_rb_merge
+ exit
fi
-else
+ git am --resolved --3way --resolvemsg="$resolvemsg" &&
+ move_to_original_branch
+ exit
+ ;;
+skip)
+ git reset --hard HEAD || exit $?
+ read_state
if test -d "$merge_dir"
then
- die "previous rebase directory $merge_dir still exists." \
- 'Try git rebase (--continue | --abort | --skip)'
+ git rerere clear
+ msgnum=$(($msgnum + 1))
+ while test "$msgnum" -le "$end"
+ do
+ call_merge "$msgnum"
+ continue_merge
+ done
+ finish_rb_merge
+ exit
fi
+ git am -3 --skip --resolvemsg="$resolvemsg" &&
+ move_to_original_branch
+ exit
+ ;;
+abort)
+ git rerere clear
+ read_state
+ case "$head_name" in
+ refs/*)
+ git symbolic-ref HEAD $head_name ||
+ die "Could not move back to $head_name"
+ ;;
+ esac
+ git reset --hard $orig_head
+ rm -r "$state_dir"
+ exit
+ ;;
+esac
+
+# Make sure no rebase is in progress
+if test -n "$in_progress"
+then
+ die '
+It seems that there is already a '"${state_dir##*/}"' directory, and
+I wonder if you are in the middle of another rebase. If that is the
+case, please try
+ git rebase (--continue | --abort | --skip)
+If that is not the case, please
+ rm -fr '"$state_dir"'
+and run me again. I am stopping in case you still have something
+valuable there.'
fi
+test $# -eq 0 && test -z "$rebase_root" && usage
+
require_clean_work_tree "rebase" "Please commit or stash them."
if test -z "$rebase_root"
unset root_flag
upstream_arg="$upstream_name"
else
- test -z "$newbase" && die "--root must be used with --onto"
+ test -z "$onto" && die "--root must be used with --onto"
unset upstream_name
unset upstream
root_flag="--root"
fi
# Make sure the branch to rebase onto is valid.
-onto_name=${newbase-"$upstream_name"}
+onto_name=${onto-"$upstream_name"}
case "$onto_name" in
*...*)
if left=${onto_name%...*} right=${onto_name#*...} &&
git format-patch -k --stdout --full-index --ignore-if-in-upstream \
--src-prefix=a/ --dst-prefix=b/ \
--no-renames $root_flag "$revisions" |
- git am $git_am_opt --rebasing --resolvemsg="$RESOLVEMSG" &&
+ git am $git_am_opt --rebasing --resolvemsg="$resolvemsg" &&
move_to_original_branch
ret=$?
test 0 != $ret -a -d "$apply_dir" &&
mkdir -p "$merge_dir"
echo "$onto_name" > "$merge_dir/onto_name"
-prev_head=$orig_head
-echo "$prev_head" > "$merge_dir/prev_head"
echo "$head_name" > "$merge_dir/head-name"
echo "$onto" > "$merge_dir/onto"
echo "$orig_head" > "$merge_dir/orig-head"