我在我的仓库是下成长的一些文件:大部分的变化涉及在该文件的底部添加新行。 这主要是语言和其他财产的文件。
作为一个恼人的副作用,只要两个人在同一时间,我得到合并冲突进行增补,分辨率始终手动涉及的复制粘贴,这样从两个版本线得到包括在内。
是否有一个尖,招或方法,这将减轻一些这个过程的痛苦吗?
例如,一个简单的解决办法是告诉开发商随意地在文件中增加新的生产线。 这可能会工作,但它涉及到有意识的努力,并且看起来怪怪的历史。
我在我的仓库是下成长的一些文件:大部分的变化涉及在该文件的底部添加新行。 这主要是语言和其他财产的文件。
作为一个恼人的副作用,只要两个人在同一时间,我得到合并冲突进行增补,分辨率始终手动涉及的复制粘贴,这样从两个版本线得到包括在内。
是否有一个尖,招或方法,这将减轻一些这个过程的痛苦吗?
例如,一个简单的解决办法是告诉开发商随意地在文件中增加新的生产线。 这可能会工作,但它涉及到有意识的努力,并且看起来怪怪的历史。
您可以使用gitattributes机制来定义一个定制的合并驱动程序 (如这一个例子 ,以自动复制相关章节)。
[merge "aggregate"]
name = agregate both new sections
driver = aggregate.sh %O %A %B
这将是一个3路合并,这意味着你可以很容易地DIFF %A
和%B
针对%O
,以便隔离(共同祖先)说,新的章节,并聚集在他们的结果合并的文件。
这骨料合并驱动程序仅需要做的:
comm -13 $1 $3 >> $2
(在通讯工具是一部分牌九- GNU在Windows -分布,如果你是在Windows上)
这里是一个小的演示:
首先,让我们建立一个Git回购,有两个分支(“修改的文件master
‘和’ abranch
”):
C:\prog\git\tests>mkdir agg
C:\prog\git\tests>cd agg
C:\prog\git\tests\agg>git init r1
Initialized empty Git repository in C:/prog/git/tests/agg/r1/.git/
C:\prog\git\tests\agg>cd r1
# Who am I?
C:\prog\git\tests\agg\r1>git config user.name VonC
C:\prog\git\tests\agg\r1>git config user.email vonc@xxx
# one file, first commit:
C:\prog\git\tests\agg\r1>echo test > test.txt
C:\prog\git\tests\agg\r1>git add .
C:\prog\git\tests\agg\r1>git commit -m "first commit"
[master c34668d] first commit
1 file changed, 1 insertion(+)
create mode 100644 test.txt
# Let's add one more common line:
C:\prog\git\tests\agg\r1>echo base >> test.txt
C:\prog\git\tests\agg\r1>more test.txt
test
base
C:\prog\git\tests\agg\r1>git add .
C:\prog\git\tests\agg\r1>git commit -m "base"
[master d1cde8d] base
1 file changed, 1 insertion(+)
现在我们创建一个新的分支,并进行并发修改该文件的两个版本,在它就像结束itsadok OP指定的问题。
C:\prog\git\tests\agg\r1>git checkout -b abranch
Switched to a new branch 'abranch'
C:\prog\git\tests\agg\r1>echo "modif from abranch" >> test.txt
C:\prog\git\tests\agg\r1>git add .
C:\prog\git\tests\agg\r1>git commit -m "abranch contrib"
[abranch a4d2632] abranch contrib
1 file changed, 1 insertion(+)
C:\prog\git\tests\agg\r1>type test.txt
test
base
"modif from abranch"
# back to master
C:\prog\git\tests\agg\r1>git checkout master
Switched to branch 'master'
C:\prog\git\tests\agg\r1>echo "contrib from master" >> test.txt
C:\prog\git\tests\agg\r1>git add .
C:\prog\git\tests\agg\r1>git commit -m "contrib from master"
[master 45bec4d] contrib from master
1 file changed, 1 insertion(+)
C:\prog\git\tests\agg\r1>type test.txt
test
base
"contrib from master"
我们拥有了两个分支(注: git lg
是我的别名 )
C:\prog\git\tests\agg\r1>git lg
* 45bec4d - (HEAD, master) contrib from master (86 minutes ago) VonC
| * a4d2632 - (abranch) abranch contrib (86 minutes ago) VonC
|/
* d1cde8d - base (87 minutes ago) VonC
* c34668d - first commit (89 minutes ago) VonC
现在让我们尝试合并:
C:\prog\git\tests\agg\r1>git merge abranch
Auto-merging test.txt
CONFLICT (content): Merge conflict in test.txt
Automatic merge failed; fix conflicts and then commit the result.
C:\prog\git\tests\agg\r1>more test.txt
test
base
<<<<<<< HEAD
"contrib from master"
=======
"modif from abranch"
>>>>>>> abranch
...失败的广告;)一个git merge --abort
将重置的情况。
让我们落实我们的合并驱动程序 :
C:\prog\git\tests\agg\r1>git config merge.aggregate.name "aggregate both new sections"
C:\prog\git\tests\agg\r1>git config merge.aggregate.driver "aggregate.sh %O %A %B"
C:\prog\git\tests\agg\r1>echo test.txt merge=aggregate > .gitattributes
在这一点上,合并仍然失败:
C:\prog\git\tests\agg\r1>git merge abranch
aggregate.sh .merge_file_a09308 .merge_file_b09308 .merge_file_c09308: aggregate.sh: command not found
fatal: Failed to execute internal merge
正常:我们需要编写脚本,并将其添加到PATH
:
vim aggregate.sh:
#!/bin/bash
# echo O: $1
# echo A: $2
# echo B: $3
# After http://serverfault.com/q/68684/783
# How can I get diff to show only added and deleted lines?
# On Windows, install GoW (https://github.com/bmatzelle/gow/wiki/)
ob=$(comm -13 $1 $3)
# echo "ob: ${ob}"
echo ${ob} >> $2
----
C:\prog\git\tests\agg\r1>set PATH=%PATH%;C:\prog\git\tests\agg\r1
而现在 , aggregate
合并司机可以操作 :
C:\prog\git\tests\agg\r1>git merge --no-commit abranch
Auto-merging test.txt
Automatic merge went well; stopped before committing as requested
C:\prog\git\tests\agg\r1>type test.txt
test
base
"contrib from master"
"modif from abranch"
在这里你去:在年底test.txt
从文件abranch
已被添加到该文件master
。
另一种解决方案是使用--union
管道命令的选项git-merge-file
。
[merge "aggregate"]
name = aggregate both new sections
driver = git merge-file --union -L %P %A %O %B
这比使用更可靠的comm
: comm
可以生成当输入线根据不排序错误的输出LC_COLLATE
。
如果您不想再补充一点,已被删除线,你必须使用一个稍微复杂的咒语comm
:
tmp=$(mktemp)
(comm -12 %A %B ; comm -13 %O %A ; comm -13 %O %B ) >| $tmp
mv $tmp %A
首先,你选择所有常见的本地和远程修改行; 这可以确保所有被删除的行保持删除。 然后添加远程修改,那么这些地方的修订补充增加了线。
这可能是策略可以安装在.gitconfig
使用一个命令:
git config merge.aggregate.driver 'tmp=$(mktemp) ; (comm -12 %A %B ; comm -13 %O %A ; comm -13 %O %B ) >| $tmp ; mv $tmp %A'