2015-02-09 4 views
8

Mi piace molto l'opzione git pull --rebase, ma quando la si utilizza in combinazione con un conflitto di merge risolvo due volte i conflitti. Ho provato a utilizzare git pull --rebase=preserve che dovrebbe renderlo considerando anche le unioni.GIT: Perché devo risolvere i miei conflitti di fusione due volte quando utilizzo rebase?

Provate a dare un'occhiata al seguente esempio:

# do a new clone "a" 
$ mkdir origin && cd origin && git init --bare --shared && cd .. 
$ git clone ./origin a && cd a 

# Add, commit, push 
a (master) $ echo "foo" > foo && git add foo && git commit -m "foo" 
a (master) $ git push origin master 

# Create branch "b" 
a (master) $ git branch b 

# change foo and push 
a (master) $ echo "// eof " >> foo && git ci -am "eof - master" 
a (master) $ git push origin master 

# checkout branch "b", change and push 
a (master) $ git checkout b 
a (b) $ echo "// EOF " >> foo && git ci -am "EOF b" && git push origin b 

# back to master 
a (b) $ git checkout master 

# merge 
a (master) $ git merge b # conflict as expected 
a (master) $ git diff 
diff --cc foo 
index e10b853,1d3cc50..0000000 
--- a/foo 
+++ b/foo 
@@@ -1,2 -1,2 +1,6 @@@ 
    foo 
++<<<<<<< HEAD 
+// eof 
++======= 
+ // EOF 
++>>>>>>> b 

# Now, resolve the conflict 
a (master|MERGING) $ echo "foo" > foo && echo "// eof" >> foo && git add foo 
a (master|MERGING) $ git commit 

# In the mean while somewhere else. ############################################ 
a (master) $ cd .. && git clone ./origin other && cd other/ 
other (master) $ echo "bar" > bar && git add bar && git ci -am "bar" && git push # OK 

# Back to us ################################################################### 
other (master) $ cd ../a 
a (master) $ git push # will fail... 

# I now do a rebase preserve as I want to rebase my merge commit to the top of master 
a (master) $ git pull --rebase=preserve # This command does not do a very good job... 
a (master|REBASE-i 1/1) $ git diff 
diff --cc foo 
index e10b853,1d3cc50..0000000 
--- a/foo 
+++ b/foo 
@@@ -1,2 -1,2 +1,6 @@@ 
    foo 
++<<<<<<< HEAD 
+// eof 
++======= 
+ // EOF 
++>>>>>>> 3cd5d3ac5b870c613233f0a9f1a81df5691ccc7c 

Se sostituisco git pull --rebase=preserve con git pull --no-rebase allora funziona come previsto (ho solo bisogno di risolvere i conflitti una volta), ma poi devo guardare a tutti questi si fondono commit nel mio registro.

Come posso rendere git "rebase" l'unione e la risoluzione dei conflitti in modo che si adatti al nuovo HEAD remoto?

risposta

5

ho trovato che il Git "rerere" caratteristica risolto il mio problema

documentata in: git rerere --help o http://git-scm.com/docs/git-rerere

L'aggiunta di questo al mio .gitconfig

[rerere] 
    enabled = true 

Ha risolto il problema.

0

Rebase fondamentalmente solo si impegna tra HEAD e base e li applica in sequenza su base. Ciò significa che se ci sono delle fusioni tra di loro si perdono e devi risolvere nuovamente i conflitti. Illustrazione:

Diciamo che sono seguente albero:

A--B---M 
\ /
    `-C' 

M è l'unione di conflitto cambia B e C ed è il tuo HEAD. Ora, se si esegue git rebase A quindi git cercherà di creare seguente albero:

A-B-C 

Ma quando si cerca di applicare C su B incontra un conflitto. Dopo aver ignorato l'unione M deve chiederlo all'utente di risolverlo.

A questo punto si può solo controllare i file in questione dalla revisione M che li ha già fusa: git checkout M -- file/with/conflict, ma non so di qualsiasi mezzo per fare questo automaticamente (ad esempio Rebase opzione).

Per essere onesti io davvero non capisco avversione di fusioni delle persone, io personalmente vedo loro come utile, ma se si vuole si possono omettere in registro con --no-merges

+0

"Ciò significa che se ci sono delle fusioni tra di loro si perdono e devi risolvere nuovamente i conflitti." L'uso dell'opzione '--rebase = preserve' con' git pull' è equivalente a 'git rebase --preserve-merges', che indica al rebase di conservare le unioni. Apparentemente, la risoluzione del conflitto di tali fusioni non è considerata nella base di Rebase. –