Subject: [PATCH v7 0/4] checkout: 'autostash' for branch switching

From: "Harald Nordgren via GitGitGadget" <[email-masked]>
Date: Thu, 09 Apr 2026 13:27:41 +0000

Harald Nordgren (4):
  stash: add --ours-label, --theirs-label, --base-label for apply
  sequencer: allow create_autostash to run silently
  sequencer: teach autostash apply to take optional conflict marker
    labels
  checkout: -m (--merge) uses autostash when switching branches

 Documentation/git-checkout.adoc |  58 +++++-----
 Documentation/git-stash.adoc    |  11 +-
 Documentation/git-switch.adoc   |  27 ++---
 builtin/checkout.c              | 138 ++++++++++-------------
 builtin/stash.c                 |  32 ++++--
 sequencer.c                     |  67 +++++++++---
 sequencer.h                     |   4 +
 t/t3420-rebase-autostash.sh     |  24 +++-
 t/t3903-stash.sh                |  18 +++
 t/t7201-co.sh                   | 188 ++++++++++++++++++++++++++++++++
 t/t7600-merge.sh                |   2 +-
 xdiff-interface.c               |  12 ++
 xdiff-interface.h               |   1 +
 13 files changed, 431 insertions(+), 151 deletions(-)

base-commit: b15384c06f77bc2d34d0d3623a8a58218313a561
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2234%2FHaraldNordgren%2Fcheckout_autostash-v7
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2234/HaraldNordgren/checkout_autostash-v7
Pull-Request: https://github.com/git/git/pull/2234

Range-diff vs v6:

 1:  cd9c64ba60 ! 1:  284075600a stash: add --ours-label, --theirs-label, --base-label for apply
     @@ Documentation/git-stash.adoc: git stash list [<log-options>]
      -git stash apply [--index] [-q | --quiet] [<stash>]
      +git stash apply [--index] [-q | --quiet] [--ours-label=<label>] [--theirs-label=<label>] [--base-label=<label>] [<stash>]
       git stash branch <branchname> [<stash>]
     - git stash [push [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]
     + git stash [push] [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]
       	     [-u | --include-untracked] [-a | --all] [(-m | --message) <message>]
      @@ Documentation/git-stash.adoc: the index's ones. However, this can fail, when you have conflicts
       (which are stored in the index, where you therefore can no longer
 2:  d572c4bb7d = 2:  64261e3cb6 sequencer: allow create_autostash to run silently
 3:  80a98116fc = 3:  c0d6b4b4c0 sequencer: teach autostash apply to take optional conflict marker labels
 4:  7ecb0835b7 ! 4:  1c29e19971 checkout: -m (--merge) uses autostash when switching branches
     @@ builtin/checkout.c: static int merge_working_tree(const struct checkout_opts *op
      -					0, 0);
      -			init_ui_merge_options(&o, the_repository);
      -			o.verbosity = 0;
     --			work = write_in_core_index_as_tree(the_repository);
     +-			work = write_in_core_index_as_tree(the_repository,
     +-							   the_repository->index);
      -
      -			ret = reset_tree(new_tree,
      -					 opts, 1,
     @@ t/t7201-co.sh: test_expect_success 'checkout --merge --conflict=diff3 <branch>'
      +	git reset --hard
      +'
      +
     ++test_expect_success 'checkout -m applies stash cleanly with non-overlapping changes in same file' '
     ++	git checkout -f main &&
     ++	git reset --hard &&
     ++	git clean -f &&
     ++
     ++	git checkout -b nonoverlap_base &&
     ++	fill a b c d >file &&
     ++	git add file &&
     ++	git commit -m "add file" &&
     ++
     ++	git checkout -b nonoverlap_child &&
     ++	fill a b c INSERTED d >file &&
     ++	git commit -a -m "insert line near end of file" &&
     ++
     ++	fill DIRTY a b c INSERTED d >file &&
     ++
     ++	git checkout -m nonoverlap_base 2>stderr &&
     ++	test_grep "Applied autostash" stderr &&
     ++	test_grep ! "resulted in conflicts" stderr &&
     ++
     ++	fill DIRTY a b c d >expect &&
     ++	test_cmp expect file &&
     ++
     ++	git checkout -f main &&
     ++	git branch -D nonoverlap_base &&
     ++	git branch -D nonoverlap_child
     ++'
     ++
      +test_expect_success 'checkout -m -b skips stash with dirty tree' '
      +	git checkout -f main &&
      +	git clean -f &&

-- 
gitgitgadget