Stash Untracked Files Using “git add” You have to add the untracked files of the repository by using the “git add” command and run the “git stash” command to save the untracked file and clean the current directory for working by removing the untracked file from the repository folder.
In order to stash untracked files, add the “–include-untracked” option to your “git stash” initial command. Alternatively, you can simply use the “-u” which is equivalent to the untracked longer version.
git stash show will show you the files that changed in your most recent stash. You can add the -p option to show the diff. Use git stash show -p stash@{0} to see a specific stash.
Untracked files are stored in the third parent of a stash commit. (This isn't actually documented, but is pretty obvious from The commit which introduced the -u feature, 787513..., and the way the rest of the documentation for git-stash
phrases things... or just by doing git log --graph 'stash@{0}'
)
You can view just the "untracked" portion of the stash via:
git show 'stash@{0}^3'
or, just the "untracked" tree itself, via:
git show 'stash@{0}^3:'
or, a particular "untracked" file in the tree, via:
git show 'stash@{0}^3:<path/to/file>'
There is, unfortunately, no good way to get a summary of the differences between all staged+unstaged+untracked vs "current" state. ie: git show 'stash@{0}'
cannot be made to include the untracked files. This is because the tree object of the stash commit itself, referred to as stash@{0}:
, does not include any changes from the third, "unstaged" parent.
This is due to the way stashes are re-applied: tracked files can be easily applied as patches, whereas untracked files can only be applied, in theory, as "whole files".
You can list all stash commits with the following command:
git rev-list -g stash
Since stashes are represented as a 3-way merge commit of HEAD, the index, and a parent-less "root" commit of untracked files, untracked file stashes can be listed by piping the above output into the following:
git rev-list -g stash | git rev-list --stdin --max-parents=0
Useful applications of the above:
git rev-list -g stash | git rev-list --stdin --max-parents=0 | xargs git show --stat
Of course, remove the --stat
to see the contents of the files.
git rev-list -g stash | xargs -n1 git ls-tree -r | sort -u | grep <pattern>
git rev-list -g stash | git rev-list --stdin --max-parents=0 | xargs git grep <pattern>
git rev-list -g stash | git rev-list --stdin | xargs git show --stat
To list the untracked files in the stash:
git ls-tree -r stash@{0}^3 --name-only
To show a complete diff of all untracked files (with content):
git show stash@{0}^3
These commands read the last (most recent) stash. For earlier stashes, increment the number behind the "stash@", for example stash@{2}
for the second from the last stash.
The reason this works is that git stash
creates a merge commit for each stash, which can be referenced as stash@{0}
, stash@{1}
etc. The first parent of this commit is the HEAD at the time of the stash, the second parent contains the changes to tracked files, and the third (which may not exist) the changes to untracked files.
This is partly explained in the manpage under "Discussion".
However, said untracked files don't show up at all with
git stash show stash@{0}
.
Note: since Git 2.11 (Q4 2016, 4 years after theis OP), you can reference stash with its index only
git stash show 0
There was a more recent bug due to git stash
being rewritten in C, fixed in Git 2.22 (Q2 2019)
Is there any way to show untracked stashed files without applying the stash?
Why, yes, there is, with Git 2.32 (Q2 2021, 9 years after the OP).
"git stash show
"(man) learned to optionally show untracked part of the stash.
See commit 0af760e, commit d3c7bf7 (03 Mar 2021) by Denton Liu (Denton-L
).
(Merged by Junio C Hamano -- gitster
-- in commit f5c73f6, 22 Mar 2021)
stash show
: teach--include-untracked
and--only-untracked
Signed-off-by: Denton Liu
Stash entries can be made with untracked files via
git stash push --include-untracked
(man).However, because the untracked files are stored in the third parent of the stash entry and not the stash entry itself, running
git stash show
(man) does not include the untracked files as part of the diff.With
--include-untracked
, untracked paths, which are recorded in the third-parent if it exists, are shown in addition to the paths that have modifications between the stash base and the working tree in the stash.It is possible to manually craft a malformed stash entry where duplicate untracked files in the stash entry will mask tracked files.
We detect and error out in that case via a customunpack_trees()
callback:stash_worktree_untracked_merge()
.Also, teach stash the
--only-untracked
option which only shows the untracked files of a stash entry.
This is similar togit show stash^3
(man) but it is nice to provide a convenient abstraction for it so that users do not have to think about the underlying implementation.
git stash
now includes in its man page:
'git stash' show [-u|--include-untracked|--only-untracked] [<diff-options>] [<stash>]
git stash
now includes in its man page:
--no-include-untracked
When used with the
push
andsave
commands, all untracked files are also stashed and then cleaned up withgit clean
.When used with the
show
command, show the untracked files in the stash entry as part of the diff.
--only-untracked
This option is only valid for the
show
command.
Show only the untracked files in the stash entry as part of the diff.
And you have a configuration to goes with those new options:
stash show
: learnstash.showIncludeUntracked
Signed-off-by: Denton Liu
The previous commit teaches
git stash show --include-untracked
(man).
It may be desirable for a user to be able to always enable the--include-untracked
behavior.
Teach thestash.showIncludeUntracked
config option which allows users to do this in a similar manner tostash.showPatch
.
git config
now includes in its man page:
stash.showIncludeUntracked
If this is set to true, the
git stash show
command without an option will show the untracked files of a stash entry.Defaults to false.
git stash
now includes in its man page:
You can use
stash.showIncludeUntracked
,stash.showStat
, andstash.showPatch
config variables to change the default behavior.
With Git 2.32 (Q2 2021), the code to handle options recently added to "git stash show
"(man) around untracked part of the stash segfaulted when these options were used on a stash entry that does not record untracked part.
See commit 1ff595d, commit aa2b05d (12 May 2021) by Denton Liu (Denton-L
).
(Merged by Junio C Hamano -- gitster
-- in commit a8a2491, 16 May 2021)
stash show
: fix segfault with--{include,only}-untracked
Signed-off-by: Denton Liu
When
git stash show --include-untracked
(man) orgit stash show --only-untracked
(man) is run on a stash that doesn't include an untracked entry, a segfault occurs.This happens because we do not check whether the untracked entry is actually present and just attempt to blindly dereference it.
Ensure that the untracked entry is present before actually attempting to dereference it.
And:
See commit af5cd44 (21 May 2021) by Denton Liu (Denton-L
).
(Merged by Junio C Hamano -- gitster
-- in commit 378c7c6, 22 May 2021)
stash show
: usestash.showIncludeUntracked
even whendiff
options givenSigned-off-by: Denton Liu
If options pertaining to how the diff is displayed is provided to
git stash show
(man), the command will ignore thestash.showIncludeUntracked
configuration variable, defaulting to not showing any untracked files.
This is unintuitive behaviour since the format of the diff output and whether or not to display untracked files are orthogonal.Use
stash.showIncludeUntracked
even when diff options are given.
Of course, this is still overridable via the command-line options.Update the documentation to explicitly say which configuration variables will be overridden when a diff options are given.
git config
now includes in its man page:
If this is set to
true
, thegit stash show
command will show the untracked files of a stash entry.Defaults to
false
.
git stash
now includes in its man page:
If no
<diff-option>
is provided, the default behavior will be given by thestash.showStat
, andstash.showPatch
config variables.You can also use
stash.showIncludeUntracked
to set whether--include-untracked
is enabled by default.
To see all the files in the stash (both tracked and untracked), I added this alias to my config:
showstash = "!if test -z $1; then set -- 0; fi; git show --stat stash@{$1} && git show --stat stash@{$1}^3 2>/dev/null || echo No untracked files -"
It takes a single argument of which stash you want to view. Note it will still present it in two back-to-back lists.
The if...fi
section changes the bash argument $1 to 0 if none was passed.
A workaround: Staging files before stashing them will make git stash show -p
work as expected.
git add .
git stash save
Note: This way gives the power adding interactive portions too, here is how.
Caution: Ensure you don't have previously staged work, or you won't be able to distinguish it.
This may be of use.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With