Come chiudere correttamente un ramo di funzionalità in Mercurial?


240

Ho finito di lavorare su un ramo di funzioni feature-x. Voglio unire i risultati al defaultramo e chiuderli feature-xper liberarmene nell'output di hg branches.

Ho escogitato il seguente scenario, ma presenta alcuni problemi:

$ hg up default
$ hg merge feature-x
$ hg ci -m merge
$ hg up feature-x
$ hg ci -m 'Closed branch feature-x' --close-branch

Quindi il feature-xramo (changests 40- 41) è chiuso, ma c'è una nuova testa , il gruppo di cambiamenti del ramo di chiusura 44, che verrà elencato hg headsogni volta:

$ hg log ...
o  44 Closed branch feature-x
|
| @  43 merge
|/|
| o  42 Changeset C
| |
o |  41 Changeset 2
| |
o |  40 Changeset 1
|/
o  39 Changeset B
|
o  38 Changeset A
|

Aggiornamento : sembra che dalla versione 1.5 Mercurial non mostri più teste di rami chiusi nell'output di hg heads.

È possibile chiudere un ramo unito senza lasciare un'altra testa? Esiste un modo più corretto per chiudere un ramo di funzionalità?

Domande correlate:


@Andrey: ma l'articolo sottolineato NON parla solo di "--close-branch". Mostra quattro modi per potare il tuo ramo. Se davvero non lo vuoi più, puoi clonare come spiegato nell'articolo. L'unico "problema" è se, per qualsiasi motivo, desideri chiuderlo, ma tenerlo in giro.
Sintassix3rr0r

1
@WizardOfOdds Sì, ho letto l'intero articolo sulla potatura dei rami secchi. Voglio che il ramo rimanga nella cronologia delle revisioni, non di buttarla via. In precedenza ho appena unito i rami delle funzionalità defaultsenza "chiuderli". Ne risultarono 0 nuove teste ma tali rami erano visibili per hg branchessempre (come rami inattivi).
Andrey Vlasovskikh,

Per sviluppare funzionalità tendo a clonare l'intero repository e quindi a ricollegarlo una volta terminata la funzionalità. Non mi piace avere i resti di rami (chiusi) nella storia.
DanMan,

Risposte:


218

Un modo è quello di lasciare aperti (e inattivi) i rami delle funzioni unite:

$ hg up default
$ hg merge feature-x
$ hg ci -m merge

$ hg heads
    (1 head)

$ hg branches
default    43:...
feature-x  41:...
    (2 branches)

$ hg branches -a
default    43:...
    (1 branch)

Un altro modo è chiudere un ramo di funzionalità prima di unire utilizzando un commit aggiuntivo:

$ hg up feature-x
$ hg ci -m 'Closed branch feature-x' --close-branch
$ hg up default
$ hg merge feature-x
$ hg ci -m merge

$ hg heads
    (1 head)

$ hg branches
default    43:...
    (1 branch)

Il primo è più semplice, ma lascia un ramo aperto. Il secondo non lascia teste / rami aperti, ma richiede un altro commit ausiliario. È possibile combinare l'ultimo commit effettivo al ramo della funzione con questo commit aggiuntivo utilizzando --close-branch, ma è necessario sapere in anticipo quale commit sarà l'ultimo.

Aggiornamento : da Mercurial 1.5 puoi chiudere il ramo in qualsiasi momento in modo che non appaia in entrambi hg branchese hg headspiù. L'unica cosa che potrebbe infastidirti è che tecnicamente il grafico delle revisioni avrà ancora un'altra revisione senza bambini.

Aggiornamento 2 : da quando i segnalibri di Mercurial 1.8 sono diventati una caratteristica fondamentale di Mercurial. I segnalibri sono più convenienti per la ramificazione rispetto ai rami con nome. Vedi anche questa domanda:


2
Non è necessariamente vero Bookmarks are more convenient for branching than named branches. I segnalibri Hg non sono la stessa cosa dei rami Git. Sono pieni di molti casi limite che li rendono inadatti come rami delle caratteristiche. Ad esempio: quando clonate un repository finirete con l'ultimo commit nel defaultramo. Se si utilizzano i segnalibri, questo gruppo di modifiche corrisponde a un segnalibro casuale (instabile). Se usi i rami con nome, otterrai l'ultimo commit nel ramo stabile / predefinito, che di solito è quello che desideri. I segnalibri arriveranno lì un giorno, ma non sono ancora lì.
Gili,

Uso i segnalibri come tag privati ​​visibili solo nel mio repository locale. Fanno da promemoria dei cambiamenti che devo rivisitare.
Gili,

Ho cercato di seguire questo approccio, ma ho ancora un errore quando si cerca di spingere: abort: push creates new remote branches:. Cosa avrei potuto fare di sbagliato?
Kasperd,

79

imho ci sono due casi per i rami che sono stati dimenticati di chiudere

Caso 1: il ramo non è stato unito al valore predefinito

in questo caso aggiorno al ramo e faccio un altro commit con --close-branch, sfortunatamente questo elegge il ramo per diventare il nuovo suggerimento e quindi prima di spingerlo verso altri cloni mi assicuro che il vero suggerimento riceva qualche altro cambiamento e altri non confonderti con quello strano consiglio.

hg up myBranch
hg commit --close-branch

Caso 2: il ramo è stato unito al valore predefinito

Questo caso non è molto diverso dal caso 1 e può essere risolto riproducendo i passaggi per il caso 1 e altri due.

in questo caso aggiorno al changeset di branch, faccio un altro commit con --close-branch e unisco il nuovo changeset che è diventato la punta in default. l'ultima operazione crea un nuovo suggerimento che si trova nel ramo predefinito - HOORAY!

hg up myBranch
hg commit --close-branch
hg up default
hg merge myBranch

Spero che questo aiuti i futuri lettori.


3
Buona risposta chiara per un principiante Mercurial come me. E grazie per non aver usato "ci" che non è elencato come uno dei comandi di hg help, quindi non so cosa significhi :)
MB.

8
@MB .: in questi casi te hg help cilo spiegherà.
Chris Morgan,

Credo che il comando 'hg merge' ti dirà, c'è ancora un altro commit alla fine
Chip Grandits

11

EDIT ahi, troppo tardi ... So che leggi il tuo commento affermando che vuoi mantenere in giro il changeset feature-x, quindi l'approccio alla clonazione qui non funziona.

Lascerò ancora la risposta qui perché potrebbe aiutare gli altri.

Se vuoi eliminare completamente la "caratteristica X", perché, ad esempio, non ha funzionato, puoi clonare. Questo è uno dei metodi spiegati nell'articolo e funziona, e parla specificamente di teste.

Per quanto ho capito, hai questo e vuoi sbarazzarti della testa "feature-x" una volta per tutte:

@    changeset:   7:00a7f69c8335
|\   tag:         tip
| |  parent:      4:31b6f976956b
| |  parent:      2:0a834fa43688
| |  summary:     merge
| |
| | o  changeset:   5:013a3e954cfd
| |/   summary:     Closed branch feature-x
| |
| o  changeset:   4:31b6f976956b
| |  summary:     Changeset2
| |
| o  changeset:   3:5cb34be9e777
| |  parent:      1:1cc843e7f4b5
| |  summary:     Changeset 1
| |
o |  changeset:   2:0a834fa43688
|/   summary:     Changeset C
|
o  changeset:   1:1cc843e7f4b5
|  summary:     Changeset B
|
o  changeset:   0:a9afb25eaede
   summary:     Changeset A

Quindi fai questo:

hg clone . ../cleanedrepo --rev 7

E avrai quanto segue e vedrai che la caratteristica-x è davvero sparita:

@    changeset:   5:00a7f69c8335
|\   tag:         tip
| |  parent:      4:31b6f976956b
| |  parent:      2:0a834fa43688
| |  summary:     merge
| |
| o  changeset:   4:31b6f976956b
| |  summary:     Changeset2
| |
| o  changeset:   3:5cb34be9e777
| |  parent:      1:1cc843e7f4b5
| |  summary:     Changeset 1
| |
o |  changeset:   2:0a834fa43688
|/   summary:     Changeset C
|
o  changeset:   1:1cc843e7f4b5
|  summary:     Changeset B
|
o  changeset:   0:a9afb25eaede
   summary:     Changeset A

Potrei aver frainteso quello che volevi, ma per favore non abbassarti, mi sono preso del tempo per riprodurre il tuo caso d'uso:)


7

È strano che nessuno abbia ancora suggerito il modo più efficace per chiudere i rami di una funzione ... Puoi semplicemente combinare il comando di unione con il flag --close-branch (ovvero eseguire il commit dei file modificati e chiudere contemporaneamente il ramo):

hg up feature-x
hg merge default
hg ci -m "Merge feature-x and close branch" --close-branch
hg branch default -f

Quindi, tutto qui. Nessuna testa in più su revgraph. Nessun impegno extra.


L'ho menzionato nella mia risposta: "" "Si può combinare l'ultimo commit effettivo con il ramo di funzionalità con questo commit extra usando --close-branch, ma si dovrebbe sapere in anticipo quale commit sarà l'ultimo." " "
Andrey Vlasovskikh,

Va bene, ho capito. Non capisco proprio l'ultima parte della frase ("ma uno dovrebbe sapere ..."), quindi ho pensato che significasse qualcosa di diverso. Inoltre, vorrei notare che questo metodo non è supportato dalla maggior parte degli strumenti della GUI (TortoiseHG, SourceTree ecc.).
tav

@AndreyVlasovskikh Il punto di questa risposta è chiudere il ramo nell'unione piuttosto che nell'ultimo commit del ramo funzione.
Kasperd,

@tav Prima di emettere il mergecomando potrebbe essere una buona idea utilizzare hg branchper verificare che il nome del ramo dell'unione sia quello che si desidera mantenere aperto.
Kasperd,

2
A prima vista sembra che l'unione sarà sempre sul ramo chiuso. Il risultato desiderato sarebbe che si trova sul ramo di uno dei suoi genitori e chiude il ramo dell'altro genitore. Questo sembra non essere possibile. Quindi, dopo tutto, questa non sembra una soluzione praticabile. Peccato, volevo davvero usare un'unione come punto di chiusura di un ramo.
Kasperd,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.