Re: [FEATURE] Proposal: git stash --only-unstaged

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Aug 13, 2025 at 5:00 AM J. Dettweiler
<git.vger.kernel.org@xxxxxxxxxx> wrote:
>
> Hi all,
>
> I’ve run into a recurring workflow problem when splitting commits during
> an interactive rebase, and I think Git could benefit from an option to
> stash *only* the working tree (unstaged) changes, without saving or
> restoring the index (staged changes) at all.
>
> ---
>
> **Scenario:**
> - I have a commit that needs to be split.
> - I stage the part of the changes that will remain in the earlier commit
> (this becomes the new, fixed commit).
> - The rest of the changes (which belong in a later commit) remain
> unstaged in the working tree.
> - I want to test the staged commit in isolation before actually
> committing it, without losing or committing the later changes.
> - After testing, I want to bring back the unstaged changes exactly as
> they were.
>
> ---
>
> **Current limitations:**
> - `git stash --keep-index` still saves the index in the stash object.
> - When I later `git stash pop`, Git tries to restore those staged
> changes, often causing merge conflicts if I’ve modified them during the
> test.
> - `git stash -p` and `git diff`+`git apply` can work as workarounds, but
> they are clunky and error-prone in longer rebases.
> - The goal is essentially:
>    > “stash the working tree only, leave the index untouched and
> unrecorded in the stash.”

I can reproduce (2.50.1):

    git init
    echo a >a && echo b >b && git add .
    git commit -m.
    echo c >>a && echo d >>b && git add b
    git stash --keep-index
    echo f >>b && git add . && git commit -m.

Here, “git stash pop” creates conflicts for b, even with “--no-index”.
“git stash branch foo” is slightly more sensible, but also includes
the stashed index changes for b, which I thought were normally dropped
when applying stashes [1,2]. This also seems like exactly the use case
that “Testing partial commits” in “git help stash“ is supposed to
cover.

Taking a closer look, though, the conflicts aren’t from the index? The
stash tree for the “W” commit (aka stash@{0}^{tree}) has the changes
in a and has b in the state before more modifications were made (since
the version in the index and working tree were the same). Try “git
diff @^{tree} stash@{0}^{tree}”. Now, the I commit in the stash has
the same changes for b (git diff @^{tree} stash@{0}^2^{tree}), so that
explains why it seems like the conflicts are about the index!

I don’t see how to avoid this in general: “git restore -W -s stash@{0}
a” does what I want, but wouldn’t scale to many files easily. If I do
a “git restore -Ws @ b” in the recipe above _before_ stashing, then I
get no conflicts on “git stash pop” (see tree diffs above for why),
but that seems hard to remember to do (and isn’t documented in “git
help stash” as being necessary)?

[1]: https://lore.kernel.org/git/20250510183358.36806-1-ben.knoble+github@xxxxxxxxx/
[2]: https://lore.kernel.org/git/20250510183358.36806-4-ben.knoble+github@xxxxxxxxx/





[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux