Merge branch 'js/rebase-autostash-fix'
authorJunio C Hamano <gitster@pobox.com>
Fri, 2 Nov 2018 02:04:58 +0000 (11:04 +0900)
committerJunio C Hamano <gitster@pobox.com>
Fri, 2 Nov 2018 02:04:58 +0000 (11:04 +0900)
"git rebase" that has recently been rewritten in C had a few issues
in its "--autstash" feature, which have been corrected.

* js/rebase-autostash-fix:
  rebase --autostash: fix issue with dirty submodules
  rebase --autostash: demonstrate a problem with dirty submodules
  rebase (autostash): use an explicit OID to apply the stash
  rebase (autostash): store the full OID in <state-dir>/autostash
  rebase (autostash): avoid duplicate call to state_dir_path()

1  2 
builtin/rebase.c
t/t3420-rebase-autostash.sh

diff --combined builtin/rebase.c
@@@ -21,7 -21,6 +21,7 @@@
  #include "diff.h"
  #include "wt-status.h"
  #include "revision.h"
 +#include "commit-reach.h"
  #include "rerere.h"
  
  static char const * const builtin_rebase_usage[] = {
@@@ -251,8 -250,10 +251,10 @@@ static int apply_autostash(struct rebas
        if (!file_exists(path))
                return 0;
  
-       if (read_one(state_dir_path("autostash", opts), &autostash))
+       if (read_one(path, &autostash))
                return error(_("Could not read '%s'"), path);
+       /* Ensure that the hash is not mistaken for a number */
+       strbuf_addstr(&autostash, "^0");
        argv_array_pushl(&stash_apply.args,
                         "stash", "apply", autostash.buf, NULL);
        stash_apply.git_cmd = 1;
@@@ -1216,15 -1217,15 +1218,15 @@@ int cmd_rebase(int argc, const char **a
                 *       git-rebase.txt caveats with "unless you know what you are doing"
                 */
                if (options.rebase_merges)
 -                      die(_("error: cannot combine '--preserve_merges' with "
 +                      die(_("error: cannot combine '--preserve-merges' with "
                              "'--rebase-merges'"));
  
        if (options.rebase_merges) {
                if (strategy_options.nr)
 -                      die(_("error: cannot combine '--rebase_merges' with "
 +                      die(_("error: cannot combine '--rebase-merges' with "
                              "'--strategy-option'"));
                if (options.strategy)
 -                      die(_("error: cannot combine '--rebase_merges' with "
 +                      die(_("error: cannot combine '--rebase-merges' with "
                              "'--strategy'"));
        }
  
                        update_index_if_able(&the_index, &lock_file);
                rollback_lock_file(&lock_file);
  
-               if (has_unstaged_changes(0) || has_uncommitted_changes(0)) {
+               if (has_unstaged_changes(1) || has_uncommitted_changes(1)) {
                        const char *autostash =
                                state_dir_path("autostash", &options);
                        struct child_process stash = CHILD_PROCESS_INIT;
                        if (safe_create_leading_directories_const(autostash))
                                die(_("Could not create directory for '%s'"),
                                    options.state_dir);
-                       write_file(autostash, "%s", buf.buf);
+                       write_file(autostash, "%s", oid_to_hex(&oid));
                        printf(_("Created autostash: %s\n"), buf.buf);
                        if (reset_head(&head->object.oid, "reset --hard",
                                       NULL, 0, NULL, NULL) < 0)
@@@ -202,7 -202,7 +202,7 @@@ testrebase () 
                echo dirty >>file3 &&
                test_must_fail git rebase$type related-onto-branch &&
                test_path_is_file $dotest/autostash &&
 -              ! grep dirty file3 &&
 +              test_path_is_missing file3 &&
                rm -rf $dotest &&
                git reset --hard &&
                git checkout feature-branch
                echo dirty >>file3 &&
                test_must_fail git rebase$type related-onto-branch &&
                test_path_is_file $dotest/autostash &&
 -              ! grep dirty file3 &&
 +              test_path_is_missing file3 &&
                echo "conflicting-plus-goodbye" >file2 &&
                git add file2 &&
                git rebase --continue &&
                echo dirty >>file3 &&
                test_must_fail git rebase$type related-onto-branch &&
                test_path_is_file $dotest/autostash &&
 -              ! grep dirty file3 &&
 +              test_path_is_missing file3 &&
                git rebase --skip &&
                test_path_is_missing $dotest/autostash &&
                grep dirty file3 &&
                echo dirty >>file3 &&
                test_must_fail git rebase$type related-onto-branch &&
                test_path_is_file $dotest/autostash &&
 -              ! grep dirty file3 &&
 +              test_path_is_missing file3 &&
                git rebase --abort &&
                test_path_is_missing $dotest/autostash &&
                grep dirty file3 &&
@@@ -351,4 -351,14 +351,14 @@@ test_expect_success 'autostash is save
        test_cmp expected file0
  '
  
+ test_expect_success 'autostash with dirty submodules' '
+       test_when_finished "git reset --hard && git checkout master" &&
+       git checkout -b with-submodule &&
+       git submodule add ./ sub &&
+       test_tick &&
+       git commit -m add-submodule &&
+       echo changed >sub/file0 &&
+       git rebase -i --autostash HEAD
+ '
  test_done