如何解决git merge冲突,从命令行,使用给定的策略,只针对一个文件?

时间:2016-08-24 14:45:46

标签: git merge git-merge

我们说我做了git合并并在某个文件中出现了冲突,例如package.jsonpom.xml,以及其他一些文件。

我想

  1. 从命令行自动解决某些文件的合并冲突,而
  2. 让我自己手动解决所有其他冲突(如果有)和
  3. 确保我不会从任何分支机构中丢失有价值的更改。
  4. 由于2),我无法使用git merge -Xours ,因为这会解决所有冲突。我想只解决一个特定文件中的冲突。

    由于3),我无法使用git checkout --ours package.json ,因为这可能会从输入分支中丢失一些更改。

    用例例如:自动合并脚本,它将以预定义的方式解决琐碎的众所周知的冲突,如果其他文件中存在其他冲突,则会失败。

    我经常遇到的典型案例是version中有package.json字段的两个分支如下所示:

    $ 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 个答案:

答案 0 :(得分:13)

这可以使用git-merge-file来实现,尽管它的API相当低级。

为了拥有一个易于使用的命令,您可以使用以下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 all of them which are in conflicted state

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