git和append主要是文件的策略 [英] strategy for git and append-mostly files

查看:168
本文介绍了git和append主要是文件的策略的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



作为一个恼人的副作用,每当两个人同时添加时,我会遇到合并冲突,并且解决方案始终涉及手动复制粘贴,以便两个版本的行都包含在内。



是否有缓解这个过程的一些痛苦的技巧,技巧或方法?



例如,一个简单的解决方案是告诉开发人员在文件中间的随机位置添加新行。这可能会起作用,但它涉及到一个有意识的努力和一个奇怪的历史。 您可以使用 gitattributes 机制来定义自定义合并驱动程序(例如this一个例子),以便自动复制相关部分。

  [mergeaggregate] 
name =汇总两个新章节
driver = aggregate.sh%O%A%B

这将是一个3路合并,这意味着您可以轻松地区分%A %B c $ c>%O (共同的祖先),以便隔离新的部分,并将它们聚合到结果合并文件中。



聚合合并驱动程序只需要做:

  comm -13 $ 1 $ 3>> $ 2 

(comm工具是 GoW - Windows上的Gnu - 发行版,如果你使用Windows的话)




下面是一个小小的演示:首先,让我们设置一个Git仓库,并在两个分支中修改文件('

$ $ $ $ $ $ $ $ p> C:\prog\git\测试> mkdir agg
C:\prog\git\测试> cd agg
C:\prog\\ \\ git \tests\agg> git init r1
在C:/prog/git/tests/agg/r1/.git/
中初始化了空的Git仓库C:\prog\git\\ \\tests\gg> cd r1

#我是谁?
C:\prog\git\tests\agg\r1> git config user.name VonC
C:\prog\git\tests\agg\r1> git config user.email vonc @ xxx

#一个文件,第一次提交:
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第一次提交
[master c34668d]第一次提交
1个文件已更改,1个插入(+)
创建模式100644 test.txt

#让我们再添加一条公共线:
C:\prog\git\tests\agg\r1> ; echo base>> test.txt
C:\prog\\git\tests\agg\r1>更多test.txt
测试
基准
C:\prog\ git \tests\agg\r1> git add。
C:\prog\git\tests\agg\r1> git commit -mbase
[master d1cde8d] base
1个文件已更改,1个插入(+ )

现在我们创建一个新的分支,并对该文件的两个版本进行并发修改,它的结尾就像 OP itsadok 在问题中指定的那样。

  C:\prog\git\tests\agg\r1> git checkout -b abranch 
转换到新分支'abranch'
C :\prog\git\tests\agg\r1> echo从abranch修改>> test.txt
C:\prog\git\tests\agg\r1> git add。
C:\prog\git\tests\agg\r1> git commit -mabranch contrib
[abranch a4d2632] abranch contrib
1个文件已更改,1个插入(+)
C:\prog\git\tests\agg\r1>类型test.txt
测试
基准
从abranch修改

#回到master
C:\prog\git\tests\agg\r1> git checkout master
转换到分支master
C :\prog\git\tests\agg\r1> echomaster from master>> test.txt
C:\prog\git\tests\agg\r1> git add。
C:\prog\git\tests\agg\r1> git commit -mcontrib from master
[master 45bec4d] contrib from master
1文件已更改, 1插入(+)
C:\prog\git\tests\agg\r1>类型test.txt
测试
基准
来自master的contrib

我们有两个分支(注意: git lg 是我的别名

  C:\prog\git\tests\agg\r1> git lg 
* 45bec4d - (HEAD,master)contrib from master 86分钟前)VonC
| VonC
| /
* d1cde8d - base(87分钟前)VonC
* c34668d - first commit(89分钟前)VonC

现在让我们试一下合并:



<$ p $ > C:\prog\git\tests\agg\r1> git合并abranch
自动合并test.txt
CONFLICT(内容):合并冲突在test.txt中
自动合并失败;修复冲突,然后提交结果。

C:\prog\git\tests\agg\r1> more test.txt
test
base
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< <<<< HEAD
来自主人的贡献
=======
来自abranch的修改
>>>>>>> abranch

...失败,因为广告;) git merge --abort 会重置这种情况。



让我们放置我们的合并驱动程序

  C:\prog\git\tests\agg\r1> git config merge.aggregate.nameaggregate两个新节
C:\prog\\git\tests\agg\r1> git config merge.aggregate.driveraggregate.sh%O%A%B
C: \prog\git\tests\agg\r1> echo test.txt merge = aggregate> .gitattributes

此时,合并仍然失败:

  C:\prog\git\tests\agg\r1> git合并abranch 
aggregate.sh .merge_file_a09308 .merge_file_b09308 .merge_file_c09308:聚合.sh:找不到命令
致命:无法执行内部合并

正常情况:我们需要编写该脚本并将其添加到 PATH

  vim aggregate.sh:
!!/ bin / bash

#echo $:$ 1
#echo A:$ 2
#echo B:$ 3

#在http://serverfault.com/q/68684/783
之后#我如何获得差异以显示仅添加和删除的行?
#在Windows上,安装GoW(https://github.com/bmatzelle/gow/wiki/)
ob = $(comm -13 $ 1 $ 3)
#echoob:$ {ob}

echo $ {ob}>> $ 2

----

C:\prog\git\tests\agg\r1> set PATH =%PATH%; C:\ prog \git\tests\agg\r1

现在, code> aggregate 合并驱动程序可以运行

  C:\ prog \ git\tests\agg\r1> git merge --no-commit abranch 
自动合并test.txt
自动合并进行得很顺利;在提交之前停止请求

C:\prog\\git\tests\agg\r1>类型test.txt
测试
基准
contrib from master
modif from abranch

你在这里:结束 test.txt 文件来自 abranch 已被添加到 master


I have some files in my repository that are bottom-growing: most of the changes involve adding new lines at the bottom of the file. This is mostly language and other property files.

As an annoying side effect, whenever two people make additions at the same time I get merge conflicts, and the resolution always involves manually copy-pasting so that lines from both versions get included.

Is there a tip, trick or methodology that will relieve some of the pain of this process?

For example, a simplistic solution would be to tell the developers to add new lines at random places in the middle of the file. This will probably work, but it involved a conscious effort, and a weird-looking history.

解决方案

You could use the gitattributes mechanism to define a custom merge driver (like this one for instance) in order to copy automatically the relevant sections.

[merge "aggregate"]
        name = agregate both new sections
        driver = aggregate.sh %O %A %B

It will be a 3-way merge, which means you can easily diff %A and %B against %O (common ancestor) in order to isolate said new sections, and aggregate them in the result merged file.

That aggregate merge driver needs only to do:

comm -13 $1 $3 >> $2

(The comm utility is part of the GoW -- Gnu on Windows -- distribution, if you are on Windows)


Here is a little demo:

First, let's set up a Git repo, with a file modified in two branches ('master' and '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(+)

Now we create a new branch, and make concurrent modifications in both versions of that file, at the end of it like the OP itsadok specifies in the question.

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"

We have out two branches (note: 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

Now let's try a merge:

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

... Failed as advertised ;) A git merge --abort will reset the situation.

Let's put in place our merge driver:

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

At this point, a merge still fails:

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

Normal: we need to write that script, and add it to the 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

And now, the aggregate merge driver can operate:

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"

Here you go: the end of the test.txt file from abranch has been added to the file on master.

这篇关于git和append主要是文件的策略的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆