28

リポジトリに底が大きくなっているファイルがいくつかあります。ほとんどの変更には、ファイルの下部に新しい行を追加することが含まれます。これは主に言語およびその他のプロパティファイルです。

厄介な副作用として、2人が同時に追加を行うと、マージの競合が発生します。解決には、両方のバージョンの行が含まれるように、常に手動でコピーして貼り付ける必要があります。

このプロセスの苦痛の一部を軽減するためのヒント、トリック、または方法論はありますか?

たとえば、単純な解決策は、ファイルの中央のランダムな場所に新しい行を追加するように開発者に指示することです。これはおそらくうまくいくでしょうが、それは意識的な努力と奇妙に見える歴史を伴いました。

4

3 に答える 3

17

関連するセクションを自動的にコピーするために、 gitattributesメカニズムを使用してカスタムマージドライバーたとえば、このドライバーなど)を定義できます。

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

これは3方向のマージになります。つまり、上記の新しいセクションを分離し、結果のマージされたファイルに集約するために、(共通の祖先)を簡単%Aに比較できます。%B%O

その集約マージドライバーは、次のことを行うだけで済みます。

comm -13 $1 $3 >> $2

(通信ユーティリティは、 Windowsを使用している場合はGoW(WindowsではGnu)ディストリビューションの一部です)


ここに小さなデモがあります:

masterまず、2つのブランチ(' 'と' abranch')で変更されたファイルを使用してGitリポジトリを設定しましょう。

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(+)

ここで、新しいブランチを作成し、そのファイルの両方のバージョンで同時に変更を加えます。その最後に、質問で指定されたOPitsadokのようになります。

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"

2つのブランチがあります(注: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

...アドバタイズされたとおりに失敗しました;)Agit 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

于 2012-08-07T07:49:19.730 に答える
6

別の解決策は--union、plumbingコマンドのオプションを使用することgit-merge-fileです。

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

これは、を使用するよりも信頼性が高くなりcommます。comm入力行が。に従ってソートされていない場合、間違った出力が生成される可能性がありLC_COLLATEます。

于 2015-12-29T18:48:38.757 に答える
1

削除された行を再度追加したくない場合は、もう少し複雑な次の呪文を使用する必要があります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'
于 2014-07-11T14:31:36.190 に答える