builtin/rebase.c: make sure the active branch isn't moved when autostashing
authorBen Wijen <ben@wijen.net>
Fri, 30 Aug 2019 15:16:05 +0000 (17:16 +0200)
committerJunio C Hamano <gitster@pobox.com>
Sat, 7 Sep 2019 17:17:05 +0000 (10:17 -0700)
Consider the following scenario:
git checkout not-the-master
work work work
git rebase --autostash upstream master

Here 'rebase --autostash <upstream> <branch>' incorrectly moves the
active branch (not-the-master) to master (before the rebase).

The expected behavior: (58794775:/git-rebase.sh:526)
AUTOSTASH=$(git stash create autostash)
git reset --hard
git checkout master
git rebase upstream
git stash apply $AUTOSTASH

The actual behavior: (6defce2b:/builtin/rebase.c:1062)
AUTOSTASH=$(git stash create autostash)
git reset --hard master
git checkout master
git rebase upstream
git stash apply $AUTOSTASH

This commit reinstates the 'legacy script' behavior as introduced with
58794775: rebase: implement --[no-]autostash and rebase.autostash

Signed-off-by: Ben Wijen <ben@wijen.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/rebase.c
t/t3420-rebase-autostash.sh
index 670096c065f5f5fa8cb57c642cd759111b010988..0a2f9273ee4744b96bf751f87effaf9edb96b23f 100644 (file)
@@ -1968,9 +1968,12 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
                                state_dir_path("autostash", &options);
                        struct child_process stash = CHILD_PROCESS_INIT;
                        struct object_id oid;
                                state_dir_path("autostash", &options);
                        struct child_process stash = CHILD_PROCESS_INIT;
                        struct object_id oid;
-                       struct commit *head =
-                               lookup_commit_reference(the_repository,
-                                                       &options.orig_head);
+                       struct object_id head_oid;
+                       struct commit *head;
+
+                       if (get_oid("HEAD", &head_oid))
+                               die(_("could not determine HEAD revision"));
+                       head = lookup_commit_reference(the_repository, &head_oid);
 
                        argv_array_pushl(&stash.args,
                                         "stash", "create", "autostash", NULL);
 
                        argv_array_pushl(&stash.args,
                                         "stash", "create", "autostash", NULL);
index b8f4d034672378065a5fe08df6b8210fa3c71721..1131e0016a76cb9627b12ec0eb7ee86cb05820f8 100755 (executable)
@@ -306,4 +306,12 @@ test_expect_success 'branch is left alone when possible' '
        test unchanged-branch = "$(git rev-parse --abbrev-ref HEAD)"
 '
 
        test unchanged-branch = "$(git rev-parse --abbrev-ref HEAD)"
 '
 
+test_expect_success 'never change active branch' '
+       git checkout -b not-the-feature-branch unrelated-onto-branch &&
+       test_when_finished "git reset --hard && git checkout master" &&
+       echo changed >file0 &&
+       git rebase --autostash not-the-feature-branch feature-branch &&
+       test_cmp_rev not-the-feature-branch unrelated-onto-branch
+'
+
 test_done
 test_done