Git:查看自上次合并冲突后其分支上的更改
我认为我的情况应该相当普遍,必须有一种更简单的方法来做我所做的事情。假设有两个分支,Git:查看自上次合并冲突后其分支上的更改,git,git-merge,Git,Git Merge,我认为我的情况应该相当普遍,必须有一种更简单的方法来做我所做的事情。假设有两个分支,current和next,用于两条开发线下一步在此阶段接收来自当前分支的所有更改。作为next分支的维护者,我正在同步更改(对于alpha版本是必要的),如下所示: $ git co origin/next -b next $ git merge origin/current 某些文件在下一个上更改了格式,自上次同步合并以来对这几个文件所做的每一次更改都会导致冲突。要解决此冲突,我需要查看自上次合并以来当前分支
current
和next
,用于两条开发线<代码>下一步在此阶段接收来自当前
分支的所有更改。作为next
分支的维护者,我正在同步更改(对于alpha版本是必要的),如下所示:
$ git co origin/next -b next
$ git merge origin/current
某些文件在下一个上更改了格式,自上次同步合并以来对这几个文件所做的每一次更改都会导致冲突。要解决此冲突,我需要查看自上次合并以来当前分支上的更改。通常很多文件都已更改,但只有1或2个像我提到的文件是冲突的
例子
假设current
分支上的文件baz.dat
包含方括号中的单词,如
[real]
[programmers]
[use]
[pascal]
在next
分支上,语法更改要求用冒号代替单词
:real:
:programmers:
:use:
:pascal:
当前分支上的更改在文件中添加了一行:
[real]
[programmers]
[don't]
[use]
[pascal]
每次合并冲突都会导致以下差异合并标记:
<<<<<<< ours
:real:
:programmers:
:use:
:pascal:
=======
[real]
[programmers]
[don't]
[use]
[pascal]
>>>>>>>> theirs
我在找什么
查看自上次合并以来,当前
(“其”)分支上发生的更改的方法,以便我可以手动将更改合并到下一个
(“我们”)分支中
而diff只会将冲突文件的更改显示为合并基础和合并点之间的增量(在理想情况下,我会进一步限制,例如--magic switch--theres
)
这样一个神奇的开关存在吗?看来我错过了一些明显的东西
git mergetool
将在您选择的diff编辑器(meld、vimdiff、kdiff3、winmerge…)中逐个打开冲突文件,作为3个版本之间的3路合并:
:当前分支中的版本(在您的情况下:local
的版本)next
:合并基提交中的版本base
:合并分支中的版本(在您的情况下:remote
的版本)origin/current
如果合并由于冲突而停止,
git
会在.git/merge\u HEAD
中存储对合并提交的引用。这意味着您可以在git命令中将字符串“MERGE\u HEAD”
用作有效的引用:
git log -1 MERGE_HEAD # view last commit on the merged branch
git merge-base MERGE_HEAD HEAD # no need for the name of the branch
然后,您可以构建一个更简单的别名:
theirs = 'git diff $(git merge-base MERGE_HEAD HEAD) MERGE_HEAD'
# usage :
git theirs # complete diff between 'base' and 'theirs'
git theirs -w -- this/file # you can add any option you would pass to 'git diff'
啊,有了这个例子,我们可以有所作为 这不是Git内置的,因为它通常是一个非常困难的问题。但是,如果我们对它进行某种限制,我们可以编写一个脚本、工具或过程来处理它(事实证明,这一部分是内置在Git中的!…嗯,有点)。让我们看看是否可以描述这些约束:
- 这是一个标准的三方合并,有一个标准的修改冲突,因此有一个基本版本(第1阶段)、一个本地/头/
——我们的版本(第2阶段)和一个远程/其他/
——他们的版本(第3阶段)
- 合并的一个“方面”涉及每一行,但以重复和可识别的模式,我们可以暂时退出。(让我们给这个更改起个名字:让我们简称它为“系统增量”或SD,+SD表示添加或保留此增量,-SD表示撤消/删除它。SD可能是一个不可逆的更改,即-SD可能无法完全撤消它;如果是这样,我们可能仍然能够自动处理它。)它可能还有一些额外的更改,也可能没有,对基地
- 合并的另一面只涉及几行,甚至没有几行,并且缺少重复和可识别的模式更改,我们可以添加到其中,可能是暂时的
- SD实际上是可逆的吗?也就是说,一旦我们发现了SD,base+SD-SD会复制原始的base吗
- 我们想要结果中的SD吗
- 我们能检测到SD的存在吗?(我们可能不需要这样做,但如果可以的话,我们会觉得很方便。)
git merge
在每个文件上运行两个过滤器(两个过滤器都可以,但我们可以使它们都“正常化”,或者保留一个未设置的过滤器,这是我们的特殊目的)。因为“规范化”给了我们想要的最终形式,它让Git完成了我们想要的合并
如果SD是不可逆的,我们需要更聪明,但只要我们希望结果中有+SD,我们仍然可以。我们可以编写自己的合并驱动程序,而不是使用。这也记录在同一手册中(进一步)。我不会在这里详细介绍,因为清理/污迹过滤方法更容易,并且可能适用于您的案例,但其本质是我们提取三个阶段,将+SD应用于需要它的任何阶段(通过测试或先验知识选择“需要它的文件”),然后
$ git status
. . . .
both modified: foo/bar/baz.dat <== copy/paste every conflict filename
$ git diff `git merge-base HEAD origin/current`..origin/current -- foo/bar/baz.dat
(next)$ git merge origin/current
. . .
CONFLICT (content): foo/bar/baz.dat
(next|MERGING)$ git diff --magic-switch
git log -1 MERGE_HEAD # view last commit on the merged branch
git merge-base MERGE_HEAD HEAD # no need for the name of the branch
theirs = 'git diff $(git merge-base MERGE_HEAD HEAD) MERGE_HEAD'
# usage :
git theirs # complete diff between 'base' and 'theirs'
git theirs -w -- this/file # you can add any option you would pass to 'git diff'