In git, is there a way to show untracked stashed files without applying the stash?
If I run git stash -u
, I can stash untracked files. However, said untracked files don't show up at all with git stash show stash@{0}
. Is there any way to show untracked stashed files without applying the stash?
Solution 1:
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".
Solution 2:
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:
Show only untracked, stashed files
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.
Find a specific file
git rev-list -g stash | xargs -n1 git ls-tree -r | sort -u | grep <pattern>
Grep untracked files
git rev-list -g stash | git rev-list --stdin --max-parents=0 | xargs git grep <pattern>
List all contents of all stashes
git rev-list -g stash | git rev-list --stdin | xargs git show --stat