即使文件已更改,Git也不显示更改

时间:2018-06-29 15:35:44

标签: git

git坏了还是我们做错了什么? ;-)

我们发现,该文件在git存储库的最新版本中已更改,我试图找出何时使用whatchanged

怎么可能:

$ 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

但是:

$ git whatchanged 27773b72432e86d308d25d666663f237e50aa3fd..master  | grep foo.php
# empty result

怎么可能?

2 个答案:

答案 0 :(得分:3)

简短的答案是,您可能想尝试使用

git whatchanged master..27773b72432e86d308d25d666663f237e50aa3fd

(的确,您实际上应该使用git log来代替,但这与为什么它没有达到您的期望无关。)

以下一些信息可帮助您了解原因:

该符号27773b72432e86d308d25d666663f237e50aa3fd..master不会不是,正如其他用户所建议的那样,意思是“一系列的提交起始于(但不包括)27773b7并结束于(包括) master”。有时它可以简化为那个,但这不是意思。 (您很快就会看到区别的重要性。)

这意味着“从master可以到达但从27773b7不能到达的所有提交”。 (“可达”是指通过父指针。)

现在,如果我们假设您的提交图看起来像

 .... 27773b7 -- A -- B -- C <--(master)

那么这将减少到其他人已经确定的“范围”类型。但是在那种情况下,您将不会遇到问题。这是因为您已经证明27773b7上的文件与Cmaster)上的文件不同,这意味着AB或{ {1}}必须已更改。如果您的提交图看起来像这样。

所以我们可以得出结论,您的提交图不是像这样。

它看起来的另一种方式是

C

在此图中,--- o -- A -- 27773b7 -- x ... \ B -- C <--(master) 仅表示27773b7...masterB,因为C无法访问A,而master < o可以到达em> ,master也可以到达。

现在,27773b7上文件不同的原因可能是它被27773b7A本身更改了。无论哪种情况,使用27773b7(如其他答案所示)都无济于事。

这让我回到了我的观点:如果您真的想将27773b7^表示法定义为范围,则可以将范围的开头假定为{{ 1}};如果有的话,您希望它是A..BA之间的合并基础(如果有的话;有时它可能只是A提交层次结构的根)-并且仅当B可以到达B时,该值才等于A。而且无论如何,您不能假定其线性的提交范围。

但是了解提交图的子集确实可以使我们更加清楚,如果A没有显示任何内容,则可能需要尝试B

答案 1 :(得分:1)

指定为A..B的范围表示从A到B,但排除A。请参见https://git-scm.com/docs/gitrevisions#gitrevisions-Theememtwo-dotRangeNotation

如果修订27773b7是唯一更改了文件Tools/foo.php的修订,则范围27773b7..master排除了仅此更改。

更新

您想要的是包含A,但排除其所有父项。快捷方式是A^!。参见https://git-scm.com/docs/gitrevisions#_other_rev_parent_shorthand_notations

所以,您的命令应该是

$ git whatchanged 27773b7^! master | grep foo.php

最后一点:https://git-scm.com/docs/git-whatchanged建议使用git log代替git whatchanged

要仅获取文件名列表,您应该说:

$ git log --name-only --format="" (other arguments here)

这将确保您在grep输出时不会意外匹配注释。