pull --rebase --autostash was failing on a fast-forward in a dirty repo since we shortcut to run_merge(), which does not know how to autostash. The shortcut is a performance optimization, and since rebase was rewritten in C, it seemed okay to just bypass the shortcut if we autostash. --- builtin/pull.c | 5 +++-- t/t5520-pull.sh | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/builtin/pull.c b/builtin/pull.c index dd1a4a94e41e..609e594d3f28 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -772,6 +772,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix) struct oid_array merge_heads = OID_ARRAY_INIT; struct object_id orig_head, curr_head; struct object_id rebase_fork_point; + int autostash; if (!getenv("GIT_REFLOG_ACTION")) set_reflog_message(argc, argv); @@ -800,8 +801,8 @@ int cmd_pull(int argc, const char **argv, const char *prefix) if (!opt_rebase && opt_autostash != -1) die(_("--[no-]autostash option is only valid with --rebase.")); + autostash = config_autostash; if (opt_rebase) { - int autostash = config_autostash; if (opt_autostash != -1) autostash = opt_autostash; @@ -868,7 +869,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix) head = lookup_commit_reference(orig_head.hash); commit_list_insert(head, &list); merge_head = lookup_commit_reference(merge_heads.oid[0].hash); - if (is_descendant_of(merge_head, list)) { + if (!autostash && is_descendant_of(merge_head, list)) { /* we can fast-forward this without invoking rebase */ opt_ff = "--ff-only"; return run_merge(); diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index 17f4d0fe4e72..4c85be0417cf 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -272,6 +272,24 @@ test_expect_success '--rebase fast forward' ' test_cmp reflog.expected reflog.fuzzy ' +test_expect_success '--rebase --autostash fast forward' ' + test_when_finished " + git reset --hard; + git checkout to-rebase; + git branch -D to-rebase-ff; + git branch -D behind" && + git branch behind && + git checkout -b to-rebase-ff && + echo another modification >>file && + git add file && + git commit -m mod && + + git checkout behind && + echo dirty >file && + git pull --rebase --autostash . to-rebase-ff && + test "$(git rev-parse HEAD)" = "$(git rev-parse to-rebase-ff)" +' + test_expect_success '--rebase with conflicts shows advice' ' test_when_finished "git rebase --abort; git checkout -f to-rebase" && git checkout -b seq && -- https://github.com/git/git/pull/365