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

Posted

技术标签:

【中文标题】Git - 如何在所选文件上强制合并冲突和手动合并【英文标题】:Git - how to force merge conflict and manual merge on selected file 【发布时间】:2011-07-01 18:15:13 【问题描述】:

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

我搜索了一个答案:

    我正在使用 --no-commit--no-ff 合并选项,但不一样。 Here 和 here 有人问同样的问题,但没有解决方案。 类似的情况似乎是 how to prevent file being merged 使用 .gitattributes 包含: somefile.php merge=ours 。我试图找到一些会产生冲突或强制手动合并的合并选项,但到目前为止没有找到。 .gitattributes 包含: somefile.php -merge 永远不会自动合并,因此会强制手动合并。这是 90% 的解决方案,但我寻求的是尝试自动合并并将其标记为冲突,无论它是否成功。 但这是迄今为止最接近解决方案的方法。 (...感谢 Charles Bailey 的澄清...) 有人建议编写自定义合并驱动程序(1,2),但我还不清楚如何去做。

编辑:变体 4. 描述

【问题讨论】:

这不是您要寻找的确切答案,但出于同样的原因,我先使用git fetch,然后使用git difftool <file> FETCH_HEAD,因此我可以手动将远程分支中的更改应用到当地人。 MHC:这是一个很好的技巧(特别是如果为每个并行分支保存在脚本中 + 并结合防止文件自动合并)。主要缺点是,在团队工作流程中,有人可能会忘记这一步,而只是进行正常的合并。 设置 -merge 不会阻止您合并文件,它只会强制您手动进行,例如使用合并工具。这不是你需要的吗? 这是我想要的 90%。我希望自动完成合并,但是对于这个敏感文件,即使没有合并也被认为是冲突的,因此每次都强制进行手动检查。 @Stepan 我处于类似情况,所以我想澄清一些事情。你在说-merge.gitatttributes git merge 什么都不做,所有的工作都必须用合并工具来完成?所以没有 >>> 供合并工具使用,对吧? Dan 的解决方案确实提供了这一点? 【参考方案1】:

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

首先,创建一个名为 merge-and-verify-driver 的合并驱动程序脚本。使其可执行并将其放在合适的位置(您可能需要考虑将此脚本签入 repo,甚至,因为 repo 的配置文件将依赖于它)。 Git 将执行这个 shell 脚本来合并敏感文件:

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

这只是 Git 本身通常所做的默认合并行为。关键区别在于脚本总是返回非零值(表示存在冲突,即使合并实际上是在没有冲突的情况下解决的)。

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

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

在此示例中,我将 merge-and-verify-driver 放在了 repo 的***目录 (./) 中。您需要相应地指定脚本的路径。

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

*.sensitive merge=verify

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

【讨论】:

非常感谢这份详细的指南! 似乎在“明显”的解决方案中没有调用合并驱动程序。例如,如果文件仅在一个分支上更改并且您进行了合并,则“敏感”文件将被覆盖并且不会调用合并驱动程序。有没有办法解决这个问题? 这真的会像@VitalyB 建议的那样表现吗?谢谢! 这行得通,但是有没有办法让它成为机器上所有存储库的全局选项?另外,有什么方法可以通过命令行调用它?我希望有一种方法可以像在命令行上更改合并策略一样简单。 添加到@VitalyB 评论。如果 both 分支对文件进行了相同的更改,则合并也不会出现。比如两个分支都把版本都加了1,你想在合并的时候加2……很实际的问题,还没解决。:(【参考方案2】:

这两个命令似乎和使用自定义合并驱动的效果一样:

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 导致错误的合并(本质上是和我们的合并)。 @Nerogris 实际上它不适用于快进合并。您始终可以添加 --no-ff 选项,但第二个命令不会产生冲突,因为合并的两个分支之一中的共同祖先没有任何更改。 我在全局配置中将 ff 设置为 false。当我说这是一次 FF 合并时,我的意思是,如果我没有告诉 Git 不要这样做,它就会这样做。 我不相信第二行实际上“创建”了以前不存在的冲突。或许您可以提供一组可以正常工作的示例命令。【参考方案3】:

注意:本文“Writing a git merge driver for PO files”说明了手动合并文件时可以执行的操作类型:您可以对其进行预处理,以便手动合并准备好某些数据。

git merge-file 可以用于例如DECRYPT (and re-encrypt) files before merging (!)

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

【讨论】:

您能否详细说明“PO 文件的合并驱动程序”链接,因为这似乎导致我无法访问?我希望它能回答问题***.com/questions/16214067/… @MikkoRantalainen 工作受阻,所以今晚我会在家尝试。 “PO 文件的合并驱动程序”对我也不起作用 :( @sampablokuper 我同意:这篇文章被“非授权”读者屏蔽。我不知道为什么。 @sampablokuper 我现在无法访问此博客。我会继续寻找它的内容。

以上是关于Git - 如何在所选文件上强制合并冲突和手动合并的主要内容,如果未能解决你的问题,请参考以下文章

如何解决Git中的合并冲突

idea解决代码冲突

如何在Git中手动合并所有文件?

Git如何合并分支代码

git 如何去解决冲突

git 分支合并 强制合并