I know that you can select a revision using the :/<text>
-syntax documented in gitrevisions(1), e.g.
git show :/"new change"
would show the (youngest reachable) commit with "new change" in the commit message.
I also often use the feature to git show
a blob in a specific revision, e.g.
git show myBranch:./coolFile.csv
to view the whole content of coolFile.csv
(in a relative path to me) in the state of revision myBranch
.
Now my question: Can I select a revision using the :/<text>
syntax and then show a blob in that revision? I have tried
git show (:/"new change"):./coolFile.csv
git show :/"new change":./coolFile.csv
That threw the error
fatal: ambiguous argument ':/new change:./coolFile.csv': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git [<revision>...] -- [<file>...]'
so I tried
git show :/"new change" -- ./coolFile.csv
which printed nothing because that syntax only prints the changes of that revision in that file.
CodePudding user response:
You could have used command substitution :
git show $(git rev-list -1 :/"new change"):coolFile.csv
(Here git rev-list
just outputs the wanted revision hash)
Note (thanks to @phd): this is a bash mechanism, it won't work in windows cmd.
CodePudding user response:
Command substitution (as in Romain Valeri's answer) or some other two-step process is usually the way to go. Note, however, that the problem here is syntactic: :/regex
has no way to terminate the regular expression and resume a revision specifier. If we look at the gitrevisions documentation, we find that this :/regex
or :/<text>
syntax:
... names a commit whose commit message matches the specified regular expression. This name returns the youngest matching commit which is reachable from any ref, including HEAD
(boldface mine).
Shortly above this description for :/<text>
we find:
^{/<text>}, e.g. HEAD^{/fix nasty bug}
described this way:
... is the same as the
:/fix nasty bug
syntax below except that it returns the youngest matching commit which is reachable from the<rev>
before^
.
This syntax does have the equivalent of a "close parenthesis", namely the closing brace. So if you're willing to search from HEAD
or some other single ref exclusively, rather than from every ref, you can replace :/foo
with HEAD^{/foo}
, and this can be followed by :./coolFile.csv
:
git show HEAD^{/new\ change}:./coolFile.csv
The fact that some revspec arguments cannot be appended-to was missed in some shell-script Git commands for some time, where people did things like:
set -e # if/as appropriate
cmt=$(git rev-parse "$1"^{commit})
tree=$(git rev-parse "$1"^{tree})
... go on to use $cmt as the commit and $tree as the tree ...
when in fact we must do:
t=$(git rev-parse "$1")
cmt=$(git rev-parse $t^{commit})
tree=$(git rev-parse $t^{tree})
in case $1
reads :/fix nasty bug
for instance.