我不确定你的困惑来自哪里,尤其是因为git diff
和git cherry
所执行的任务非常不同。
在Git中,通常绘制提交图表(特别是在这种情况下)可以帮助理解,例如运行git log --graph --oneline --all --decorate
命令,或截取gitk
的某个窗口图像,或者(这只是文档下面的建议,修改以匹配你的分支名称,但它将显示我们需要的内容):
git log --oneline --graph --boundary branchA...branchB
在某些情况下,省略
--boundary
可以使结果更加清晰,特别是当有很多提交在对称差异的边界上时。但对于大多数简单情况,它只是添加了合并基础提交,从而有助于阅读结果。
现在,让我们也看一下
git cherry文档,其中有一个很好的例子说明我们如何使用三点对称差异符号来理解
git cherry
的输出。
In a situation where [branch] topic
consisted of three commits, and the
maintainer applied two of them, the situation might look like:
$ git log --graph --oneline --decorate --boundary origin/master...topic
* 7654321 (origin/master) upstream tip commit
[... snip some other commits ...]
* cccc111 cherry-pick of C
* aaaa111 cherry-pick of A
[... snip a lot more that has happened ...]
| * cccc000 (topic) commit C
| * bbbb000 commit B
| * aaaa000 commit A
|/
o 1234567 branch point
这里,提交1234567
是包括--boundary
的一个。通常情况下,三个点的标记只会选择左侧的origin/master
(左侧)提交,例如7654321
、cccc1111
和aaaa111
,以及右侧的master
(右侧)提交,例如cccc000
、bbbb000
和aaaa000
。添加--boundary
将添加共享提交,实际上将这些左半部分和右半部分分开。
看看我们上游的维护人员做了什么:他接受了我们的commit A
和commit C
,一字不差地将它们复制到他的master
中,我们在origin/master
中看到了这一点。他没有接受我们的commit B
,或者至少没有一字不差地接受(从这个命令和git cherry
中我们无法确定他是否采用了我们修改的替代版本)。
现在看看运行git cherry
的示例输出:
In such cases, git-cherry shows a concise summary of what has yet to be
applied:
$ git cherry origin/master topic
- cccc000... commit C
+ bbbb000... commit B
- aaaa000... commit A
这个示例展示了我们在
log [flags] origin/master...topic
的列表中,右侧(
topic
)显示了所有三个提交,而左侧(
origin/master
)没有显示任何提交。对于它所显示的提交——仅在右侧的提交——每个提交都被标记为
-
(已取)或
+
(未取)。
不过,我们没有一个图形片段,因此让我们先使用当前所拥有的内容。
git cherry branchA branchB
[is empty, but]
git cherry branchB branchA
(includes at least)
+ c5f84105c242939a9d18fb9d6355534a80735277
+ 41acd0a40bfeaf3d68185a540c131838651cd889
+ 4859fd89c5dafeed6a68f0881ea6ad081a53fd68
+ 7226c9e5acf5a9d2d33b6aef3e5abf9b040f0b76
+ 4fc3206508d6ce7a19477e4c006608c78bb28801
+ 8816c66ed72da762b9b34858eec5b52a16d0ea99
+ 692d271ab07d4b92e54e72bcda09ee067654acee
这意味着在branchB上没有任何提交不在branchA上,而在branchA上有许多提交(至少是上面列出的7个)不在branchB上。实际上,所有这7个列出的提交也都没有被复制——毫不奇怪,如果左侧(branchB)没有独有的提交,那么所有独有于右侧(branchA)的提交都不可能被复制。
这意味着我们可以得到一个近似的图形,如果我们要求的话(这里的哈希值可能不正确)。
* 692d271 (branchB) commit 7
* ....... commit 6
* ....... commit 5
* ....... commit 4
* ....... commit 3
* ....... commit 2
* c5f8410 commit 1
* xxxxxxx (branchA) branch point
这是一种-可能是唯一的方式-来获取您所看到的输出。
同时:
git diff branchA branchB
git diff branchB branchA
(both produce no output at all.)
这意味着与
branchA
相关联的
源代码树与与
branchB
相关联的
源代码树匹配(在执行差异比较时,可能会进行任何筛选)。有许多方法可以实现这一点,很难说使用了哪些方法,但以下是一个示例:
$ git branch remember-where-we-parked-kids
$ echo new file > new-file && git add new-file
$ echo add another line >> existing-file && git add existing-file
$ git commit -m 'commit a change'
[master 643b37e] commit a change
2 files changed, 2 insertions(+)
create mode 100644 new-file
$ git revert --no-edit HEAD
[master 0af7c6a] Revert "commit a change"
2 files changed, 2 deletions(-)
delete mode 100644 new-file
第一个提交包含添加文件和修改文件的更改。第二个(还原)提交包含删除已添加的文件new-file并将旧文件existing-file恢复到刚才的状态,删除了添加的行。将当前提交与两步前的提交进行比较将不会显示任何差异,因为总共的两个提交都没有做任何事情。
在remember-where-we-parked-kids分支上使用git cherry命令,我们会发现这两个添加提交(修改和其还原)都不在“其他”分支中(该分支只比我们当前分支落后两个提交)。
$ git cherry remember-where-we-parked-kids master
+ 643b37ef242fdc35dfdd4551b42393af3eb91a85
+ 0af7c6a3cf5e49928de132c341c848be80ab84c7
以下是我们的两个提交,还原提交为0af7c6a
,初始更改为643b37e
。将参数反转到git-cherry
中,我们得到了空值,当然git diff
同样为空:
$ git cherry master remember-where-we-parked-kids
$ git diff master remember-where-we-parked-kids
$
“没有更多的信息,我们无法确定你是如何到达现在的状态。” 但是,你所看到的输出结果是这样的。