2012-01-03 17 views
31

mio albero locale è discostato dal master:git: rami divergenti; come procedere?

$ git status 
# On branch master 
# Your branch and 'origin/master' have diverged, 
# and have 7 and 3 different commit(s) each, respectively. 
# 
nothing to commit (working directory clean) 

ho provato git pull --rebase e non è riuscito:

$ git pull --rebase 
First, rewinding head to replay your work on top of it... 
Applying: * ... 
Using index info to reconstruct a base tree... 
Falling back to patching base and 3-way merge... 
Auto-merging ChangeLog 
CONFLICT (content): Merge conflict in ChangeLog 
Failed to merge in the changes. 
Patch failed at 0001 * ... 

Così ho ritornato con git rebase --abort ed io sono ora al quadrato 1.

Quello che voglio è:

  1. "Esportare" le mie 7 patch in file diff leggibili dall'uomo (a la hg export).
  2. Trasforma il mio albero in una copia carbone dell'origine/master (a la hg strip).
  3. riapplicare le mie 7 patch una per una a mano (a la hg import).

Capisco che git rebase --continue fa questo. L'ho fatto e ha funzionato (dopo un paio di fusioni manuali e un git aggiungere). Tuttavia, desidero essere in grado di farlo manualmente, , quindi mi chiedo quali sono i comandi corrispondenti ai comandi hg di cui sopra.

Grazie.

PS. Per favore non dirmi che usare un file ChangeLog con git è stupido. Anche se lo è, non dipende da me.

+0

1. git merge origine/master. 2. git pull --no-rebase. Dal momento che i tuoi commit sono enormi, tirare senza rebase sarà più facile. –

risposta

43

Esistono, naturalmente, diversi modi per eseguire questa operazione manualmente. Avrai comunque gli stessi conflitti perché git fondamentalmente lo sta facendo per te. Ma se vuoi farlo manualmente, ecco un paio di modi.

Prima di tutto, esporta i tuoi commit come una serie di patch. Il modo più semplice per farlo è usare git format-patch:

git format-patch -M @{upstream} 

produrrà 7 file di patch - uno per ciascuno dei tuoi commit. (Si noti che "@ {upstream}" è letterale - è una funzionalità non molto conosciuta di git.) È meglio che catturare l'output di git diff perché tutte le informazioni di commit (autore, data, messaggio, ecc.) Sono conservato.

allora si potrebbe ripristinare il repository per abbinare il monte:

git reset --hard @{upstream} 

Quindi è possibile applicare nuovamente le patch utilizzando git am - o uno alla volta o tutti insieme.

git am 0001-blah-blah.patch 
git am 0002-blah-blah.patch 
... 

Una seconda opzione sarebbe quella di creare un ramo di ricambio per il vostro lavoro su di esso:

git branch scrap 

quindi reimpostare la vostra filiale al monte:

git reset --hard @{upstream} 

Poi cherry-pick il commetti su:

git cherry-pick scrap~6 
git cherry-pick scrap~5 
git cherry-pick scrap~4 
... 

Poi cestinare il ramo di scarto:

git branch -D scrap 
+4

Al posto di "@ {upstream}" puoi persino utilizzare "@ {u}". –

+0

Questo è incredibilmente efficiente e pulito - si finisce con una storia lineare. – hauron

6

Git dice che ha cercato di fare esattamente quello che vuoi (riapplica le tue patch in cima alle ultime modifiche da origine/master) ma non è riuscito con un conflitto. Subito dopo i conflitti git pull --rebase, aprire un editor con i file in conflitto (git status elencherà questi in "entrambi modificati") e risolvere i conflitti, contrassegnati in standard diff lingua. Al termine della risoluzione del conflitto, immettere git rebase --continue (o git rebase --skip se la risoluzione non introduce modifiche).

Ulteriori informazioni sul suo Stackexchange documentation for 'Resolving merge conflicts after a Git rebase'.

+0

Git è piuttosto bravo a fondere (o risolvere automaticamente i "conflitti") e riapplicare le patch, ma purtroppo, a volte ha bisogno del tuo aiuto.In questi casi, nella mia esperienza, non conosco altri strumenti che farebbero meglio. Hai davvero bisogno di risolvere manualmente questi conflitti. – wilhelmtell

+0

Buon punto: assicuratevi di dare un'occhiata [git rerere] (http://progit.org/2010/03/08/rerere.html). –

+0

Questo non risponde alla domanda. – sds

15

Hai provato git merge origin/master?

Le modifiche remote sono memorizzate nel ramo origin/master. (O lo farà, se lo fai git fetch.) Basta unire i due rami - master e origin/master - come qualsiasi due rami e risolvere i conflitti (se presenti).

Questo può aiutare se è necessario sapere come risolvere i conflitti di git.

How to resolve merge conflicts in Git?

+0

Venerato. Ho avuto lo stesso identico problema e questo l'ha risolto. Personalmente non mi piace vi o vim, quindi ho cambiato il mio editor predefinito in nano. Google per le istruzioni. – Cocoadelica

0

Ecco alcune buone risposte allo stesso problema (solo senza risolvere i conflitti):

master branch and 'origin/master' have diverged, how to 'undiverge' branches'?

In primo luogo, si consiglia di rivedere ciò che è stato cambiato sul master a distanza in confronto con la tua versione locale:

git log HEAD..origin/master 

Per risolvere il tuo problema, si riduce al sam La linea che wilhelmtell ha proposto:

git pull --rebase 

Come hai detto, avrai dei conflitti.

La risoluzione dei conflitti è un problema ricorrente. Se non lo hai ancora fatto, puoi dare un'occhiata a git mergetool (vedi git help mergetool per i dettagli). Per ottenere supporto grafico, raccomanderei di sovrascrivere la configurazione merge.tool. Per esempio, se si desidera utilizzare meld per unioni a 3 vie, è possibile utilizzare:

git config --global merge.tool meld 

Così dopo che risolto il conflitto, che cosa ha fatto git pull --rebase? Ha unito tutte le modifiche da origine/master al tuo master locale e ha riprodotto le modifiche su di esso. Congratulazioni, sei tornato alla normalità.

+0

quando "git pull --rebase", dice "errore: alimentazione non modificata ... per diffcore Impossibile tirare con rebase: il tuo indice contiene modifiche non salvate. Per favore, commetti o riporli", ma quando "git commit", Dice "Il tuo ramo e 'origine/padrone' sono divergenti, e hanno rispettivamente 1 e 1 commit diversi, (usa" git pull "per unire il ramo remoto nel tuo) niente da salvare, directory di lavoro pulita" – diyism