Ho 2 commit, A quindi B, pronto per essere spinto. Mi rendo conto di aver dimenticato di aggiungere qualcosa in A.
Come posso aggiungere questa modifica ad A usando Magit? Non so nemmeno quale parte della documentazione di Git dovrei guardare.
Ho 2 commit, A quindi B, pronto per essere spinto. Mi rendo conto di aver dimenticato di aggiungere qualcosa in A.
Come posso aggiungere questa modifica ad A usando Magit? Non so nemmeno quale parte della documentazione di Git dovrei guardare.
Risposte:
Facciamo finta per un momento di voler aggiungere qualcosa al HEAD
commit, ovvero "il secondo commit B" nel tuo esempio.
Il popup di commit su cpresenta un " aAmend" vincolante . La pressione di quel tasto "modifica" le modifiche temporanee al HEAD
commit. Poiché i commit non sono modificabili in Git, questo sostituirà effettivamente il vecchio commit con un nuovo commit. Verrà visualizzato un buffer con il vecchio messaggio di commit, in modo da poterlo modificare nel caso in cui la modifica aggiunta richieda anche la modifica del messaggio. Come sempre, premere C-c C-cal termine della modifica del messaggio. Ciò equivale all'esecuzione git commit --amend
sulla riga di comando.
HEAD
consente di aggiungere le modifiche graduali e di modificarne il messaggio di commitPoiché spesso accade che devi solo modificare la modifica o il messaggio, Magit offre due varianti aggiuntive:
HEAD
senza modificare il messaggio di commitHEAD
senza aggiungervi le modifiche temporaneeQuando si desidera modificare un commit che non lo è HEAD
, allora quanto sopra non funzionerà. Questi comandi "modificano" sempre (ovvero sostituiscono) il HEAD
commit. Git non fornisce un singolo comando per modificare un commit diverso da quello, HEAD
quindi questo è un po 'più coinvolto.
Magit vuol fornire un tale comando, ma perché ci sono situazioni in cui è preferibile farlo in più passaggi, si discuterà quella prima.
La modifica di un commit diverso da HEAD
può essere suddivisa in tre passaggi:
A
) il HEAD
.HEAD
(come descritto sopra), con conseguente commit A'
.A
, ma per di più A'
.Questo può essere fatto usando un rebase interattivo. Digitare rper mostrare il popup rebase. Quindi digitare mper richiamare la variante rebase "modifica un commit". Viene visualizzato un buffer con commit recenti. Passa al commit che desideri modificare e digita C-c C-cper selezionarlo. Git quindi riavvolge la cronologia a quel commit e mostra le informazioni sul rebase in corso nel buffer di stato.
Modificare HEAD
come descritto sopra. Quindi dì a Git che hai finito digitando r r. Se A'
e B
conflitto allora rebase si fermerà a B
e devi risolvere il conflitto. Al termine, premere r rper continuare.
Se sai che le tue modifiche A
porteranno a conflitti con B
, procedi come descritto sopra, altrimenti usa il seguente approccio.
Git consente di creare "commit di correzione" usando git commit --fixup A
. Ciò crea un nuovo commit, che registra le modifiche che "avrebbero dovuto essere apportate in un altro commit". Quel commit diventa il nuovo HEAD
. Esiste anche una --squash
variante. Per informazioni sulle differenze, consultare la git-commit
pagina man.
Per combinare effettivamente il A
commit e il nuovo commit A'
e quindi riapplicarlo B
, devi usare rebase. Magit fornisce un comodo comando per farlo r f.
La principale differenza rispetto all'approccio di cui sopra è che qui creiamo prima un nuovo commit e poi ci riordiniamo per combinarlo con il "target" e riapplicare B
. Sopra abbiamo iniziato con il rifacimento invece di impegnarci.
Nel Magit sia la --fixup
e le --squash
varianti sono disponibili presso il commit a comparsa, su fe s. Ma Magit fornisce anche varianti "istantanee" dei comandi fixup e squash su Fe S. Queste varianti creano un nuovo commit come le varianti "non istantanee", ma poi combinano istantaneamente il commit fixup con il commit target usando rebase, senza che tu debba invocare un altro comando.
"Instant fixup" ( c F) è essenzialmente la stessa cosa di "extension HEAD
" ( c e), tranne per il fatto che funziona per qualsiasi commit, non solo HEAD
.
Ulteriori letture:
git-commit(1)
git-rebase(1)
git-commit
la pagina man reindirizza a git-rebase(1)
chi ha queste righe: Il messaggio di commit suggerito per il commit piegato è la concatenazione dei messaggi di commit del primo commit e di quelli con il comando "squash", ma omette i messaggi di commit di commit con il "fixup" comando. IOW, usa fixup se vuoi solo correggere il codice nel commit precedente, usa squash se vuoi anche correggere il messaggio di commit.
git commit --amend –C HEAD
è il comando Git che vuoi cercare e con Magit puoi fare ammenda C-c C-a
.
C-c C-a
è di una versione precedente (penso). Inoltre, non vedo traccia di "modifica" nel buffer della guida ( ?
).
Quindi un flusso di lavoro è:
Poi
L'autosquash sposta automaticamente tutto! Fixup si impegna nel posto giusto e li imposta per essere schiacciati sulla base.
i
mi dà Cannot rebase: Your index contains uncommitted changes. Please commit or stash them.
. Tranne il fatto che non ho alcuna modifica non impegnata. : /
Proceed despite merge in rebase range? [c]ontinue, [s]elect other, [a]bort
. Sta cercando di dirmi che il mio fixup potrebbe fare la cacca sulla prossima fusione?
merge in rebase
:, vedi BUGS sotto git help rebase
. Suggerisco di fare il fixup prima di tirare a monte.
Per ottenere l'ultimo commit, è "c a". La correzione è per l'ammissione di alcuni commit più vecchi.