2

我试图理解git diffvs. git rev-listor之间的符号差异的基本原理(如果有的话) git log

澄清:

我了解每个命令的作用,如下所述。我只是想解释一下为什么 Git 会在两个不同的命令中使用相同的符号,以便一个直观地(IHO)与另一个相反。

git log/rev-list

在 log 和 rev-list 中,当您想查看分叉分支的两侧(对称)时,符号是三个点 ( ...)。例如,

$ git log --oneline --boundary a...b
* aaaaa Commit to Branch a
| * bbbbb Commit to branch b
|/
o 000000

而两个点 ( ..) 只会显示右侧(不对称)。例如,

$ git log --oneline --boundary a..b
* bbbbb Commit to branch b
o 000000

混帐差异

但是,使用 git diff 两个点 ( ..) 显示了对称差异(我的话),即,它显示了列出的两个确切提交之间的差异,例如,

git diff a..b

显示 aaaaa 和 bbbbb 的树之间的差异。

而三个点 ( ...) 显示了不对称差异,即,它显示了两个提交的合并基础与第二个提交之间的差异。例如,

git diff a..b 

显示 00000 和 bbbbb 的树之间的差异。

4

2 回答 2

0

中的点表示法git-log指定了一个所谓的修订范围,这正是它的名称所说的,以及您通过示例所描述的内容。使用它是因为 的目的git-log是显示提交列表(范围)。

git-diff也使用修订范围,但如果你现在让我引用:

然而,“差异”是关于比较两个端点,而不是范围,并且范围符号(“..”和“...”)并不意味着 gitrevisions [7] 中的“指定范围”部分中定义的范围。

来自 git-diff 的文档。

于 2015-12-17T17:41:45.990 回答
0

TL;DR 答案: git diff根本不做对称差异(也没有任何集合)。它只是找到一些提交对,并区分那对提交。

首先(顺便说一句,为了清楚起见,以防各种访问者在“对称差异”中遇到“差异”一词,git diff而不是几乎不相关的命令),让我在这里注意对称差异git rev-list指to 是图论对称差,即集合并集减去集合交集。在这种情况下,联合和相交的两个集合是可以从两个命名提交中的任何一个访问的所有提交的集合:git rev-list a...b解析a以获取提交 ID,然后找到从该提交可访问的所有提交;它解析和处理b类似;然后交叉点从合并基础本身开始,然后返回历史记录。

在您的示例中,这只留下了两个分支提示提交。您添加了--boundary哪些原因git rev-list包括分支点提交(两个历史记录在集合交集的尖端连接)以获得此:

$ git log --oneline --graph --boundary a...b
* aaaaa Commit to Branch a
| * bbbbb Commit to branch b
|/
o 000000

没有--boundary我们会省略提交o(使--oneline --graph无用)。

您当然也正确,使用两个点,a..b您可以从无法到达的提交b中获得可访问的提交(通常这也会省略其自身标识的提交,但再次将其放回结果集中)。aa--boundary

git diff 不同

git logandgit rev-list命令对完整的提交集进行操作。例如,如果您正在查看一组 75 个提交,git log则会显示所有 75 个提交(除非您使用 限制它-n)。

git diff命令不一样。它产生两个提交的比较(差异),并且——只要我们忽略仅适用于合并提交的“组合差异”——它只会查看两个提交。鉴于:

$ git diff HEAD~5 HEAD

很明显,这将 commitHEAD~5与 commit进行比较HEAD,但即使HEAD~5..HEAD名称为 5 个或更多1 个提交:

$ git diff HEAD~5..HEAD

仍然只是比较相同的两个提交,HEAD~5反对HEAD.

(注意:

$ git diff HEAD..HEAD~5

比较相同的两个提交,但告诉您如何修改HEAD提交以产生HEAD~5提交,而不是更典型的“如何修改HEAD~5产生HEAD”。所以顺序确实很重要,但本质git diff上只是在这里用空格替换两个点。)

git diff命令同样采用三点表示法。因为它仍然只会查看两个提交,所以当你给它三点符号时,它会像往常一样找到合并基础提交,但不是修改输入来假装你只是分别命名了左侧和右侧提交,它修改输入以假装您在左侧命名为合并基础,在右侧命名为右侧提交。

对于实际的对称差异(集合操作),操作数的顺序无关紧要。但是由于git diff找到一对,然后用合并基替换左操作数,并将其与右操作数进行比较,这里顺序很重要:将“最终结果”提交名称放在右边,因为git diff会将合并基放入作为左边。


HEAD~5..HEAD产生所有可到达的提交HEAD,但无法从HEAD~5. 在线性结构中,这是五个提交:

... - HEAD~5 - HEAD~4 - HEAD~3 - HEAD~2 - HEAD~1 - HEAD
- excluded -    -------- included: five commits ---------

但是,对于分支和合并结构,其他提交位于此集中:

                       HEAD~3
                      /      \
... - HEAD~5 - HEAD~4         HEAD~2 - HEAD~1 - HEAD
                     \       /
                      HEAD~2^2

例如,这个结构在结果集中有六个提交。

于 2015-12-17T17:44:38.233 回答