为什么 GitHub 在比较两个相同的分支时会显示变化?

dhy*_*sba 7 git github

我已经创建了测试存储库:https : //github.com/Labutin/CompareBranches 让我们尝试克隆和比较两个分支 branch_01 和 branch_02

$ git clone https://github.com/Labutin/CompareBranches.git
Cloning into 'CompareBranches'...
remote: Counting objects: 7, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 7 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (7/7), done.

$ git diff remotes/origin/branch_01..remotes/origin/branch_02 --exit-code
$ echo $?
0
Run Code Online (Sandbox Code Playgroud)

所以,我们有两个相同的分支。

但是,如果我尝试使用 Web UI 来比较两个分支https://github.com/Labutin/CompareBranches/compare/branch_01...branch_02,它会显示 1 个文件已更改。为什么?Web UI 有什么问题?也许我必须修改网址?

tor*_*rek 5

这个问题实际上是关于 GitHub 的——但我们可以用它来构造一个关于 Git 的问题。

在我克隆您的存储库后:

$ git clone https://github.com/Labutin/CompareBranches.git
Cloning into 'CompareBranches'...
remote: Counting objects: 7, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 7 (delta 0), reused 0 (delta 0), pack-reused 0
Run Code Online (Sandbox Code Playgroud)

我可以查看其中的所有提交:

$ cd CompareBranches
$ git log --all --decorate --oneline --graph
* 5707453 (origin/branch_02) Commit to branch_02
| * c0e3722 (origin/branch_01) commit to branch_01
|/  
* 0e9a4e3 (HEAD -> master, origin/master, origin/HEAD) Initial commit
Run Code Online (Sandbox Code Playgroud)

因此,有三个提交,其实际的(但略)名称0e9a4e3c0e37225707453。该远程跟踪名称 origin/master指的是第一次提交,另两个远程跟踪名称origin/branch_01origin/branch_02参考其他两次提交。

如果我们让 Git 比较 commitsc0e37225707453,我们看不出有什么区别:

$ git diff c0e3722 5707453
Run Code Online (Sandbox Code Playgroud)

但是如果我们让 Git 比较,比如 commit0e9a4e3到 commit 5707453,我们会发现两个 commit不同的:

$ git diff 0e9a4e3 5707453
diff --git a/README.md b/README.md
index f00f3be..b183451 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,2 @@
-# CompareBranches
\ No newline at end of file
+# CompareBranches
+commit1
Run Code Online (Sandbox Code Playgroud)

由于提交c0e37225707453具有相同的内容,因此与0e9a4e3任何一个进行比较都会显示相同的更改。

git diff命令具有特殊语法

当我们想要比较两个提交时,我们可以运行:

git diff <thing-1> <thing-2>
Run Code Online (Sandbox Code Playgroud)

Git 会比较 thing-1 和 thing-2。尖括号内的部分可以是任何标识提交的内容:例如0e9a4e3,原始哈希 ID或分支名称或远程跟踪名称。

如果我们运行:

git diff <thing-1>..<thing-2>
Run Code Online (Sandbox Code Playgroud)

Git 做的事情完全一样:它比较这两件事。

但是,如果我们使用三个点而不是两个点:

git diff <thing-1>...<thing-2>
Run Code Online (Sandbox Code Playgroud)

Git 做了一些特别的事情。Git 没有比较我们命名的两个提交,而是查找第三个提交。特别是,Git 查找合并基础提交,命名提交均从该提交下降。我们在git log --graph上面的输出中看到了这一点:两个提示提交都来自 commit 0e9a4e3。所以这是合并基础,因此,三个点而不是两个点,这是 Git 在比较左侧使用的提交。

右边就是它<thing-2>自己。

事实证明,GitHub 在这里做了同样的事情,这就是为什么 GitHub 的链接中有三个点:GitHubgit diff故意模仿 , 的语法。


Sch*_*ern 2

请注意 Github URL 中的三点。Github 正在做git diff remotes/origin/branch_01...remotes/origin/branch_02. r1..r2与 略有不同r1...r2

r1..r2要求所有可从 访问的提交,r2除了 可以访问的提交之外r1

r1...r2要求“两个引用中的任何一个都可以访问但两者都不能访问的所有提交。

让我们在您的存储库中看看这些。

A - B [branch_02]
 \
  C [branch_01]
Run Code Online (Sandbox Code Playgroud)

git log branch_01..branch_02给我们Bbranch_02可以到达 A 和 B,但branch_01也可以到达 A,所以这给了我们B

git log branch_01..branch_02给我们BCbranch_01可以达到ACbranch_02可以达到AB。两个分支都可以到达A,因此被排除。我们只剩下BC

有关更多信息,请参阅Pro Git 中的修订选择、双点和三点