Ho un paio di commit che dovrebbero essere uno solo. Se stessi usando git, userei:
git rebase -i <some-commit-before>
e poi schiacciarli.
Posso farlo in Mercurial? Se é cosi, come?
Ho un paio di commit che dovrebbero essere uno solo. Se stessi usando git, userei:
git rebase -i <some-commit-before>
e poi schiacciarli.
Posso farlo in Mercurial? Se é cosi, come?
Risposte:
Sì, puoi farlo usando Mercurial senza alcuna estensione concatenando i changeset .
In alternativa, se desideri utilizzare un'estensione, puoi utilizzare:
Il mio preferito è il hg strip --keep
comando. E poi effettuo tutte le modifiche in un unico commit.
È il modo più veloce e comodo per me, perché mi piace fare tanti piccoli impegni durante il mio lavoro quotidiano;)
Nota 1: strip
necessita di un'estensione incorporata mq
per essere abilitata.
Nota 2: il mio client Git / Mercurial preferito (SmartGit / Hg) aggiunge il --keep
parametro predefinito durante strip
. E ciò che è ancora più conveniente: fornisce un'opzione chiamata join commits
:]
hg strip --keep --rev [rev]
Dov'è rev
il numero di revisione del primo commit che vuoi schiacciare con l'ultimo
--rev
è opzionale, il comando completo èhg strip --keep [rev]
hg help strip
dà hg strip [-k] [-f] [-n] [-B bookmark] [-r] REV...
e omettendo la revisione mi dà abort: empty revision set
.
hg strip
non è l'idea migliore. Non è esattamente sicuro. Prova hg histedit
, forse anche provare a utilizzare l'estensione evolve.
L' estensione Rebase ha funzionato a meraviglia . Per schiacciare 2 commit:
$ hg rebase --dest .~2 --base . --collapse
Il punto è una scorciatoia per la revisione corrente.
È ancora più semplice quando hai alcuni commit su un ramo e vuoi comprimerli tutti in uno:
$ hg rebase --dest {destination branch (e.g. master)} --base . --collapse
Come funziona:
(da http://mercurial-scm.org/wiki/RebaseExtension#Collapsing )
Se stai leggendo questa risposta, puoi dimenticare ogni altra opzione menzionata in questa risposta e utilizzare il
fold
comando dall'estensione evolve .
evolve
è un'estensione di mercurial che ci aiuta ad avere una storia mutevole sicura, ma è ancora sperimentale. Puoi usarlo clonandolo dal suo repository e aggiungendolo nel tuo .hgrc in questo modo.
[extensions]
evolve = ~/evolve/hgext/evolve.py
Supponendo che tu abbia clonato evolve repo nella tua home directory. Adesso sei a posto. Puoi anche cercare aiuto da hg help fold
.
Dici fold
di schiacciare / piegare una catena lineare di commit che non è interrotta. Quello che fa fold è che crea un nuovo changeset che contiene le modifiche da tutti i changeset e contrassegna tutti quei commit come obsoleti. Puoi avere una visione più approfondita di questo in docs .
Supponiamo ora di avere la seguente cronologia.
a -> b -> c -> d -> e -> f -> g
Si vuole schiacciare e
, f
e g
. Tu puoi fare
hg up g
hg fold -r e
Il risultato sarà
a -> b -> c -> d -> h
dov'è h
il changeset che contiene le modifiche da tutti e tre i commit e
, f
e g
.
Puoi anche piegare i changeset dal centro della cronologia, cioè non devi necessariamente scegliere una catena che include la punta. Si supponga di voler piegare b
, c
e d
. Tu puoi fare
hg up d
hg fold -r b
hg evolve --all
Questo risulterà in
a -> i -> j
dove i
è il changeset piegato b
, c
, d
ed j
è la stessa come changeset h
.
La guida per l'utente Evolve è assolutamente da leggere.
--keep
opzione di rebase copre questo (seguito dal contrassegno delle revisioni come segrete o dall'uso di strisce su di esse dopo aver controllato il risultato). Anche lo spostamento delle revisioni tra altre revisioni è possibile con una sequenza di due comandi rebase.
Con Mercurial 4.8 (novembre 2018, 9 anni dopo), potresti prendere in considerazione il nuovo comando hg absorb
(prima era una funzionalità sperimentale ).
Vedi " Assorbimento dei cambiamenti di commit in Mercurial 4.8 "
L'estensione per assorbire prenderà ogni modifica nella directory di lavoro, scoprirà quali commit nella serie hanno modificato quella riga e modificherà automaticamente la modifica a quel commit.
Se c'è qualche ambiguità (cioè più commit modificati sulla stessa riga), allora Absorb ignorerà semplicemente quel cambiamento e lo lascerà nella tua directory di lavoro per essere risolto manualmente.A livello tecnico,
hg absorb
trova tutte le modifiche non confermate e tenta di mappare ogni riga modificata su un commit precedente non ambiguo.
Per ogni modifica che può essere mappata in modo pulito, le modifiche non salvate vengono assorbite nel commit precedente appropriato. I commit influenzati dall'operazione vengono ribasati automaticamente.
Se una modifica non può essere mappata a un commit precedente non ambiguo, non viene eseguito il commit e gli utenti possono tornare a un flusso di lavoro esistente (ad esempio utilizzandohg histedit
).La logica di riscrittura automatica di
hg absorb
viene implementata seguendo la cronologia delle righe: Questo è fondamentalmente diverso dall'approccio adottato dahg histedit
ogit rebase
, che tende a fare affidamento su strategie di unione basate sull'unione a 3 vie per derivare una nuova versione di un file dato più input versioni.Questo approccio combinato con il fatto che hg Absorb salta le modifiche con un commit dell'applicazione ambiguo significa che hg Absorb non incontrerà mai conflitti di unione!
Ora, potresti pensare che se ignori le righe con obiettivi di applicazione ambigui, la patch si applicherebbe sempre in modo pulito utilizzando una classica unione a 3 vie. Questa affermazione sembra logicamente corretta. Ma non lo è:
hg absorb
può evitare conflitti di unione quando l'unione eseguita dahg histedit
ogit rebase -i
fallirebbe.
Penso che chistedit
(integrato a partire da Mercurial 2.3) sia il più vicino a rebase -i
quello puro Mercurial ( chistedit
è la versione interattiva di histedit
). Una volta in histedit, il fold
comando mappa a rebase squash
e il roll
comando mappa a rebase fixup
. Vedi la documentazione di histedit per maggiori informazioni.
Qui c'è un semplice esempio. Supponiamo di avere quanto segue e di voler spostare tutte le modifiche di 1e21c4b1 nella revisione precedente mantenendo solo il messaggio della revisione precedente.
@ 1e21c4b1 drees tip
| A commit you want to squash
o b4a738a4 drees
| A commit
o 788aa028 drees
| Older stuff
Puoi eseguire la hg chistedit -r b4a738a4
modifica della cronologia su b4a738a4. In chistedit si sposta quindi il cursore verso il basso su 1e21c4b1 e si preme r
per indicare che si desidera ottenere quella revisione. Si noti che l'ordine in histedit (dal più vecchio al più recente) è invertito da hg log
( dal più recente al più vecchio).
#0 pick 160:b4a738a49916 A commit
#1 ^roll 161:1e21c4b1500c
Dopo aver scelto le modifiche, scegli c
di eseguirle. Il risultato è il seguente:
@ bfa4a3be drees tip | Un commit o 788aa028 drees | Cose più vecchie
Se sei relativamente nuovo a loro, allora histedit
può essere una scelta migliore rispetto al chistedit
fatto che fornisce le descrizioni dei comandi nel file histedit come riferimento. Ci vuole solo un po 'più di editing per impostare i comandi usando la normale modifica del testo (proprio come il normale rebase).
Nota, per utilizzare histedit
o chistedit
è necessario aggiungere histedit
alle estensioni nel tuo ~ / .hgrc:
[extensions]
histedit =
Ho suggerito chistedit
poiché è il più vicino rebase -i
e funziona ovunque nella storia. Se vuoi solo riassumere / modificare la revisione corrente in quella precedente, allora @G. Il strip
suggerimento di Demecki può essere buono poiché ciò che sta accadendo è chiaro. È costruito a partire da Mercuria 2.8. Per ottenere i risultati equivalenti come sopra, puoi fare quanto segue:
hg strip .
hg add
hg commit --amend
Nota strip
, come histedit, deve essere abilitato nel tuo ~ / .hgrc:
[extensions]
strip =
Supponiamo che tu voglia schiacciare (unire) i 2 commit più recenti.
Trova un numero di revisione
hg log -G -l 3
possibile output:
@ changeset: 156:a922d923cf6f
| branch: default
| tag: tip
| user: naXa!
| date: Thu Dec 13 15:45:58 2018 +0300
| summary: commit message 3
|
o changeset: 155:5feb73422486
| branch: default
| user: naXa!
| date: Thu Dec 13 15:22:15 2018 +0300
| summary: commit message 2
|
o changeset: 154:2e490482bd75
| branch: default
~ user: naXa!
date: Thu Dec 13 03:28:27 2018 +0300
summary: commit message 1
Ramo di soft reset
hg strip --keep -r 155
Esegui nuovamente il commit delle modifiche
hg commit -m "new commit message"
strip
richiede un'estensione incorporata per essere abilitata. Crea / modifica ~/.hgrc
file di configurazione con il seguente contenuto:
[extensions]
strip =