Git does not show change even the file changed


Git does not show change even the file changed



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.


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?





You can configure git to ignore line endings for one thing. I don't think you can make md5sum ignore them :)
– Mad Physicist
Jun 29 at 15:37





It's not line endings. It's a real code change. I just used md5sum to illustrate the problem
– Alex
Jun 29 at 15:42





@Alex what happened when you apply a diff instead of whatchanged in final command?
– Supun Wijerathne
Jun 29 at 16:12




2 Answers
2



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.)


git log



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.)


27773b72432e86d308d25d666663f237e50aa3fd..master


27773b7


master



What it means is, "all commits that are reachable from master, but that are not reachable from 27773b7". (Where "reachable" means via parent pointers.)


master


27773b7



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.


27773b7


C


master


A


B


C



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.


27773b7...master


B


C


A


master


o


master


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.


27773b7


A


27773b7


27773b7^



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 Bs 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.


A..B


A


A


B


B


A


A


B



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.


A..B


B..A



A range specified as A..B means from A to B but excluding A. See https://git-scm.com/docs/gitrevisions#gitrevisions-Theememtwo-dotRangeNotation


A..B



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.


27773b7


Tools/foo.php


27773b7..master



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.


A^!



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.


git log


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.


grep





You might also add a suggestion about how to get the desired results.
– Code-Apprentice
Jun 29 at 17:48





No, this analysis is wrong. If the file at 27773b7 differs from the file at master, the issue isn't that the range is excluding a change that 27773b7 made.
– Mark Adelsberger
Jun 29 at 19:45





@MarkAdelsberger git log (or git whatchanged) prints what has been changed in each revision in the range. It does not make a diff. So, when none of the selected revisions includes a change of the selected file, you won't see it.
– Adrian W
Jun 29 at 19:51



git log


git whatchanged





@AdrianW - Yes, but that's beside the point. If, as you assume in your answer, 27773b7 were an ancestor of master, AND the file differs between 27773b7 and master, that would mean that some commit AFTER 27773b7 had changed the file. A change made by 27773b7 - the change that you keep pointing out would be excluded - would already be accounted for in the version of the file AT 27773b7, so it would not be a difference between that and the master version. This is not hard to test if you remain confused (it took me about 5 minutes to set up and verify).
– Mark Adelsberger
Jun 29 at 20:44


master


master






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Comments

Popular posts from this blog

paramiko-expect timeout is happening after executing the command

Opening a url is failing in Swift

Export result set on Dbeaver to CSV