remove - git tag recursive




strategia per git e append per lo più file (2)

È possibile utilizzare il meccanismo gitattributes per definire un driver di unione personalizzato (come questo, ad esempio ) al fine di copiare automaticamente le sezioni pertinenti.

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

Sarà un'unione a 3 vie, il che significa che puoi facilmente diff %A e %B rispetto a %O (antenato comune) per isolare dette nuove sezioni e aggregarle nel file unito ai risultati.

Quel driver di aggregazione aggregato deve solo fare:

comm -13 $1 $3 >> $2

(L'utilità di comunicazione è parte della distribuzione di GoW - Gnu su Windows , se sei su Windows)

Ecco una piccola demo:

Per prima cosa, impostiamo un repository Git, con un file modificato in due rami (' master ' e ' 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 [email protected]

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

Ora creiamo un nuovo ramo e apportiamo modifiche simultanee in entrambe le versioni di quel file, alla fine di esso come l' specifica nella domanda.

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"

Abbiamo due rami (nota: git lg è uno pseudonimo del mio )

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

Ora proviamo a unire:

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

... Fallito come pubblicizzato;) A git merge --abort ripristinerà la situazione.

Mettiamo in atto il nostro driver di unione :

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

A questo punto, una fusione non riesce ancora:

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

Normale: dobbiamo scrivere quello script e aggiungerlo al 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

E ora, il driver di fusione aggregate può operare :

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"

Ecco qua: la fine del file test.txt da abranch è stata aggiunta al file su master .

Ho alcuni file nel mio repository che sono in crescita dal basso: la maggior parte delle modifiche comporta l'aggiunta di nuove righe nella parte inferiore del file. Questo è principalmente linguaggio e altri file di proprietà.

Come fastidioso effetto collaterale, ogni volta che due persone fanno aggiunte allo stesso tempo ottengo conflitti di fusione e la risoluzione implica sempre il copia-incolla manuale in modo che le righe di entrambe le versioni vengano incluse.

C'è un suggerimento, un trucco o una metodologia che allevierà parte del dolore di questo processo?

Ad esempio, una soluzione semplicistica sarebbe quella di dire agli sviluppatori di aggiungere nuove linee in posti casuali nel mezzo del file. Questo probabilmente funzionerà, ma ha comportato uno sforzo consapevole e una storia dall'aspetto strano.


Se non si desidera aggiungere nuovamente le righe rimosse, è necessario utilizzare un incantesimo leggermente più complicato di comm :

tmp=$(mktemp)
(comm -12 %A %B ; comm -13 %O %A ; comm -13 %O %B ) >| $tmp
mv $tmp %A

Prima si seleziona tutta la linea comune alle revisioni locale e remota; questo assicura che tutte le righe cancellate rimangano cancellate. Quindi aggiungi le righe aggiunte dalla revisione remota, poi quelle aggiunte dalla revisione locale.

Questa può essere una strategia può essere installata in .gitconfig usando un singolo comando:

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