1

I want to display a patch for a single file of a certain stash. Usually with git-diff you can append the -- <pathspec> to limit the output.

Now the git-stash manpage states the following for the show command...

By default, the command shows the diffstat, but it will accept
any format known to git diff

... but unfortunately it does not accept a trailing pathspec, so the following command won't work

$ git stash show -p --include-untracked stash@{0} -- test/foo.txt                   
Too many revisions specified: 'stash@{0}' 'test/foo.txt'

The reason I want to use git-stash for this is because it has the --include-untracked option. Is there a way to limit the output to a specific pathspec, or emulate the behavior of

git stash show -p --include-untracked stash@{0}

with a regular git-diff call?

Henry Ecker
  • 34,399
  • 18
  • 41
  • 57
  • Yes, the default for `git stash show` is to diff vs ^ where is the "w" (working tree) commit for the stash, whose hash ID is the one you get with `git rev-parse refs/stash`. You can just write `stash^ stash` as the two commit hash IDs passed to `git diff` here. Note that `--include-untracked` (used at stash creation time) just creates a *third* commit in the stash for these files; that's `stash^3`, with `stash^2` holding the index commit. Commit `stash^3` has no parent (so there's nothing to diff against). – torek May 03 '22 at 05:11
  • `git stash show` is learning or has learned to accept pathspecs in Git 2.36 or later, I believe. However, Git 2.36 has acquired some bugs when dealing with pathspecs and `git diff`, so you might want to hold off on using the new feature until all the bugs are ironed out. :-) – torek May 03 '22 at 05:13
  • If what you want is to list out (or show) the "u" commit's files within some particular directory, consider diffing it against the [empty tree](https://stackoverflow.com/q/9765453/1256452). That is, if you've made the name `empty` for the empty tree, `git diff empty stash^3 -- ` will produce such a diff. Every file will be added from scratch, though, so `--name-only` might be more useful. – torek May 03 '22 at 05:19
  • It has to work for any stash, not just untracked or regular. `git diff stash^3` won't work on regular stashes unfortunately. –  May 03 '22 at 07:31
  • Yes, you'll have to test the stash to see if `stash^3` exists to determine whether it's a two-commit (no untracked files) or three-commit (untracked files) stash. – torek May 03 '22 at 07:46
  • But there is also a 3rd option, where the stash contains tracked and untracked files. Diffing against `stash^3` won't work for those. You'd essentially have to make 2 diffs and combine them (which is what `--include-untracked` does I think). –  May 03 '22 at 08:05
  • All stashes contain tracked files: that's what the i (index) and w (working tree) commits are. *Some* stashes *also* contain *untracked* files. And yes, it takes two `git diff` invocations here (which is why it's kind of broken in Git 2.36, which releases pathspecs after running one diff). – torek May 03 '22 at 08:07

0 Answers0