I have this on my windows-bash console and git repository:
$ git stash list
stash@{0}: WIP on Issue55A: cc3f7ff A3
stash@{1}: On Issue55A: A named stash
Then I would like to show/apply/pop with the message (or part of it) and I am trying this one:
$ git stash show stash^{/named}
fatal: ambiguous argument 'stash^{/named}': unknown revision or
path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
I have read this so question: stash@{1} is ambiguous? But no luck trying a lot of options to escape curly brackets.
Anyway with the error message I get I think there is no problem with escape characters.
UPDATED: I know the stash standard options pop/apply/show. But what I asking for is to use all of them searching by "message description" or part of it, as in this answer: https://stackoverflow.com/a/11688523/357618 I have tested it with only a stash save and this works but seems what when there are more than one stash items on list, this not works.
That does look like it should work (but it doesn't work, and can't easily be made to work; I'll explain why in a moment).
As a general rule, it's worth trying passing the same argument directly to git rev-list
to see if that can resolve it to an SHA-1. If you do this, you will just get the same error message again, but that will confirm that it's not something happening in git stash
, and that it's more generic instead.
Here's the root of the problem: git's stash
abuses git's commit DAGs. (The word "abuses" might be a bit strong, but I think it's justifiable.1) What stash
does is hang two (or sometimes three) commits from the current branch-tip, but not put these commits on any branch. Instead, if you make two stashes on two different branches, you get this sort of arrangement (let's assume stash@{1}
was made on branch1
and stash@{0}
on branch0
just for consistency and concreteness):
... - A - B - C - D <-branch1
\ |\
\ i-w <-- stash@{1}
\
E - F <-- branch0
|\
i-w <-- stash@{0}
These i-w
pairs are the stash commits. The i
commit contains the index state and the w
commit contains the work-tree state. Commit w
is a merge commit, even though it has nothing to do with merging; each w
's first parent is the on-branch commit (D
or F
) and its second is the i
commit.
Note that there is only one git reference involved here, which is refs/stash
. The other thing git stash
might be said to abuse (rather less of an abuse in this case I think, since we're already in trouble via the commit-DAG abuse) is git's reflogs: stashes other than the most recent, stash
or stash@{0}
, are simply reflog entries: stash@{1}
, stash@{2}
, and so on.
In any case, the revspec^{/text}
syntax directs git rev-parse
to start at the given revspec
and then walk the commit graph backwards, looking for a commit whose message contains the given text
. In your case both stashes were no doubt made on the same branch—something like:
... - A - B - C - D <-- branch
|\__
| \ \
| i-w <-- stash@{0}
|\
i-w <-- stash@{1}
perhaps—but the point is that starting from either of these w
ork-tree commits, the backwards walk will check commit D
, then commit C
, then B
, then A
, and so on. It will never hit the other stash at all! The same holds even if the two stash-bags are hung from two different commits:
... - A - B - C - D <-- branch
|\ |\
i-w i-w
Starting from the stash-bag hung off D
, the rev-list walk is (the second) w
, then D
, C
, B
, A
, and so on. Starting from the one hung off B
, it's (the first) w
, then B
, then A
, and so on.
Anyway, the short answer is that commit text searches apply to the commit graph, not to reflogs, and git's stashes are done via reflogs. If git stash
used a different method to retain the commits and their parentage, that could make it work, but changing this would be nontrivial (in particular you'd have to support multiple stash forms for some transition period).
1I claim that both the word "abuse" and the actual abuse itself are justifiable. The word seems justified because these stash-bags aren't really merges, they're just stored as merges so that the git stash
code can save two or even three work-trees in a convenient and recoverable form. The abuse itself seems justified because this does a perfect job of saving the trees and making them convenient and recoverable.