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

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

我寻找答案:

  1. 我使用 没有承诺不要合并选项,但它是不一样的。
  2. 在这里和 给你有人问同样的问题,但没有解决办法。
  3. 类似的情况似乎是 如何防止文件被合并使用。Gittribute 包含: 合并 = 我们的。我试图找到一些合并选项,将产生冲突或强制手动合并,但没有发现到目前为止。
  4. .gitattributes containing: Some file. php-merge is never merged automatically and therefore forcing manual merge. It is 90% solution, but what I seek is to try automatic merge and mark it as conflict regardless it is successful or not. 但这是目前最接近解决方案的方法。 (... 感谢 Charles Bailey 的澄清...)
  5. 有人建议写自定义合并驱动程序(12) ,但如何做到这一点远远不清楚我。

编辑: 变体4. 描述

37853 次浏览

Option 5, a custom merge driver, is probably the way to get closest to what you want. It is surprisingly easy to do. Below is an example of one that I think should get you pretty close to the behavior you desire.

First, create a merge driver script called merge-and-verify-driver. Make it executable and put it in a suitable location (you may want to consider checking this script into the repo, even, since the repo's config file is going to depend on it). Git is going to execute this shell script to perform the merge of the sensitive files:

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

This just does the default merge behavior that Git itself normally does. The key difference is that the script always returns non-zero (to indicate that there was a conflict, even if the merge was actually resolved without conflicts).

Next, you need to tell Git about the existence of your custom merge driver. You do this in the repo's config file (.git/config):

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

In this example, I've put merge-and-verify-driver in the repo's top level directory (./). You will need to specify the path to the script accordingly.

Now, you just need to give the sensitive files the proper attributes so that the custom merge driver is used when merging those files. Add this to your .gitattributes file:

*.sensitive merge=verify

Here, I've told Git that any file with a name matching the pattern *.sensitive should use the custom merge driver. Obviously, you need to use pattern that is appropriate for your file(s).

Note: this article "Writing a git merge driver for PO files" illustrates the kind of manipulation you can do when manually merging a file: you can pre-processed it in order for your manual merge to have certain data ready.

git merge-file can be used, for instance, to DECRYPT (and re-encrypt) files before merging (!)

In your case, exiting your merge driver with a non-0 status ensure that the merge will be a manual one.

These two commands seems to have the same effect as using the custom merge driver:

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)

The first command stops the merge before the creation of the merge commit, and the second marks all the files modified in the two branches as a conflict to solve even if there was no conflict originally.