Git-如何在选定文件上强制合并冲突和手动合并


82

我们维护的Web应用程序具有公共主分支和许多并行分支,每个安装一个,每个分支都有一些特定的更改。源代码在git中进行管理,当我们需要将功能和错误修正从master分支转移到并行分支中时,它是一个了不起的工具。但是很少有敏感文件,自动合并通常会产生不好的结果。因此,如果可以以某种方式标记它们,则合并会容易得多,并且每次合并都会导致需要手动合并的冲突。

我搜索了一个答案:

  1. 我正在使用--no-commit--no-ff合并选项,但这并不相同。
  2. 在这里这里,有人问同样的问题,但没有解决方案。
  3. 类似的情况似乎是如何防止使用包含以下内容的.gitattributes合并文件somefile.php merge = ours。我试图找到一些合并选项,该选项会产生冲突或强制进行手动合并,但到目前为止没有找到。
  4. .gitattributes包含:somefile.php -merge永远不会自动合并,因此会强制进行手动合并。这是90%的解决方案,但我寻求的是尝试自动合并并将其标记为冲突,无论是否成功。但这到目前为止是最接近解决方案的。 (...感谢查尔斯·贝利的澄清...)
  5. 有人建议编写自定义合并驱动程序(12),但如何做到这一点还远未清晰。

编辑:变体4。描述


6
这不是您要查找的确切答案,但是出于相同的原因,我git fetch首先这样做,然后使用git difftool <file> FETCH_HEAD,因此我可以将远程分支中的更改手动应用于本地。
MHC

MHC:这是一个很好的技巧(特别是如果将其保存在脚本中的每个并行分支上,并结合了防止文件自动合并的功能)。主要缺点是在团队工作流程中,有人会忘记此步骤,而只是进行正常合并。
Stepan

2
设置-merge不会阻止您合并文件,而只是迫使您手动进行操作,例如使用mergetool。这不是您所需要的吗?
CB Bailey

这是我想要的90%。我希望合并是自动完成的,但是对于此敏感文件,即使没有合并也被认为是冲突,因此每次都强制执行手动检查。
Stepan

@Stepan我处于类似情况,所以我想澄清一些事情。您是说什么用-mergein.gitatttributes git merge做任何事情,并且所有工作都必须通过合并工具才能完成?因此,没有<<<<< ===== >>>>供合并工具使用,对吧?Dan的解决方案确实提供了这一点吗?
Nero gris

Answers:


59

选项5(自定义合并驱动程序)可能是最接近所需内容的方法。这很容易做到。下面是一个示例,我认为应该可以使您非常接近自己想要的行为。

首先,创建一个名为的合并驱动程序脚本merge-and-verify-driver。将其设置为可执行文件并将其放置在适当的位置(甚至可能要考虑将此脚本检入到存储库中,因为该存储库的配置文件将依赖于此脚本)。Git将执行以下shell脚本来执行敏感文件的合并:

#!/bin/bash
git merge-file "${1}" "${2}" "${3}"
exit 1

这只是Git本身通常执行的默认合并行为。关键区别在于该脚本始终返回非零值(以表明存在冲突,即使合并实际上已解决也没有冲突)。

接下来,您需要告诉Git您的自定义合并驱动程序的存在。您可以在存储库的配置文件(.git/config)中执行此操作:

[merge "verify"]
        name = merge and verify driver
        driver = ./merge-and-verify-driver %A %O %B

在此示例中,我将其放置merge-and-verify-driver在存储库的顶级目录(./)中。您需要相应地指定脚本的路径。

现在,您只需要为敏感文件提供适当的属性,以便在合并这些文件时使用自定义合并驱动程序。将此添加到您的.gitattributes文件:

*.sensitive merge=verify

在这里,我告诉Git,任何名称与模式匹配的文件*.sensitive都应使用自定义合并驱动程序。显然,您需要使用适合您文件的模式。


非常感谢此详细指南!
Stepan

13
似乎在“显而易见的”解决方案中未调用合并驱动程序。例如,如果仅在一个分支上更改了文件并且您进行了合并,则“敏感”文件将被覆盖,并且合并驱动程序将不会被调用。有办法解决吗?
VitalyB

这真的会像@VitalyB建议的那样表现吗?谢谢!
filippo 2013年

1
这行得通,但是有没有办法使它成为计算机上所有存储库中的全局选项?另外,可以通过命令行调用它吗?我希望有一种方法可以像在命令行上更改合并策略那样简单。
2014年

4
添加到@VitalyB评论。如果两个分支对文件进行了相同的更改,则合并也不会出现。例如,两个分支由1增加的版本,和你想通过2,而试图合并......很实际的问题,未解决又增加:(。
VasiliNovikov

1

这两个命令似乎与使用自定义合并驱动程序具有相同的效果:

git merge --no-commit your_target_branch
git checkout --conflict merge .   (do not forget the . and run it in the top dir of the repository)

第一个命令在创建合并提交之前停止合并,第二个命令将在两个分支中修改的所有文件标记为要解决的冲突,即使最初没有冲突也可以解决。


我喜欢“一次性”解决方案的想法(我遇到了这种情况),但这对我不起作用。Git做一个FF导致合并失败(本质上是我们的合并)。
Nero gris

@Nerogris实际上,它不适用于快速合并。您始终可以添加--no-ff选项,但是第二个命令不会产生冲突,因为在合并的两个分支之一中,公共祖先没有任何更改。
louisiuol

我在全局配置中将ff设置为false。当我说这是FF合并时,我的意思是,如果我不告诉Git不要这样做,那一定会。
Nero gris

0

注意:本文“为PO文件编写git合并驱动程序”说明了手动合并文件时可以执行的操作:您可以对其进行预处理,以使手动合并准备好某些数据。

git merge-file例如,可以在合并(!)之前用于解密(并重新加密)文件

在您的情况下,以非0的状态退出合并驱动程序可确保合并将是手动的。


2
您能否详细说明“ PO文件的合并驱动程序”链接,因为这似乎导致我被拒绝访问?我希望它能为问题stackoverflow.com/questions/16214067/…
Mikko Rantalainen 2013年

@MikkoRantalainen在工作中受阻,所以今天晚上我将在家中尝试。
VonC

1
“ PO文件的合并驱动程序”对我也不起作用:(
sampablokuper 2013年

1
我同意@sampablokuper:“非授权”读者被禁止阅读。我不知道为什么。
VonC

1
@sampablokuper我现在无权访问此博客。我将继续寻找其内容。
VonC
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.