2012-01-16 12 views
15

Got un file che ha due commit di interesse, sia sul ramo Master, sia solo modificando un singolo file foo: un precedente commit AA, e la versione corrente in HEAD. Vorrei unire le due versioni del file, mantenendo i bit di entrambi, in HEAD su Master.Git: Unire vecchio impegnarsi nella versione corrente di testa

ho fatto la cosa più semplice che ho pensato che sarebbe lavorare:

git checkout -b merge-purgatory AA 
git commit -m "pulled foo back from previous commit for merging into HEAD." 
git checkout master 
git merge merge-purgatory 

che sovrascrive semplicemente la versione corrente di HEADfoo con AA versione. Ho provato anche il più prolisso git checkout -m, lo stesso risultato: una sovrascrittura stupida.

Come posso forzare git a trattare la versione AA di foo come unione in conflitto con la versione HEAD corrente?

risposta

14

Se merge di Git non sta facendo ciò che si vuole, si potrebbe fare la seguente invece:

  1. Verificare che non vi siano modifiche non nel file foo, per esempio assicurandosi che git status sia pulito.
  2. sovrascrivere foo con la versione da AA utilizzando: git show AA:foo > foo
  3. selettivamente fase solo le modifiche da foo che desiderate con: git add -p foo
  4. scartare tutte le altre modifiche al foo con git checkout -- foo
  5. confermare le modifiche messe in scena: git commit

in alternativa, se si preferisce utilizzare uno strumento diff grafica (come ad esempio meld), Si può solo fare:

git show AA:foo > old-foo 
meld old-foo foo 
+2

Quindi, in pratica, basta bypassare la conoscenza di git del commit precedente e utilizzare un unione/unsetet manuale. Speravo in un comportamento più cromatico da Git, ma è così semplice che l'ho usato con successo e ho fatto un po 'di pulizia in seguito. Grazie! – Noel

1
git merge --no-commit merge-purgatory 

ti darebbe almeno la possibilità di rivedere: cambia l'unione prima di eseguirla.
Vedere anche le tecniche proposte in "How do you merge selective files with git-merge?", in base alla selezione della ciliegia o al checkout.


Per quanto riguarda costringendo l'unione manuale, si potrebbe dichiarare un .gitatributes file, per quel file specifico, una politica fusione impostato disinserire.

Esecuzione di un tre vie merge

merge

The attribute merge affects how three versions of a file is merged when a file-level merge is necessary during git merge, and other commands such as git revert and git cherry-pick. 
Unset 

accettare la versione dal ramo corrente come risultato della fusione sperimentale, e dichiarare che l'unione ha conflitti. Questo è adatto per file binari che non hanno una semantica merge ben definita.

+0

Is "recensione: cambiamento" un interruttore di comando o un'opzione? – Noel

+0

E, in ogni caso, "merge automatico è andato bene; fermato prima di impegnarsi come richiesto" abbastanza non rispondere alla mia domanda: come prevenire il "merge automatico" accada, e invece trattare le due versioni come in conflitto (che sono, sovrascrivendo le linee dell'altro) e richiedendo l'unione manuale? – Noel

+0

@Noel: scusa, ho zappato la parte di unione manuale. Ho modificato la mia risposta. – VonC

3

Le risposte precedenti non mantengono la storia del cambiamento, quindi il fatto che è stato utilizzato un precedente impegnano a generare il nuovo commit. La seguente procedura manterrà questa storia.

git checkout -b merge-purgatory AA 

qui è necessario modificare leggermente il file, ad esempio è possibile aggiungere una riga vuota. Quindi

git commit "pulled foo back from previous commit for merging into HEAD." 
git checkout master 
git merge --no-commit merge-purgatory 

In questo modo l'unione fallirà e quindi tutto ciò che devi fare è risolvere il conflitto. Questo ha funzionato per me.

Problemi correlati