Reputation: 35138
Is git broken or what are we doing wrong ? ;-)
We found out, that a file was changed in a recent version of the git repository and I tried to figure out when that was using whatchanged
.
How can this be:
$ git checkout 27773b72432e86d308d25d666663f237e50aa3fd Tools/foo.php
$ md5sum Tools/foo.php
85552061cae9832c11eb6607ac88e3d8 Tools/foo.php
$ git checkout master Tools/foo.php
$ md5sum Tools/foo.php
f38f51232785a432af2d1bd8db4429ed Tools/foo.php
BUT:
$ git whatchanged 27773b72432e86d308d25d666663f237e50aa3fd..master | grep foo.php
# empty result
How can this be?
Upvotes: 4
Views: 124
Reputation: 45819
The short answer is, you might want to try using
git whatchanged master..27773b72432e86d308d25d666663f237e50aa3fd
(It's true that you really should probably use git log
instead, but that isn't related to why it isn't doing what you expect.)
Here's some info that will help understand why:
That notation 27773b72432e86d308d25d666663f237e50aa3fd..master
does not, as other users have suggested, mean "a range of commits starting at (but excluding) 27773b7
and ending at (and including) master
". It sometimes reduces to that, but that isn't what it means. (And you'll see in a minute why the distinction is important.)
What it means is, "all commits that are reachable from master
, but that are not reachable from 27773b7
". (Where "reachable" means via parent pointers.)
Now if we assume that your commit graph looks like
.... 27773b7 -- A -- B -- C <--(master)
then this would reduce to the type of "range" others have identified. But in that case, you wouldn't be experiencing the problem. That's because you've shown that the file at 27773b7
is different from the file at C
(master
), which means either A
or B
or C
must have changed it. If your commit graph looked like that.
So we can conclude that your commit graph doesn't look like that.
Another way it could look is
--- o -- A -- 27773b7 -- x ...
\
B -- C <--(master)
In this graph, 27773b7...master
means just B
and C
, because A
is not reachable by master
, and while o
is reachable by master
, it's also reachable by 27773b7
.
Now it's possible that the reason the file is different at 27773b7
is that it was changed either by A
or by 27773b7
itself. In either case, using 27773b7^
(as other answer suggests) would not help.
Which brings me back to my point: if you really want to think of the A..B
notation as defining a range, the start of the range can not be assumed to be A
; if anything, you'd expect it to be the merge base between A
and B
(if there is one; sometimes it could just be the root of B
s commit hierarchy) - and that's equal to A
only if A
is reachable from B
. And at any rate, you can't assume its a linear range of commits.
But understanding the subset of the commit graph it really indicates makes it more clear, that if A..B
shows nothing you might need to try B..A
.
Upvotes: 3
Reputation: 5036
A range specified as A..B
means from A to B but excluding A. See https://git-scm.com/docs/gitrevisions#gitrevisions-Theememtwo-dotRangeNotation
If revision 27773b7
is the only revision in which the file Tools/foo.php
has been changed, then the range 27773b7..master
excludes exactly that only change.
Update:
What you want is to include A but exclude all its parents. The shortcut for that is A^!
. See https://git-scm.com/docs/gitrevisions#_other_rev_parent_shorthand_notations.
So, your command would be
$ git whatchanged 27773b7^! master | grep foo.php
One last note: https://git-scm.com/docs/git-whatchanged suggests to use git log
instead of git whatchanged
.
To get a list of the file names only, you would say:
$ git log --name-only --format="" (other arguments here)
That would make sure that when you grep
that output you would not accidentally match a comment.
Upvotes: 1