From: Phillip Wood Date: Mon, 18 Aug 2025 15:14:13 GMT Subject: Re: [FEATURE] Proposal: git stash --only-unstaged Message-ID: <89394e50-9077-4a7b-b30e-afd1be1a40e8@gmail.com> In-Reply-To: On 17/08/2025 17:08, Junio C Hamano wrote: > Phillip Wood 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 > Thanks. > > (the script left for reference without comments below). > >> ---- 8< ---- >> #!/bin/sh >> >> USAGE="${0##*/} []" >> 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