Re: [FEATURE] Proposal: git stash --only-unstaged
- From
- Phillip Wood <phillip.wood123@gmail.com>
- Date
- Aug 18, 2025, 15:14 UTC
- Message-ID
- <89394e50-9077-4a7b-b30e-afd1be1a40e8@gmail.com>
- In-Reply-To
- <xmqqfrdqkk1l.fsf@gitster.g>
On 17/08/2025 17:08, Junio C Hamano wrote:
Show 14 quoted lines
> Phillip Wood <phillip.wood123@gmail.com> writes: > >> To use it create your stash with "git stash push --keep-index" and then >> use the script to pop the unstaged changes rather than using "git stash >> pop". If the script proves to be useful then perhaps we could add an >> "--unstaged" option to "git stash pop" > > Hmph, would the behaviour useful enough that it should be always > enabled, without any new option? I strongly suspect that those who > worked on adding "--keep-index" option did not expect the user to be > mucking with the working tree files while "testing the staged stuff > by updating the working tree files to match it and nothing else", > and as long as the end-user stays within that originally designed > use case, nothing changes for them, no?
Yes it probably would make sense if we knew that the stash had been created with "--keep-index". At the moment I don't think there is anywhere to tell from looking at the stash if that's the case but we could add a trailer to the commit message when we create the stash to record that it was created with "--keep-index" and apply only the unstaged changes when we see that trailer.
Thanks
Phillip
Show 49 quoted lines
> Thanks.
>
> (the script left for reference without comments below).
>
>> ---- 8< ----
>> #!/bin/sh
>>
>> USAGE="${0##*/} [<stash>]"
>> SUBDIRECTORY_OK=1
>> . "$(git --exec-path)/git-sh-setup"
>> cd_to_toplevel
>> require_clean_work_tree stash-pop-unstaged
>>
>> LF='
>> '
>> stash="${1:-stash@{0}}"
>> if ! stash_oid="$(git rev-parse --verify --quiet "$stash")" ||
>> ! oid1="$(git rev-parse --verify --quiet $stash_oid^1)" ||
>> ! oid2="$(git rev-parse $stash_oid^2^@ 2>/dev/null)" ||
>> test "$oid1" != "$oid2"
>> then
>> die "error: '$stash' does not look like a stash commit"
>> fi
>> merge_output="$(git merge-tree --merge-base=$stash_oid^2: HEAD: $stash_oid:)"
>> status=$?
>> if test $status = 0
>> then
>> tree=$merge_output
>> conflict_info=
>> messages=
>> elif test $status = 1
>> then
>> merge_output="$merge_output$LF"
>> tree="${merge_output%%$LF*}"
>> conflict_info="${merge_output%%$LF$LF*}"
>> conflict_info="${conflict_info#*$LF}"
>> messages="${merge_output#*$LF$LF}"
>> else
>> exit 128
>> fi
>> git read-tree --index-output="$GIT_DIR/stash-pop-index" -m -u HEAD $tree &&
>> rm "$GIT_DIR/stash-pop-index" &&
>> if test -n "$conflict_info"
>> then
>> printf '%s' "$messages" >&2
>> printf '%s\n' "$conflict_info" | git update-index --index-info
>> else
>> git stash drop "$stash"
>> fi