Git: Come modificare / riformulare il messaggio di un commit di unione?


148

Come posso modificare o riformulare il messaggio di un commit di unione?

git commit --amendfunziona se è l'ultimo commit fatto ( HEAD), ma cosa succede se arriva prima HEAD?

git rebase -i HEAD~5 non elenca i commit di merge.

Risposte:


207

Se aggiungi l' --preserve-mergesopzione (o il suo sinonimo -p) al git rebase -icomando, git proverà a preservare le fusioni durante la rigenerazione, anziché linearizzare la cronologia, e dovresti essere in grado di modificare anche i commit di unione:

git rebase -i -p HEAD~5

1
L'ho fatto, ma dopo aver apportato le mie modifiche e provo ad aumentare le mie modifiche, ottengo questo! [rejected] HEAD -> master (non-fast-forward)error: failed to push some refs to
Marc

1
prova a eseguire git push -f e quindi il tuo ramo di origine. questo dovrebbe funzionare. Ho avuto lo stesso problema, per qualche motivo questo è un artefatto del rebasing perché quello che è sostanzialmente accaduto è che dopo il rebasing sei finito con un hed distaccato, quindi la forza dovrebbe risolverlo e dovrebbe spingere tutto.
Radu Comaneci,

11
@Marc Questo accade perché hai modificato i commit che hai già inviato. È considerata una cattiva pratica forzare il push su un server poiché può desincronizzare completamente te e i tuoi colleghi. Bene, se sei solo non dovrebbe essere un problema.
ibizaman

Dov'è HEAD~5il genitore del commit che vuoi modificare (di solito sha1 ^).
Gabriel Devillers,

2
--preserve-mergesè ora--rebase-merges
OrangeDog,

32

Nota che, avviando git1.7.9.6 (e git1.7.10 +), esso git mergestesso attiverà sempre l'editor , in modo da poter aggiungere dettagli a un'unione.

" git merge $tag" per unire un tag annotato apre sempre l'editor durante una sessione di modifica interattiva. La serie v1.7.10 ha introdotto una variabile di ambiente GIT_MERGE_AUTOEDIT per aiutare gli script più vecchi a rifiutare questo comportamento, ma anche la traccia di manutenzione dovrebbe supportarlo.

Inoltre introduce una variabile d'ambiente GIT_MERGE_AUTOEDIT per aiutare gli script meno recenti a rifiutare questo comportamento.

Vedi " Anticipating Git 1.7.10 ":

Di recente in a discussione sulla mailing list di Git , Linus ha ammesso (e ho concordato) che questo è stato uno degli errori di progettazione che abbiamo fatto all'inizio della storia di Git.
E in 1.7.10 e versioni successive, il comando git merge che viene eseguito in una sessione interattiva (ovvero sia l'input standard sia l'output standard collegati a un terminale) aprirà un editor prima di creare un commit per registrare il risultato della fusione, per dare all'utente la possibilità di spiegare l'unione, proprio come il comando git commit che l'utente esegue dopo aver già risolto un'unione in conflitto.

Linus disse:

Ma non mi interessa davvero come funziona davvero - il mio problema principale è che git rende troppo facile avere messaggi di unione errati.
Penso che parte di ciò sia un'idiozia ancora più semplice: nongit commit
accendiamo mai l'editor per impostazione predefinita per un "git merge", ma lo facciamo per un " ". È stato un errore di progettazione e significa che se si desidera effettivamente aggiungere una nota a un'unione, è necessario svolgere un lavoro extra. Quindi la gente no .


Si noti che, prima di Git 2.17 (Q2 2018), " git rebase -p" hanno modificato i messaggi di registro di un commit di unione, che ora è stato corretto.

Vedi commit ed5144d (08 feb 2018) di Gregory Herrero (``) .
Suggerito da: Vegard Nossum ( vegard) e Quentin Casasnovas ( casasnovas) .
(Unita da Junio ​​C Hamano - gitster- in commit 8b49408 , 27 febbraio 2018)

rebase -p: risolve il messaggio di commit errato durante la chiamata git merge .

Dal momento che commit dd6fb00 (" rebase -p: correzione dell'offerta durante la chiamatagit merge ", gennaio 2018, Git 2.16.0-rc2), il messaggio di commit del commit di merge in fase di riepilogo viene passato al comando di merge usando una subshell che esegue ' git rev-parse --sq-quote'.

Le virgolette doppie sono necessarie attorno a questa subshell in modo che, le nuove righe vengano mantenute per il git merge comando.

Prima di questa patch, seguire il messaggio di unione:

"Merge mybranch into mynewbranch

Awesome commit."

diventa:

"Merge mybranch into mynewbranch Awesome commit."

dopo a rebase -p.


Con Git 2.23 (2 ° trimestre 2019), una " merge -c" istruzione durante " git rebase --rebase-merges" dovrebbe dare all'utente la possibilità di modificare il messaggio di registro, anche quando altrimenti non è necessario creare una nuova unione e sostituire quella esistente (ovvero avanzamento rapido invece ), ma non lo ha fatto.
Che è stato corretto.

Vedi commit 6df8df0 (02 maggio 2019) di Phillip Wood ( phillipwood) .
(Unito da Junio ​​C Hamano - gitster- in commit c510261 , 13 giu 2019)


16

Un'altra bella risposta usando solo i comandi primitivi - di knittl https://stackoverflow.com/a/7599522/94687 :

git checkout <sha of merge>
git commit --amend # edit message
git rebase HEAD previous_branch

o un comando rebase finale migliore (più corretto):

git rebase <sha of merge> previous_branch --onto HEAD

A proposito, l'uso dei comandi primitivi potrebbe avere la bella "caratteristica" di non consumare troppa CPU e di farti aspettare un tempo sconosciuto fino a quando Git non avrà finito di pensare all'elenco dei commit che devono essere rielaborati in caso di git rebase -p -i HEAD^^^^(tale comando che comporterebbe un elenco di soli 4 ultimi si impegna con l'unione come l'ultima nel mio caso nel mio caso ha richiesto circa 50 secondi!).


2
Questo è davvero utile, risparmiami un bel po 'di tempo. La mia azienda blocca alcuni messaggi di commit nel repository, che è facile con --amend o con i comandi rebase ma: Un grosso problema se uniamo un ramo nel tuo, facciamo un commit e proviamo a spingere, il messaggio di unione predefinito di git è bloccato ( questo dovrebbe essere risolto, lo so) che ci costringe a cambiare quel messaggio. Fino a questa risposta ho provato molte cose a cambiare un messaggio di unione tra una cronologia di commit senza successo.
Giovanni Silva,

2

git merge --edit
Ti permette di dare il commento anche in caso di unione non interattiva.

git merge --edit --no-ff può essere utile se segui git flow con rebasing sul ramo di sviluppo e ti fondi in esso senza avanzamento veloce.


2

Per le attuali versioni di Git (Mai 2020):

git rebase -i -r <parent>,

quindi sostituire nell'editor merge -C ...con merge -c ....

Questo aprirà il messaggio di commit nell'editor durante il rebasing, dove puoi cambiarlo.

(Grazie a VonC per il suggerimento .)


0

Il git rebase -i HEAD~5comando apre l'editor. Elenca i commit specificati (in questo caso cinque). La prima colonna contiene pickper ogni commit. Basta sostituire pickcon rewordin quell'editor e salvare + chiudere l'editor. Poi git si aprirà l'editor per ogni commit in cui è stata modificata pickper reworde vi permetterà di modificare il messaggio di commit.


6
Questo non funziona per un commit di merge a meno che non si aggiunga anche -pal git rebasecomando.
Paul Price,

4
ottima risposta se fosse una domanda diversa
doz87
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.