我将分支A合并到分支B:
git checkout A
git merge B
在文件c.txt
中发生冲突。我通过编辑c.txt
文件来解决它。现在,在批准git add c.txt
的更改之前,我想看看它们。即查看c.txt
和分支a之间的差异。怎么做?
如果我简单地使用git diff c.txt
,它显示了比我想要的更多的变化。它似乎同时显示了来自分支B和分支A的更改(与它们共同的原始提交相比)。即结果与git add c.txt; git diff --cached c.txt
不同。当c.txt
被标记为冲突时,git diff c.txt
究竟显示了什么?
TL;DR:你可能想要git diff HEAD:c.txt c.txt
.
虽然文件被标记为&;conflicted&;,但有多个&;higher stage&;文件在Git索引中的条目。事实上,这就是文件首先是冲突的含义:非冲突的文件处于"阶段0"。在Git的索引中,一个冲突的文件有阶段1、阶段2和/或阶段3的条目(通常三个都有)。
当文件处于冲突状态时,git diff
对文件执行组合diff。
在文件上使用git add
会擦除更高阶段的条目,只留下一个阶段零(无冲突)的文件,这就是为什么它不再以这种方式显示。
现在,在使用git add .txt批准更改之前,我希望看到它们。例如,到查看c.txt和分支a之间的差异怎么做呢?
我通常不打扰这个(我只是读取合并的diff,或git add
文件,然后可以看到我想要的没有任何花哨的东西-记住,你仍然可以访问文件的其他版本;只有合并基础版本(很难找到),但是您可以这样做。你必须挑选出你想要比较的两个c.txt
副本:
- 其中之一是,你说,在某些提交(
branch A
)中的副本:这是A:c.txt
。 - 另一个副本由您决定:在
HEAD
提交中有一个,在MERGE_HEAD
提交中有一个,在Git的索引中有三个,在工作树中有一个。棘手的部分是命名每一个,但我们可以使用gitrevisions语法。与A:c.txt
一样,HEAD:c.txt
和MERGE_HEAD:c.txt
用于选择这些版本;:1:c.txt
选择合并基础版本;:2:c.txt
选择--ours
版本(从HEAD
复制,因此应该匹配HEAD:c.txt
),:3:c.txt
选择--theirs
版本(从MERGE_HEAD
复制)。
因此,如果你想,例如,看看HEAD:c.txt
和MERGE_HEAD:c.txt
有什么不同,你可以只运行git diff HEAD:c.txt MERGE_HEAD:c.txt
(或git diff :2:c.txt :3:c.txt
)。
这对你可能最关心的人没有帮助。工作树中的c.txt
副本如何编辑以生成合并的文件?幸运的是,我们可以将其命名为文件名c.txt
。
在某些情况下,该文件名可能类似于分支名称,以欺骗Git。如果是这种情况,请确保您记住--
总是告诉Git:在此之后,所有内容都是文件名,或者至少不是选项,也可能不是分支名称。因此,如果文件不是命名为c.txt
而是命名为main
,并且:
git diff HEAD:main main
做错了,使用:
git diff HEAD:main -- main
(注意HEAD:main
不会被误认为是分支名称,--
应该放在两者之间)。
关于序反转问题的说明
如果你想比较in-treec.txt
和branch-Ac.txt
,两者:
git diff c.txt A:c.txt
:
git diff A:c.txt c.txt
工作。这两个参数的顺序决定了哪个文件是"before"或者左边那个,哪个是后面那个;或者右边的一个,它反过来决定哪些行被删除,哪些行被添加。
在大多数情况下,如果您要求的差异是"向后"&;根据表示的顺序,您可以简单地交换参数。但对于:
git diff HEAD:main -- main
有一个问题:你不能交换这些。这里,git diff -R
来拯救:-R
标志意味着交换边。所以git diff -R HEAD:main -- main
做到了:main
文件在左边结束,HEAD:main
文件在右边结束。