Ribasamento un'unione git commit
-
24-10-2019 - |
Domanda
Prendete il caso seguente:
Ho un po 'di lavoro in un ramo argomento e ora sono pronto per unire di nuovo da padroneggiare:
* eb3b733 3 [master] [origin/master]
| * b62cae6 2 [topic]
|/
* 38abeae 1
I eseguire l'unione da maestro, risolvere i conflitti e ora ho:
* 8101fe3 Merge branch 'topic' [master]
|\
| * b62cae6 2 [topic]
* | eb3b733 3 [origin/master]
|/
* 38abeae 1
Ora, l'unione mi ha preso un po 'di tempo, così faccio un altro a prendere e notare che il ramo master remoto ha nuove modifiche:
* 8101fe3 Merge branch 'topic' [master]
|\
| * b62cae6 2 [topic]
| | * e7affba 4 [origin/master]
| |/
|/|
* | eb3b733 3
|/
* 38abeae 1
Se provo 'origine git rebase / master' da padrone, sono costretto a risolvere ancora una volta tutti i conflitti, e ho anche perso l'unione commit:
* d4de423 2 [master]
* e7affba 4 [origin/master]
* eb3b733 3
| * b62cae6 2 [topic]
|/
* 38abeae 1
C'è un modo pulito per rebase l'unione commettere così finisco con una storia come quella che vi mostro qui di seguito?
* 51984c7 Merge branch 'topic' [master]
|\
| * b62cae6 2 [topic]
* | e7affba 4 [origin/master]
* | eb3b733 3
|/
* 38abeae 1
Soluzione
Ci sono due opzioni qui.
Una è quello di fare un rebase interattivo e modificare l'unione commit, rifare l'unione manualmente e continuare la rebase.
Un altro è quello di utilizzare l'opzione -p
su git rebase
, che è descritta come segue dal manuale: "Invece di ignorare le unioni, cercare di ricreare loro" Questa domanda spiega ulteriormente: Che cosa significa esattamente "rebase di git --preserve-merge" fanno (e perché?)
Altri suggerimenti
Ok, questa è una vecchia questione ed è già risposta accettata da @siride
, ma che la risposta non era abbastanza in il mio caso, mentre le forze --preserve-merges
a risolvere tutti i conflitti seconda volta. La mia soluzione basata sull'idea da @Tobi B
ma con esatta passo-passo i comandi
Quindi inizieremo a tale stato sulla base di esempio nella domanda:
* 8101fe3 Merge branch 'topic' [HEAD -> master]
|\
| * b62cae6 2 [topic]
| |
| | * f5a7ca8 5 [origin/master]
| | * e7affba 4
| |/
|/|
* | eb3b733 3
|/
* 38abeae 1
Si noti che abbiamo 2 commit avanti maestri, in modo da cherry-pick non funzionerebbe.
-
Prima di tutto, creiamo la storia giusta che vogliamo:
git checkout -b correct-history # create new branch to save master for future git rebase -s ours -p origin/master
mezzi
-p
--preserve-merges
, lo usiamo per salvare il nostro merge commit nella storia mezzi-s ours
--strategy=ours
, lo usiamo per ignorare tutti i conflitti di unione, come non ci importa di quello che i contenuti saranno in quel merge commit, abbiamo solo bisogno di storia piacevole ora.La storia ci assomiglia che (master ignorando):
* 51984c7 Merge branch 'topic' [HEAD -> correct-history] |\ | * b62cae6 2 [topic] * | f5a7ca8 5 [origin/master] * | e7affba 4 * | eb3b733 3 |/ * 38abeae 1
-
Let 's Get indice corretto ora.
git checkout master # return to our master branch git merge origin/master # merge origin/master on top of our master
possiamo ottenere alcuni conflitti di unione aggiuntivi qui, ma questo è solo sarebbe conflitti da file modificati tra
8101fe3
ef5a7ca8
, ma non include già risolto i conflitti datopic
La storia si presenta così (ignorando corretta-storia):
* 94f1484 Merge branch 'origin/master' [HEAD -> master] |\ * | f5a7ca8 5 [origin/master] * | e7affba 4 | * 8101fe3 Merge branch 'topic' | |\ | | * b62cae6 2 [topic] |/ / * / eb3b733 3 |/ * 38abeae 1
-
L'ultima fase è quella di combinare la nostra filiale con la storia corretta e filiale con indice corretto
git reset --soft correct-history git commit --amend
Usiamo
reset --soft
per ripristinare la nostra filiale (e la storia) per correggere-storia, ma lasciare indice e albero di lavoro come è. Poi usiamocommit --amend
per riscrivere il nostro merge commit, che usato per avere un indice non corretto, con il nostro indice di buona da padrone.Alla fine avremo tale stato (nota un altro ID del top commit):
* 13e6d03 Merge branch 'topic' [HEAD -> master] |\ | * b62cae6 2 [topic] * | f5a7ca8 5 [origin/master] * | e7affba 4 * | eb3b733 3 |/ * 38abeae 1
Dato che ho appena perso un giorno cercando di capire questo e in realtà trovato una soluzione con l'aiuto di un collega, ho pensato di carillon.
Abbiamo una grande base di codice e abbiamo a che fare con 2 ramo pesantemente sta modificando allo stesso tempo. C'è un ramo principale e un ramo secondario se che.
Mentre io unire il ramo secondario nel ramo principale, si continua a lavorare nel ramo principale e per il momento ho finito, non riesco a spingere i miei cambiamenti, perché sono incompatibili.
Ho quindi bisogno di "rebase" mio "merge".
Questo è il modo in cui finalmente fatto:
1) Prendere nota del CSA. Es .: c4a924d458ea0629c0d694f1b9e9576a3ecf506b
git log -1
2) Creare la storia corretta, ma questo si romperà l'unione.
git rebase -s ours --preserve-merges origin/master
3) Prendere nota del CSA. Es .: 29dd8101d78
git log -1
4) Ora ripristinare dove eravate prima
git reset c4a924d458ea0629c0d694f1b9e9576a3ecf506b --hard
5) A questo punto unire il master corrente nel vostro lavoro ramo
git merge origin/master
git mergetool
git commit -m"correct files
6) Ora che avete i file giusti, ma la storia sbagliata, ottenere il giusto Storia sulla parte superiore del cambiamento con:
git reset 29dd8101d78 --soft
7) E poi --amend i risultati nella stampa originale impegnano
git commit --amend
Voila!
Sembra che ciò che si vuole fare è rimuovere il prima unione. Si potrebbe seguire la seguente procedura:
git checkout master # Let's make sure we are on master branch
git reset --hard master~ # Let's get back to master before the merge
git pull # or git merge remote/master
git merge topic
che si darebbe quello che vuoi.
- Dal merge commit
- cherry-pick il nuovo cambiamento che dovrebbe essere facile
- copiare la tua roba
- rifare l'unione e risolvere i conflitti, semplicemente copiando i file dalla vostra copia locale;)