解决合并冲突后,“git diff”到底显示了什么?以及如何只看到新的变化?
What exactly `git diff` shows after resolving merge conflict? and how to see only the new changes?
我将分支A合并到分支B:
git checkout A
git merge B
在文件 c.txt
中发生冲突。我通过编辑 c.txt
文件来解决它。现在,在使用 git add c.txt
批准更改之前,我想先看看它们。 IE。 to 看看c.txt
和分支A的区别,怎么做到的?
如果我简单地使用 git diff c.txt
,它显示的内容比我想要的要多得多。它似乎同时显示了分支 B 的更改和分支 A 的更改(与它们共同的原始提交相比)。 IE。结果不同于 git add c.txt; git diff --cached c.txt
。
当 c.txt
被标记为冲突时,git diff c.txt
究竟向我显示了什么?
TL;DR:您可能想要 git diff HEAD:c.txt c.txt
。
虽然文件被标记为“冲突”,但在 Git 的索引中有多个文件的“更高阶段”条目。事实上,这就是文件首先 是 冲突的含义:非冲突文件在 Git 的索引中处于“阶段零”,并且冲突文件具有阶段 1、2、and/or 3 个条目(通常全部三个)。
当文件处于这种冲突状态时,git diff
对文件执行组合差异。
在文件上使用 git add
会删除更高阶段的条目,留下一个零阶段(无冲突)文件,这就是它不再以这种方式显示的原因。
Now, before approving the changes with git add c.txt I would like to see them. I.e. to see the difference between c.txt and branch A. How to do it?
我通常不会理会这个(我只是阅读组合的差异,或者 git add
文件,然后可以看到我想要的东西,而不需要任何花哨的东西——记住,你仍然可以访问其他版本的文件;只有 merge base 版本很难找到),但你 可以 做到这一点。您必须选择要比较的 c.txt
的哪两个副本:
- 你说其中一个是某个提交中的副本 (
branch A
):那是 A:c.txt
。
- 另一个副本由您决定:
HEAD
提交中有一个,MERGE_HEAD
提交中有一个,Git 的索引中有三个,您的工作中有一个树。棘手的部分是为其中的每一个命名,但我们可以使用 the gitrevisions syntax 来完成其中的大部分。与 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
不会被误认为是分支名称,--
应该介于两者之间。
订单反转问题注意事项
如果您想将树内 c.txt
与分支 A c.txt
进行比较,两者:
git diff c.txt A:c.txt
和:
git diff A:c.txt c.txt
工作。这两个参数的顺序决定了哪个文件是“之前”或左侧文件,哪个文件是“之后”或右侧文件,这又决定了哪些行被删除,哪些行被添加。
在大多数情况下,如果您要求的差异与您想要的顺序“相反”,您可以简单地交换参数。但是对于:
git diff HEAD:main -- main
有一个问题:你不能交换这些。在这里,git diff -R
来拯救:-R
标志意味着 交换双方 。所以 git diff -R HEAD:main -- main
起到了作用:main
文件在左侧结束,HEAD:main
文件在右侧结束。
我将分支A合并到分支B:
git checkout A
git merge B
在文件 c.txt
中发生冲突。我通过编辑 c.txt
文件来解决它。现在,在使用 git add c.txt
批准更改之前,我想先看看它们。 IE。 to 看看c.txt
和分支A的区别,怎么做到的?
如果我简单地使用 git diff c.txt
,它显示的内容比我想要的要多得多。它似乎同时显示了分支 B 的更改和分支 A 的更改(与它们共同的原始提交相比)。 IE。结果不同于 git add c.txt; git diff --cached c.txt
。
当 c.txt
被标记为冲突时,git diff c.txt
究竟向我显示了什么?
TL;DR:您可能想要 git diff HEAD:c.txt c.txt
。
虽然文件被标记为“冲突”,但在 Git 的索引中有多个文件的“更高阶段”条目。事实上,这就是文件首先 是 冲突的含义:非冲突文件在 Git 的索引中处于“阶段零”,并且冲突文件具有阶段 1、2、and/or 3 个条目(通常全部三个)。
当文件处于这种冲突状态时,git diff
对文件执行组合差异。
在文件上使用 git add
会删除更高阶段的条目,留下一个零阶段(无冲突)文件,这就是它不再以这种方式显示的原因。
Now, before approving the changes with git add c.txt I would like to see them. I.e. to see the difference between c.txt and branch A. How to do it?
我通常不会理会这个(我只是阅读组合的差异,或者 git add
文件,然后可以看到我想要的东西,而不需要任何花哨的东西——记住,你仍然可以访问其他版本的文件;只有 merge base 版本很难找到),但你 可以 做到这一点。您必须选择要比较的 c.txt
的哪两个副本:
- 你说其中一个是某个提交中的副本 (
branch A
):那是A:c.txt
。 - 另一个副本由您决定:
HEAD
提交中有一个,MERGE_HEAD
提交中有一个,Git 的索引中有三个,您的工作中有一个树。棘手的部分是为其中的每一个命名,但我们可以使用 the gitrevisions syntax 来完成其中的大部分。与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
不会被误认为是分支名称,--
应该介于两者之间。
订单反转问题注意事项
如果您想将树内 c.txt
与分支 A c.txt
进行比较,两者:
git diff c.txt A:c.txt
和:
git diff A:c.txt c.txt
工作。这两个参数的顺序决定了哪个文件是“之前”或左侧文件,哪个文件是“之后”或右侧文件,这又决定了哪些行被删除,哪些行被添加。
在大多数情况下,如果您要求的差异与您想要的顺序“相反”,您可以简单地交换参数。但是对于:
git diff HEAD:main -- main
有一个问题:你不能交换这些。在这里,git diff -R
来拯救:-R
标志意味着 交换双方 。所以 git diff -R HEAD:main -- main
起到了作用:main
文件在左侧结束,HEAD:main
文件在右侧结束。