Merge branch 'js/rebase-detached'
authorJunio C Hamano <gitster@pobox.com>
Wed, 14 Nov 2007 22:04:06 +0000 (14:04 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 14 Nov 2007 22:04:06 +0000 (14:04 -0800)
* js/rebase-detached:
  rebase: fix "rebase --continue" breakage
  rebase: operate on a detached HEAD

git-rebase.sh
t/t3402-rebase-merge.sh
t/t3403-rebase-skip.sh

index 224cca9..c059749 100755 (executable)
@@ -87,7 +87,7 @@ call_merge () {
        cmt="$(cat "$dotest/cmt.$1")"
        echo "$cmt" > "$dotest/current"
        hd=$(git rev-parse --verify HEAD)
-       cmt_name=$(git symbolic-ref HEAD)
+       cmt_name=$(git symbolic-ref HEAD 2> /dev/null || echo HEAD)
        msgnum=$(cat "$dotest/msgnum")
        end=$(cat "$dotest/end")
        eval GITHEAD_$cmt='"${cmt_name##refs/heads/}~$(($end - $msgnum))"'
@@ -115,7 +115,24 @@ call_merge () {
        esac
 }
 
+move_to_original_branch () {
+       test -z "$head_name" &&
+               head_name="$(cat "$dotest"/head-name)" &&
+               onto="$(cat "$dotest"/onto)" &&
+               orig_head="$(cat "$dotest"/orig-head)"
+       case "$head_name" in
+       refs/*)
+               message="rebase finished: $head_name onto $onto"
+               git update-ref -m "$message" \
+                       $head_name $(git rev-parse HEAD) $orig_head &&
+               git symbolic-ref HEAD $head_name ||
+               die "Could not move back to $head_name"
+               ;;
+       esac
+}
+
 finish_rb_merge () {
+       move_to_original_branch
        rm -r "$dotest"
        echo "All done."
 }
@@ -153,7 +170,11 @@ do
                        finish_rb_merge
                        exit
                fi
-               git am --resolved --3way --resolvemsg="$RESOLVEMSG"
+               head_name=$(cat .dotest/head-name) &&
+               onto=$(cat .dotest/onto) &&
+               orig_head=$(cat .dotest/orig-head) &&
+               git am --resolved --3way --resolvemsg="$RESOLVEMSG" &&
+               move_to_original_branch
                exit
                ;;
        --skip)
@@ -173,16 +194,23 @@ do
                        finish_rb_merge
                        exit
                fi
-               git am -3 --skip --resolvemsg="$RESOLVEMSG"
+               head_name=$(cat .dotest/head-name) &&
+               onto=$(cat .dotest/onto) &&
+               orig_head=$(cat .dotest/orig-head) &&
+               git am -3 --skip --resolvemsg="$RESOLVEMSG" &&
+               move_to_original_branch
                exit
                ;;
        --abort)
                git rerere clear
                if test -d "$dotest"
                then
+                       move_to_original_branch
                        rm -r "$dotest"
                elif test -d .dotest
                then
+                       dotest=.dotest
+                       move_to_original_branch
                        rm -r .dotest
                else
                        die "No rebase in progress?"
@@ -318,6 +346,19 @@ then
        GIT_PAGER='' git diff --stat --summary "$mb" "$onto"
 fi
 
+# move to a detached HEAD
+orig_head=$(git rev-parse HEAD^0)
+head_name=$(git symbolic-ref HEAD 2> /dev/null)
+case "$head_name" in
+'')
+       head_name="detached HEAD"
+       ;;
+*)
+       git checkout "$orig_head" > /dev/null 2>&1 ||
+               die "could not detach HEAD"
+       ;;
+esac
+
 # Rewind the head to "$onto"; this saves our current head in ORIG_HEAD.
 echo "First, rewinding head to replay your work on top of it..."
 git-reset --hard "$onto"
@@ -327,14 +368,21 @@ git-reset --hard "$onto"
 if test "$mb" = "$branch"
 then
        echo >&2 "Fast-forwarded $branch_name to $onto_name."
+       move_to_original_branch
        exit 0
 fi
 
 if test -z "$do_merge"
 then
        git format-patch -k --stdout --full-index --ignore-if-in-upstream "$upstream"..ORIG_HEAD |
-       git am $git_am_opt --binary -3 -k --resolvemsg="$RESOLVEMSG"
-       exit $?
+       git am $git_am_opt --binary -3 -k --resolvemsg="$RESOLVEMSG" &&
+       move_to_original_branch
+       ret=$?
+       test 0 != $ret -a -d .dotest &&
+               echo $head_name > .dotest/head-name &&
+               echo $onto > .dotest/onto &&
+               echo $orig_head > .dotest/orig-head
+       exit $ret
 fi
 
 # start doing a rebase with git-merge
@@ -343,8 +391,10 @@ fi
 mkdir -p "$dotest"
 echo "$onto" > "$dotest/onto"
 echo "$onto_name" > "$dotest/onto_name"
-prev_head=`git rev-parse HEAD^0`
+prev_head=$orig_head
 echo "$prev_head" > "$dotest/prev_head"
+echo "$orig_head" > "$dotest/orig-head"
+echo "$head_name" > "$dotest/head-name"
 
 msgnum=0
 for cmt in `git rev-list --reverse --no-merges "$upstream"..ORIG_HEAD`
index 0779aaa..7b7d072 100755 (executable)
@@ -48,9 +48,14 @@ test_expect_success 'reference merge' '
        git merge -s recursive "reference merge" HEAD master
 '
 
+PRE_REBASE=$(git rev-parse test-rebase)
 test_expect_success rebase '
        git checkout test-rebase &&
-       git rebase --merge master
+       GIT_TRACE=1 git rebase --merge master
+'
+
+test_expect_success 'test-rebase@{1} is pre rebase' '
+       test $PRE_REBASE = $(git rev-parse test-rebase@{1})
 '
 
 test_expect_success 'merge and rebase should match' '
index eab053c..2ee5a00 100755 (executable)
@@ -39,6 +39,19 @@ test_expect_success 'rebase --skip with am -3' '
        git reset --hard HEAD &&
        git rebase --skip
        '
+
+test_expect_success 'rebase moves back to skip-reference' '
+       test refs/heads/skip-reference = $(git symbolic-ref HEAD) &&
+       git branch post-rebase &&
+       git reset --hard pre-rebase &&
+       ! git rebase master &&
+       echo "hello" > hello &&
+       git add hello &&
+       git rebase --continue &&
+       test refs/heads/skip-reference = $(git symbolic-ref HEAD) &&
+       git reset --hard post-rebase
+'
+
 test_expect_success 'checkout skip-merge' 'git checkout -f skip-merge'
 
 test_expect_failure 'rebase with --merge' 'git rebase --merge master'
@@ -51,6 +64,10 @@ test_expect_success 'rebase --skip with --merge' '
 test_expect_success 'merge and reference trees equal' \
        'test -z "`git diff-tree skip-merge skip-reference`"'
 
+test_expect_success 'moved back to branch correctly' '
+       test refs/heads/skip-merge = $(git symbolic-ref HEAD)
+'
+
 test_debug 'gitk --all & sleep 1'
 
 test_done