我已经大量使用Git大约7年了。几天前,我发现了一个让我惊讶的行为。我发现git log
、git blame
和git bisect
表现出了这种奇怪的行为。一个朋友让我知道了--full-history
到git log
的标志,它解决了我的问题。为了我自己的教育,我想知道git blame
和git bisect
是否有等效的修复方法。
请随意查看此回购的问题:https://dl.dropboxusercontent.com/u/1927707/problematic_repo.7z
这是它的日志:
$ git log --graph
* commit b7a8d7aa001d06eb7491ab5fb447a8dd3aa421a8
| Author: Ram Rachum <ram@rachum.com>
| Date: Tue Apr 19 17:45:01 2016 +0300
|
| adding more to some-file
|
* commit 0aa833916e908ea93902a6c4c227f9a884a1bcef
| Merge: 2413945 3068c7d
| | Author: Ram Rachum <ram@rachum.com>
| | Date: Tue Apr 19 17:44:31 2016 +0300
| |
| | Merge branch 'master' into development
| |
| * commit 3068c7d2548f1798b6840f73b13a649937339f28
| | Author: Ram Rachum <ram@rachum.com>
| | Date: Tue Apr 19 16:02:27 2016 +0300
| |
| | Adding sugar to coffee
| |
* | commit 24139451ab954b1f0a9ef616775a3dba0ac81669
|/ Author: Ram Rachum <ram@rachum.com>
| Date: Tue Apr 19 16:01:28 2016 +0300
|
| Creating some-file
|
* commit cf02fbbc40104cd02eea4c7c6f134ef1fd7b5661
Author: Ram Rachum <ram@rachum.com>
Date: Tue Apr 19 16:00:47 2016 +0300
Create coffee
在第一次提交时,添加了文件coffee
。在提交3068c7d
中,我在coffee
文件中添加了一行"sugar"。但后来我将这个分支合并到development
分支中,在那个合并中,出现了一个错误,删除了"sugar"行,使coffee
为空。然后添加了另一个提交b7a8d7a
,进行了一个不相关的更改。
现在我看着我的咖啡,发现里面没有糖。我清楚地记得我在咖啡里加了糖。我运行git log coffee
,得到以下输出:
$ git log coffee
commit cf02fbbc40104cd02eea4c7c6f134ef1fd7b5661
Author: Ram Rachum <ram@rachum.com>
Date: Tue Apr 19 16:00:47 2016 +0300
Create coffee
就是这样。git log
既没有显示添加糖的原始提交,也没有显示删除糖的合并。缺少两个非常相关的提交。
我对这个问题感到沮丧了大约一个小时,因为它发生在一个巨大的企业回购中,在那里很难手动找到提交。
我还尝试使用git bisect
和git blame
来确定两个提交,但这两个工具都忽略了这两个提交。在我完成所有git bisect bad
和git bisect good
操作后,git bisect
向我指出了错误的提交。
然后,正如我一开始所说,一个朋友把我指向--full-history
标志:
$ git log --full-history --graph coffee
* commit 0aa833916e908ea93902a6c4c227f9a884a1bcef
| Merge: cf02fbb 3068c7d
| | Author: Ram Rachum <ram@rachum.com>
| | Date: Tue Apr 19 17:44:31 2016 +0300
| |
| | Merge branch 'master' into development
| |
| * commit 3068c7d2548f1798b6840f73b13a649937339f28
|/ Author: Ram Rachum <ram@rachum.com>
| Date: Tue Apr 19 16:02:27 2016 +0300
|
| Adding sugar to coffee
|
* commit cf02fbbc40104cd02eea4c7c6f134ef1fd7b5661
Author: Ram Rachum <ram@rachum.com>
Date: Tue Apr 19 16:00:47 2016 +0300
Create coffee
这让我很高兴,因为它显示了两个相关的提交,一个添加了糖,另一个删除了糖的合并。所以我的问题得到了解决但我真的希望我能知道如何让git bisect
和git blame
表现得一样好有人知道吗?
有趣。由于线路不在那里,git blame
一开始就毫无帮助。如git blame
的文档所示:
报告没有告诉你任何关于删除或替换;您需要使用诸如gitdiff或"鹤嘴锄"界面在以下段落中简要提及。
在这种情况下,我们可以运行git log -SSugar
来查找它的去向:
$ git log --pretty=oneline -SSugar
3068c7d2548f1798b6840f73b13a649937339f28 Adding sugar to coffee
但CCD_ 27不会立即帮助我们找到它的去向。(正如您刚刚发现的,如果我们想在提到文件时找到那一行,我们可能需要--full-history
,因为添加路径以限制git log
将考虑的提交,还可以通过修剪每个提交的树以仅包含提到的文件,然后使用该TREESAME
代码来简化历史。)
从已知的好版本开始,我们现在可以尝试--reverse
[edit:我注意到3068c7d2548f1798b6840f73b13a649937339f28
==master
,并且在这里实际使用了master
,可能应该直接使用SHA-1]:
$ git blame --reverse master..HEAD coffee
^3068c7d (Ram Rachum 2016-04-19 16:02:27 +0300 1) Sugar
这似乎意味着3068c7d
是该行存在的最后一个rev,因此它必须在该特定路径上的部分或所有子级中删除,这是真的:
$ git log --oneline --graph --decorate --all
* b7a8d7a (HEAD -> development) adding more to some-file
* 0aa8339 Merge branch 'master' into development
|
| * 3068c7d (master) Adding sugar to coffee
* | 2413945 Creating some-file
|/
* cf02fbb Create coffee
这里只有一个提交是3068c7d
的子级,即0aa8339
,因此:
$ git show -m 0aa8339
commit 0aa833916e908ea93902a6c4c227f9a884a1bcef (from 3068c7d2548f1798b6840f73b1
Merge: 2413945 3068c7d
Author: Ram Rachum <ram@rachum.com>
Date: Tue Apr 19 17:44:31 2016 +0300
Merge branch 'master' into development
diff --git a/coffee b/coffee
index 4d0f160..e69de29 100644
--- a/coffee
+++ b/coffee
@@ -1 +0,0 @@
-Sugar
diff --git a/some-file b/some-file
new file mode 100644
index 0000000..e69de29
(我们需要-m
来获得git,以便将合并与双亲进行比较)。这确实是一种有点迂回的方式。
(同时,似乎没有治愈平分问题的方法。好吧,除了"避免邪恶合并"…)