我的存储库中有一些底部增长的文件:大多数更改都涉及到在文件的底部添加新行。这主要是语言和其他属性文件。
作为一个恼人的副作用,每当两个人同时进行添加时,我就会得到合并冲突,并且解决方案总是涉及手动复制-粘贴,以便包含两个版本的行。
有什么技巧、技巧或方法可以减轻这个过程中的一些痛苦吗?
例如,一种简单的解决方案是告诉开发人员在文件中间的任意位置添加新行。这可能会起作用,但它需要有意识的努力,以及一段看起来怪异的历史。
发布于 2012-08-07 15:49:20
您可以使用gitattributes机制来定义自定义合并驱动程序(如this one for instance),以便自动复制相关部分。
[merge "aggregate"]
name = agregate both new sections
driver = aggregate.sh %O %A %B这将是一个3向合并,这意味着您可以轻松地将%A和%B与%O (公共祖先)进行比较,以便隔离所述新部分,并将它们聚合到结果合并文件中。
该聚合合并驱动程序只需执行以下操作:
comm -13 $1 $3 >> $2(如果您使用的是Windows,那么comm实用程序是GoW -- Gnu on 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(+)现在,我们创建一个新的分支,并在该文件的两个版本中进行并发修改,在它的末尾,就像OP itsadok在问题中指定的那样。
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 is an alias of mine)
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 mergeNormal:我们需要编写该脚本,并将其添加到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"在这里:来自abranch的test.txt文件的末尾已经被添加到master上的文件中。
发布于 2015-12-30 02:48:39
另一种解决方案是使用管道命令git-merge-file的--union选项。
[merge "aggregate"]
name = aggregate both new sections
driver = git merge-file --union -L %P %A %O %B这比使用comm更可靠:当输入行没有根据LC_COLLATE排序时,comm可能会生成错误的输出。
发布于 2014-07-11 22:31:36
如果不想重新添加已删除的行,则必须使用稍微复杂一点的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'https://stackoverflow.com/questions/11841127
复制相似问题