checkout: separate autostash conflict advice from branch-switch message

"git checkout -m" stashes the user's local changes when it cannot
perform the checkout, and then applies the stash.  When applying the
stash results in conflicts, the advice on how to deal with them is
printed directly on top of the branch-switch message ("Switched to
branch ..."), making the two hard to tell apart.  Print a blank line
in between so that the advice and the branch-switch message are
visually distinct.

apply_autostash_ref() reports whether applying the stash resulted in
conflicts via its enum stash_apply_result return value, so only print
the blank line in the conflicted case.

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Harald Nordgren 2026-09-02 18:29:03 +00:00 committed by Junio C Hamano
parent 89b514c7a4
commit ff7d12a553
2 changed files with 21 additions and 10 deletions

View File

@ -1163,6 +1163,7 @@ static int switch_branches(const struct checkout_opts *opts,
int flag, writeout_error = 0;
int do_merge = 1;
int created_autostash = 0;
enum stash_apply_result autostash_res = STASH_APPLY_CLEAN;
struct strbuf old_commit_shortname = STRBUF_INIT;
struct strbuf autostash_msg = STRBUF_INIT;
const char *stash_label_base = NULL;
@ -1234,12 +1235,12 @@ static int switch_branches(const struct checkout_opts *opts,
git_config_push_parameter(cfg.buf);
strbuf_release(&cfg);
}
apply_autostash_ref(the_repository,
"CHECKOUT_AUTOSTASH_HEAD",
new_branch_info->name,
"local",
stash_label_base,
autostash_msg.buf);
autostash_res = apply_autostash_ref(the_repository,
"CHECKOUT_AUTOSTASH_HEAD",
new_branch_info->name,
"local",
stash_label_base,
autostash_msg.buf);
}
if (ret) {
branch_info_release(&old_branch_info);
@ -1252,6 +1253,8 @@ static int switch_branches(const struct checkout_opts *opts,
if (!opts->quiet && !old_branch_info.path && old_branch_info.commit && new_branch_info->commit != old_branch_info.commit)
orphaned_commit_warning(old_branch_info.commit, new_branch_info->commit);

if (autostash_res == STASH_APPLY_CONFLICT && !opts->quiet)
fputc('\n', stderr);
update_refs_for_switch(opts, &old_branch_info, new_branch_info);

if (created_autostash) {

View File

@ -236,10 +236,18 @@ test_expect_success 'checkout -m creates a recoverable stash on conflict' '
test_must_fail git checkout side 2>stderr &&
test_grep "Your local changes" stderr &&
git checkout -m side >actual 2>&1 &&
test_grep "resulted in conflicts" actual &&
test_grep "git stash drop" actual &&
test_grep "git stash pop" actual &&
test_grep "The following paths have local changes" actual &&
cat >expect <<-EOF &&
Your local changes are stashed, however applying them
resulted in conflicts. You can either resolve the conflicts
and then discard the stash with "git stash drop", or, if you
do not want to resolve them now, run "git reset --hard" and
apply the local changes later by running "git stash pop".

Switched to branch ${SQ}side${SQ}
The following paths have local changes:
M one
EOF
test_cmp expect actual &&
git log -p -1 --format="%gs%n%B" -g --diff-merges=1 refs/stash >actual &&
sed /^index/d actual >actual.trimmed &&
cat >expect <<-EOF &&