git和附加文件的策略

git和附加文件的策略,git,git-merge,Git,Git Merge,我的存储库中有一些文件是底部增长的:大多数更改涉及在文件底部添加新行。这主要是语言和其他属性文件 作为一个恼人的副作用,每当两个人同时添加内容时,我就会遇到合并冲突,而解决方法总是涉及手动复制粘贴,以便包含两个版本中的行 是否有一个技巧、技巧或方法可以减轻这个过程中的一些痛苦 例如,一个简单的解决方案是告诉开发人员在文件中间的随机位置添加新的行。这可能会起作用,但它涉及到有意识的努力和奇怪的历史。您可以使用该机制定义一个自定义合并驱动程序(如),以便自动复制相关部分 [merge "aggreg

我的存储库中有一些文件是底部增长的:大多数更改涉及在文件底部添加新行。这主要是语言和其他属性文件

作为一个恼人的副作用,每当两个人同时添加内容时,我就会遇到合并冲突,而解决方法总是涉及手动复制粘贴,以便包含两个版本中的行

是否有一个技巧、技巧或方法可以减轻这个过程中的一些痛苦

例如,一个简单的解决方案是告诉开发人员在文件中间的随机位置添加新的行。这可能会起作用,但它涉及到有意识的努力和奇怪的历史。

您可以使用该机制定义一个自定义合并驱动程序(如),以便自动复制相关部分

[merge "aggregate"]
        name = agregate both new sections
        driver = aggregate.sh %O %A %B
这将是一个三方合并,这意味着您可以轻松地将
%a
%B
%O
(公共祖先)区分开来,以隔离所述新节,并将它们聚合到合并结果文件中

该聚合合并驱动程序只需执行以下操作:

comm -13 $1 $3 >> $2
(如果您在Windows上,comm实用程序是--distribution的一部分)


下面是一个小演示:

首先,让我们建立一个Git回购,在两个分支(“
master
”和“
abranch
”)中修改一个文件:

现在我们创建一个新的分支,并在该文件的两个版本中同时进行修改,最后就像问题中指定的那样

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"
我们有两个分支机构(注:)

现在让我们尝试合并:

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
此时,合并仍然失败:

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
正常:我们需要编写该脚本,并将其添加到
路径

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
现在,聚合合并驱动程序可以运行了

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 --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
上的文件中。如果您不想重新添加已删除的行,则必须使用稍微复杂一点的
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'

另一种解决方案是使用管道命令git merge file的
--union
选项

[merge "aggregate"]
    name = aggregate both new sections
    driver = git merge-file --union -L %P %A %O %B

这比使用
comm
更可靠:
comm
可能会在输入行未按照
LC\u-COLLATE
排序时生成错误的输出。刚刚添加了一个演示来演示这种合并驱动程序注:如中所述,合并驱动程序脚本和
.gittributes
文件可以进行版本控制,但是声明合并驱动程序的配置需要由克隆repo.Wow的每个用户声明。。。你确实多走了一英里。谢谢现在,如果有任何方法可以告诉github支持,那将是非常昂贵的。我认为您不需要添加自定义合并策略,只需在
内部设置
myfile merge=union
。gittributes
git config merge.aggregate.driver 'tmp=$(mktemp) ; (comm -12 %A %B ; comm -13 %O %A ; comm -13 %O %B ) >| $tmp ; mv $tmp %A'
[merge "aggregate"]
    name = aggregate both new sections
    driver = git merge-file --union -L %P %A %O %B