如何使用特定策略从命令行解决git合并冲突,仅针对一个文件?

23

假设我执行了一个 git 合并操作,发现某些文件(如 package.jsonpom.xml )存在冲突。

我想要:

  1. 在命令行中自动解决特定文件的合并冲突,
  2. 对于其他所有冲突,让我手动解决,
  3. 确保不会丢失任何分支的重要更改。

由于第二点,我不能使用 git merge -Xours,因为这将解决所有的冲突。我只想要解决一个特定文件中的冲突。

由于第三点,我不能使用 git checkout --ours package.json,因为这可能会丢失输入分支的一些更改。

例如,自动合并脚本会以预定义的方式解决一些简单的已知冲突,并在其他文件中出现其他冲突时失败。

我通常遇到的典型情况是:两个包含 package.json 中的 version 字段的分支发生了分歧,如下所示:

$ git diff
diff --cc package.json
index 75c469b,f709434..0000000
--- a/package.json
+++ b/package.json
@@@ -1,6 -1,6 +1,12 @@@
  {
    "name": "test",
++<<<<<<< HEAD
 +  "version": "2.0.1",
++||||||| merged common ancestors
++  "version": "1.0.0",
++=======
+   "version": "1.0.2",
++>>>>>>> master

是否可以使用给定的策略仅解决一个文件的冲突?就像这样:

git-resolve-conflict --ours package.json
1个回答

22

虽然其 API 比较低级,但可以使用 git-merge-file 来实现此操作。

为了拥有易于使用的命令,您可以使用以下 bash 脚本(导入到 .bashrc 中,或者也可以使用 npm install -g git-resolve-conflict 进行安装):

git-resolve-conflict() {
  STRATEGY="$1"
  FILE_PATH="$2"

  if [ -z "$FILE_PATH" ] || [ -z "$STRATEGY" ]; then
    echo "Usage:   git-resolve-conflict <strategy> <file>"
    echo ""
    echo "Example: git-resolve-conflict --ours package.json"
    echo "Example: git-resolve-conflict --union package.json"
    echo "Example: git-resolve-conflict --theirs package.json"
    return
  fi

  git show :1:"$FILE_PATH" > ./tmp.common
  git show :2:"$FILE_PATH" > ./tmp.ours
  git show :3:"$FILE_PATH" > ./tmp.theirs

  git merge-file "$STRATEGY" -p ./tmp.ours ./tmp.common ./tmp.theirs > "$FILE_PATH"
  git add "$FILE_PATH"

  rm ./tmp.common
  rm ./tmp.ours
  rm ./tmp.theirs
}

(注:我一直在GitHub存储库中更新脚本,请查看该存储库以获取最新的改进:https://github.com/jakub-g/git-resolve-conflict/blob/base/lib/git-resolve-conflict.sh)

对于问题描述中的特定示例,使用方法如下:

git-resolve-conflict --ours package.json

详细步骤请参见:

https://github.com/jakub-g/git-resolve-conflict

额外收获:

如果您在子文件夹中有多个 package.json 文件,并且想要解决合并时处于冲突状态的所有文件

for ITEM in $(git diff --name-only --diff-filter=U | grep package.json$); do git-resolve-conflict --ours $ITEM; done

不错的脚本。但是,如果从存储库的根目录以外的目录运行,则会失败。 git -x 仅匹配精确匹配,但文件名缺少前导路径。 - Matt
1
@Matt,你可以在第一行添加cd "./"$(git rev-parse --show-cdup)以移动到库的根目录,然后在最后加上cd -返回到之前的文件夹。(如果你从库外运行脚本,则此方法不适用,但这可能是一个非常特殊的边缘情况。) - jakub.g

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接