0

I'm currently trying to find some changes in a stash, which I know is stash@{1}. For this, I'm using git grep:

git grep somePattern stash@{1} 

This returns me what I'm searching for.

However, when running git stash show, these changes aren't here and I get a different diff, not containing my changes.

git stash show stash@{1} 

Same thing if I try to git stash apply said changes.

Is there any behavior of git stash that is preventing changes to be part of this stash when showing/applying it?

2 Answers 2

4

git grep searches for a pattern in the complete content of a commit (not just the changes it introduced).

If somePattern is present in any other file (including a file not changed in the stash), you will see an output.


If you want to spot files where the changes contain the pattern, instead of git grep, try one of :

git show -S somePattern stash@{1} # or : git show -G somePattern stash@{1} 

In your case : it looks like the pattern you are looking for is not part of the changes of stash@{1}.

If you want to inspect the content of all your stash entries, use one of the -S or -G options on git reflog stash :

# * you also need the '-m' option when inspecting the stash, because all # stash entries are actually merge commits # * '-p' will print the patch of files matching the pattern, and will # allow you to see if those are the changes you are looking for git reflog --oneline -m -S somePattern -p stash 
Sign up to request clarification or add additional context in comments.

4 Comments

Be careful with git show here: you'll need -m and/or --first-parent. (With an upcoming Git, there's a new flag that means -m --first-parent.)
Thank you for this. I've tried both commands, and they still didn't show the diff I was searching for. Also, somePattern doesn't seem to be present in current commit state: - If I git grep somePattern stash@{1}, it shows the file - If I cat path-of-file-from-that-grep-output, the change is not there. So logically, it should be present in the git show or git stash show output?
@torek : I had forgotten a stash is a merge commit, updating my answer. Thanks. [edit] I need the -m option for git reflog -S ..., but git show -S ... works straight away (the diff is presented in the combined diff format by default). Is this behavior a recent change ?
You'll get a diff if the merged file is "different from all parents" (so, different from both index and previous-commit). I may have overstated the case in my own answer: if you haven't git add-ed a file, you can get a diff. Still, the combined diff will drop some changes from this diff. It's never been completely clear to me which diff hunks get dropped in combined diffs; I should take some time to study that...
1

There are multiple possible reasons for this:

  • A stash is actually a complex of two (or sometimes three) commits. The git grep operation looks in the W (work-tree) commit, completely ignoring the I (index-state) commit.1

  • As LeGEC notes, git stash show generates a diff. The diff is from the W commit's parent to the W commit.

  • It's easy to accidentally run git show stash instead of git stash show. This works, for some definition of work, but also fails because a stash is a complex of commits. The W commit has the form of a merge commit.2 This makes git show use a combined diff to show it, and because of the way stashes are built, this combined diff can be completely empty (it depends on what you've git add-ed when you run git stash).

It's hard to know precisely which of these issues you might have hit, but all of them will cause confusion.


1If a third commit exists, it holds the untracked files, and git grep ignores it too. That's because refs/stash, or stash@{whatever}, points to the W commit.

2This means that the W commit is a merge commit. But it wasn't made by git merge, and the normal Git tools, applied to it, produce nonsensical results. The reason W is a merge is to be able to find the rest of the stash commits, plus the commit from which the stash was made, all with simple gitrevisions syntax.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.