git diff和git cherry之间的区别

时间:2016-05-04 18:06:40

标签: git

我有两个分支:branchA,branchB

以下命令不返回任何输出(包括没有差异,至少对于git diff命令而言):

git cherry branchA branchB
git diff branchA branchB
git diff branchB branchA

然而,当我运行时:

git cherry branchB branchA

我得到一个提交ID列表,前面都有一个加号:

e.g。

+ c5f84105c242939a9d18fb9d6355534a80735277
+ 41acd0a40bfeaf3d68185a540c131838651cd889
+ 4859fd89c5dafeed6a68f0881ea6ad081a53fd68
+ 7226c9e5acf5a9d2d33b6aef3e5abf9b040f0b76
+ 4fc3206508d6ce7a19477e4c006608c78bb28801
+ 8816c66ed72da762b9b34858eec5b52a16d0ea99
+ 692d271ab07d4b92e54e72bcda09ee067654acee

有人可以解释一下这意味着什么吗?想要理解为什么git diff没有显示出差异,但git cherry显示出差异。

3 个答案:

答案 0 :(得分:2)

Git diff显示没有输出,因为两个分支中的文件内容相同。但是,提交ID(SHA字符串)可能不同。

git cherry branchA BranxhB没有输出,因为分支B中的所有提交(SHA而不是文件内容)都存在于分支A中。但反之亦然。分支A中有一些提交不在分支B中,因此是git cherry branchB branchA的输出。这里用例子很好地解释了这一点。 http://jafrog.com/2012/03/22/git-cherry.html

答案 1 :(得分:1)

这意味着branchAbranchB的内容相同,但由于某种原因,branchB上的提交不在branchA上。

正在显示这些提交。但是,这些提交的总和会产生相同的内容,因此您不会看到任何差异。您也不会看到git cherry branchA branchB的任何内容,因为branchB上没有branchA上的提交。

答案 2 :(得分:0)

我不确定你的困惑来自哪里,特别是因为git diffgit cherry做了很多不同的事情。

绘制提交图或至少相关部分(例如,运行git log --graph --oneline --all --decorate或从gitk剪切一些窗口图像可能会有帮助(在Git中几乎总是如此)或者(这只是文档中的建议,经过修改以匹配您的分支名称,但它会显示我们需要的内容):

git log --oneline --graph --boundary branchA...branchB

(在某些情况下,当对称差异的边界上存在很多提交时,省略--boundary可以使这更加清楚,但是对于大多数简单情况,它只是添加了合并基础提交,因此帮助阅读结果。)

现在,让我们看一下the git cherry documentation,它有一个很好的例子,说明我们如何使用三点对称差异表示法来理解git cherry的输出:

  

在[branch] topic由三个提交组成的情况下,并且     维护者应用其中两个,情况可能如下:

$ 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(左侧)提交,例如7654321cccc1111aaaa111,用于{{1}的左半部分和...(右侧)提交,如mastercccc000bbbb000提交右半部分。添加aaaa000会添加共享提交,实际上会将这些左半部分和右半部分分开。

看看我们的维护人员上游做了什么:他接受了我们的--boundary和我们的commit A,将他们的变更更改为我们在{{1}中看到的commit C }}。他没有接受我们的master,或者至少,不是改变变化(我们无法从这里得知,也不能从origin/master,如果他已经采取了一些我们变更的替代版本。)

现在查看运行commit B的示例输出:

  

在这种情况下,git-cherry显示了尚未完成的内容的简明摘要    施加:

git cherry

这向我们展示了右侧(git cherry)的所有三个提交,而未向我们显示左侧提交的任何提交({{ 1}}),我们的$ git cherry origin/master topic - cccc000... commit C + bbbb000... commit B - aaaa000... commit A 列表。

对于提交, 显示 - 仅在右侧显示 - 它标记每个提交topic(已拍摄)或origin/master(未拍摄)。

我们没有图形片段,所以让我们一起使用我们现在拥有的东西。

log [flags] origin/master...topic
     

[空,但是]

-
     

(至少包括)

+

这意味着branchB上的 no 提交不在branchA上,而在branchA上有很多(至少上面列出的7个)提交,而不是在branchB上。事实上,列出的所有7个都没有被复制 - 这并不奇怪,如果没有任何exlusive-to-left,那么没有一个可以被复制的排他性到右侧的git cherry branchA branchB 提交。 -side(git cherry branchB branchA )提交。

这意味着我们可以绘制一个我们可能得到的图的近似值,如果我们要求一个(我可能在这里有错误的缩写哈希):

+ c5f84105c242939a9d18fb9d6355534a80735277
+ 41acd0a40bfeaf3d68185a540c131838651cd889
+ 4859fd89c5dafeed6a68f0881ea6ad081a53fd68
+ 7226c9e5acf5a9d2d33b6aef3e5abf9b040f0b76
+ 4fc3206508d6ce7a19477e4c006608c78bb28801
+ 8816c66ed72da762b9b34858eec5b52a16d0ea99
+ 692d271ab07d4b92e54e72bcda09ee067654acee

这是一种方式 - 可能是唯一的方式 - 获得您看到的输出。

同时

branchA
     

(两者都没有输出。)

这只是意味着附加到branchB源代码树与附加到* 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

第一次提交包含添加文件和修改文件的更改。第二个(恢复)提交包含一个更改,删除添加的文件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

(这些是我们的两次提交,即还原,git cherry和初始更改remember-where-we-parked-kids)。将$ git cherry remember-where-we-parked-kids master + 643b37ef242fdc35dfdd4551b42393af3eb91a85 + 0af7c6a3cf5e49928de132c341c848be80ab84c7 的参数反转,我们什么也得不到,当然0af7c6a同样是空的:

643b37e

如果没有更多信息,就无法说出你现在的位置,但这就是你所看到的输出意味着什么。