2012-07-23 14 views
6

Ho un sacco di commit, ad esempio A, B, C, D, e voglio mantenere B, C e D, e fare un commit che è (BCD) ⁻¹. Qual è il modo più semplice per farlo, se ho molti commit che voglio annullare allo stesso tempo?Come posso annullare più commit in Mercurial?

(mi sembra di ricordare di vedere una domanda StackOverflow di questo che ha suggerito che ho hg update ad A, e quindi chiamare hg commit con alcuni argomenti, ma io non riesco a trovare questa domanda ora.)

risposta

1

You' Ho risposto alla tua domanda, aggiornare di nuovo ad A e solo continuare da lì. Se hai bisogno di fare una nuova testa a quel punto, dovrai apportare una modifica ad un file o all'altro come descritto qui: How can I force mercurial to accept an empty commit. A mail thread collegato da quel post descrive un modo di utilizzare MqExtension per rimuovere BCD (a meno che non li abbiate spinti):

+0

Questo, ma solo se D è un TESTA. Non ci sono garbage collection in hg, quindi B, C e D non andranno persi. D rimarrà solo una TESTA che puoi spingere o meno - fino a te. – DanMan

4

Sembra che stiate cercando backout. Vedere:

hg help backout 

non credo che si può tornare indietro multipli impegna in una sola volta, in modo da avere a loro tornare indietro singolarmente:

hg backout D 
hg backout C 
hg backout B 

Questo creerà tre commit in cima a D che sono il contrario di D, C e B. Se si desidera combinare questi commit in un changeset, è possibile piegarli utilizzando rebase --collapse o uno dei numerosi altri interni (ad esempio le estensioni histedit o collapse).

Se non si desidera eseguire le singole modifiche, ma fare tutto in una volta, si potrebbe procedere come segue:

hg update A 
hg debugsetparents D 
hg commit -m "revert B-D" 

E 'brutto, ma funziona. Tuttavia questo non registra i nomi in negativo. Per essere onesti però, non consiglierei di farlo, se hai bisogno di tirarti indietro così tanto che i singoli comandi di backout sono troppo difficili da scrivere, mi chiedo se il back out sia davvero quello che dovresti fare per quel particolare Astuccio.

In alternativa, si potrebbe fare come suggerito da Jim e Rafael, e decidere che B, C e D sono su un ramo, e aggiornare di nuovo ad A e continuare a commettere lì (dividendo la cronologia in quel punto). Questo potrebbe essere più appropriato.

+0

Questo farà ciò che voglio (se schiaccio i tre commit insieme in mq), ma diventerà poco pratico se ci sono, diciamo, 50 commit che voglio annullare. Sto cercando qualcosa di più vicino alla seconda parte della risposta accettata in http://stackoverflow.com/questions/1463340/revert-multiple-git-commits (ma per hg), cioè l'equivalente hg di 'git reset --hard A && git reset --soft @ {1} && git commit -a' –

+0

Ho aggiornato la risposta con un modo per farlo in Mercurial. Tuttavia, come la risposta git a cui ti sei collegato, in realtà non inverte i changeset. Mi fa davvero meravigliare, però, perché mai vorresti ripristinare una sequenza così ampia di changeset. Sembra meglio parcheggiarli su un ramo inattivo e continuare dal cambiamento precedente. Se descrivi un po 'il tuo caso d'uso nella tua domanda, potrebbe aiutarti a trovare una soluzione migliore al tuo problema. –

+0

Inoltre, è possibile prendere in considerazione l'invio di una richiesta di funzionalità a Mercurial per il comando di backout per accettare un set di revisione anziché solo singole revisioni. –

4

Il modo più semplice:

Sei in changeset D e si desidera interrompere quel ramo

hg commit --close-branch -m "Branch closed" 

Ora, basta andare a changeset A e continuare il vostro lavoro commettere novità

hg up -r A 
... change stuff ... 
hg ci -m "New stuff" 

Il ramo con B, C e D sarà lì, ma verrà terminato, non verrà mostrato in hg heads. Sarà un ramo inattivo.

Anche questo è facile da fare ed espressivo. Se guardi il grafico vedrai un ramo separato che è stato chiuso e il ramo "ufficiale" andrà avanti. È molto meglio che avere quei changeset e backout che fanno rumore nel tuo ramo.

+1

Come spiegato in [un'altra domanda] (http://stackoverflow.com/questions/3688263/mercurial-beheading- a-head), quando provi a spingere la testa chiusa in un altro repository, riceverai un avvertimento sulla creazione di più teste. Quindi, usa 'hg push --force' la prima volta che premi. Le persone che tirano la testa chiusa non riceveranno alcun avvertimento. – mernst