合并新代码的冲突解决方案

时间:2012-01-26 19:00:38

标签: git version-control merge

假设我有一些订购的代码,但订购不是技术要求。

apple
kiwi
strawberry

然后我有两个我要合并的主题,其差异如下:

TOPIC BRANCH: orange
  kiwi
+ orange
  strawberry

TOPIC BRANCH: pear
  kiwi
+ pear
  strawberry

这两个补丁有没有办法自动解决?在我看来,这是一场合并冲突,因为他们争夺同一条新线。我提出的一个解决方案是重新排序其中一个更改,因为排序顺序只是一个软性要求(水果实际上是函数定义)。

 TOPIC BRANCH: pear'
   apple
 + pear
   kiwi

现在我们可以将orangepear'合并在一起形成:

 _ apple
 p pear
 _ kiwi
 o orange
 _ strawberry

还有其他方法可以解决这个问题,以便保留订购吗?我还想到pear必须在orange下游,以便orange始终获得优先权,并且不再存在合并冲突。但这是一个错误的依赖,因为orangepear是两个独立的功能分支。

可以在另一个之前将一个主线加入主干,但这不会解决集成分支。

编辑:我突然意识到可以保留的两个帅哥(我只想添加?)可能有两个合并策略称为“我先”和“你先”,这样可以解决模糊的排序两个分支之间的互动。

2 个答案:

答案 0 :(得分:7)

基本方法是定义自定义合并工具,然后使用git属性功能告诉git将这些自定义合并工具用于这些文件。

示例:

  1. 创建测试存储库:

    $ git init t
    $ cd t
    
  2. 定义名为mymerge的自定义合并工具:

    $ git config merge.mymerge.name "my custom merge tool"
    $ git config merge.mymerge.driver "cat '%A' '%B'|sort -u >'%A'.tmp && mv '%A'.tmp '%A'"
    

    上面的合并工具连接文件,对生成的行进行排序,然后删除重复的行。如果您不想更改顺序,请将上述命令替换为您想要的自定义脚本。有关详细信息,请参阅git help attributes

  3. 告诉git在合并存储库中名为mymerge的任何文件时要使用foo.txt

    $ echo "foo.txt merge=mymerge" >.gitattributes
    $ git add .gitattributes
    $ git commit -m "tell git to use the mymerge merge tool for foo.txt"
    
  4. 在三个分支上制作一些测试数据:

    $ printf 'apple\nkiwi\nstrawberry\n' >foo.txt
    $ git add foo.txt
    $ git commit -m "common ancestor version of foo.txt"
    $ git checkout -b orange
    $ printf 'apple\nkiwi\norange\nstrawberry\n' >foo.txt
    $ git commit -a -m "add orange"
    $ git checkout -b pear master
    $ printf 'apple\nkiwi\npear\nstrawberry\n' >foo.txt
    $ git commit -a -m "add pear"
    
  5. 合并分支(注意没有冲突!):

    $ git checkout master
    $ git merge orange
    $ git merge pear
    
  6. 利润!

    $ cat foo.txt
    apple
    kiwi
    orange
    pear
    strawberry
    

答案 1 :(得分:0)

如果需要订购的代码位于单独的文件中,您可以使用自定义合并工具,该工具接收两个输入文件,读取它们并输出其内容,并将其分类到结果文件中。然后你会告诉git为这个文件使用自定义合并工具。我不太了解git知道你是否可以根据文件类型或某种类型的正则表达式设置自定义合并工具,但这可能会给你你想要的想法。