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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5074452/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 10:10:00  来源:igfitidea点击:

Git - how to force merge conflict and manual merge on selected file

gitmergebranchconflictmanual

提问by Stepan

We maintain web application which has common master branch and many parallel branches, one for each installation, each have few specific changes. Source code is managed in git and it is terrific tool when we need transfer features and bugfixes from master branch into parallel ones. But are few files that are sensitive and automatic merging usually give bad results. So merging would be much easier if they can be somehow marked and every merge would result in conflict requiring manual merge.

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

I searched for an answer :

我搜索了一个答案:

  1. I am using --no-commitand --no-ffmerge options, but it is not the same.
  2. Hereand heresomeone asks the same question but with no solution.
  3. Similar case seems to be how to prevent file being mergedusing .gitattributes containing: somefile.php merge=ours. I tried to find some merge option which would generate conflict or force manual merge but found none so far.
  4. .gitattributes containing: somefile.php -mergeis 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. But this is so far closest to solution.(...thanks Charles Bailey for clarification...)
  5. Someone suggest to write custom merge driver (1, 2), but how to do it is far from clear to me.
  1. 我正在使用--no-commit--no-ff合并选项,但它不一样。
  2. 这里这里有人问了同样的问题,但没有解决方案。
  3. 类似的情况似乎是如何防止文件被合并使用 .gitattributes 包含:somefile.php merge=ours。我试图找到一些会产生冲突或强制手动合并的合并选项,但到目前为止没有找到。
  4. .gitattributes 包含:somefile.php -merge永远不会自动合并,因此强制手动合并。这是 90% 的解决方案,但我寻求的是尝试自动合并并将其标记为冲突,无论它是否成功。但这到目前为止最接近解决方案。(...感谢 Charles Bailey 的澄清...)
  5. 有人建议编写自定义合并驱动程序 ( 1, 2),但我不清楚该怎么做。

edit:variant 4. description

编辑:变体 4. 描述

采纳答案by Dan Moulding

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.

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

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:

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

#!/bin/bash
git merge-file "" "" ""
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).

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

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):

接下来,您需要告诉 Git 您的自定义合并驱动程序的存在。您可以在 repo 的配置文件 ( .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-driverin the repo's top level directory (./). You will need to specify the path to the script accordingly.

在这个例子中,我已经放入merge-and-verify-driver了 repo 的顶级目录 ( ./)。您需要相应地指定脚本的路径。

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 .gitattributesfile:

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

*.sensitive merge=verify

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

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

回答by VonC

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.

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

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

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

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

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

回答by louisiuol

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.

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