Modifica del messaggio di commit git dopo il push (dato che nessuno ha estratto dal telecomando)


983

Ho fatto un commit git e successiva spinta. Vorrei cambiare il messaggio di commit. Se ho capito bene, questo non è consigliabile perché qualcuno potrebbe aver estratto dal repository remoto prima di apportare tali modifiche. E se sapessi che nessuno ha tirato?

C'è un modo per fare questo?


Che cosa hai provato? Supponendo che tu sappia già come modificare il messaggio di commit e poi prova a spingere, Git ti dirà cosa devi fare per farlo accadere.
Andrew Marshall,

1
Vedi la risposta alla domanda "Come posso modificare un messaggio di commit errato in git (ho premuto)?" stackoverflow.com/a/457396/444639
Mike Rylander

4
Dichiarandolo - Google Domanda di git commit Rango n. 1!
Manish Shrivastava,


Se si modifica il commit HEAD e si spinge di solito (senza --force), sorprendentemente non fallisce. Il messaggio di commit HEAD viene aggiornato con l'ID commit modificato. Significa che altri ID di commit tranne HEAD rimangono intatti. Ho notato questo comportamento con la versione 2.8.1 di git.
Irsis,

Risposte:


1374

Storia che cambia

Se è il commit più recente, puoi semplicemente farlo:

git commit --amend

Questo fa apparire l'editor con l'ultimo messaggio di commit e ti permette di modificare il messaggio. (Puoi usarlo -mse vuoi cancellare il vecchio messaggio e usarne uno nuovo.)

spingendo

E poi quando spingi, fai questo:

git push --force-with-lease <repository> <branch>

Oppure puoi usare "+":

git push <repository> +<branch>

Oppure puoi usare --force:

git push --force <repository> <branch>

Fai attenzione quando usi questi comandi.

  • Se qualcun altro ha inviato le modifiche allo stesso ramo, probabilmente vorrai evitare di distruggerle. L' --force-with-leaseopzione è la più sicura, perché si interromperà in caso di modifiche a monte (

  • Se non specifichi esplicitamente il ramo, Git utilizzerà le impostazioni push predefinite. Se l'impostazione push predefinita è "corrispondente", è possibile distruggere le modifiche su più rami contemporaneamente.

Tirare / recuperare in seguito

Chiunque abbia già estratto ora riceverà un messaggio di errore e dovrà aggiornarlo (supponendo che non stia apportando alcuna modifica da solo) facendo qualcosa del genere:

git fetch origin
git reset --hard origin/master # Loses local commits

Fai attenzione quando lo usi reset --hard. Se sono presenti modifiche al ramo, tali modifiche verranno distrutte.

Una nota sulla modifica della cronologia

I dati distrutti sono in realtà solo il vecchio messaggio di commit, ma --forcenon lo sanno e elimineranno felicemente anche altri dati. Quindi pensa --forcea "Voglio distruggere i dati e so con certezza quali dati vengono distrutti". Ma quando vengono commessi i dati distrutti, è spesso possibile recuperare vecchi commit dal reflog: i dati vengono effettivamente resi orfani anziché distrutti (sebbene i commit orfani vengano periodicamente eliminati).

Se non pensi di distruggere i dati, stai lontano da --force... potrebbero succedere cose brutte .

Questo è il motivo per cui --force-with-leaseè un po 'più sicuro.


13
Fai attenzione a quella "correzione", come se avessero dei commit locali e non compressi che saranno "persi" ( perso significa veramente orfano , ma recuperarli non è ovvio).
Andrew Marshall,

1
probabilmente si desidera specificare il nome del ramo quando si preme --force, altrimenti si può spingere più del previsto.
user693960

1
@ user693960: Git invierà solo ciò che si configura per inviare.
Dietrich Epp,

10
Semplicemente anche git push --forcesenza le opzioni <repository> e <branch> funziona, se hai il tuo upstream impostato.
ahnbizcad,

2
Puoi fare un esempio di <repository>? È vero origin? org/repo? O semplicemente repo?
MikeSchinkel,

440

Di 'solo:

git commit --amend -m "New commit message"

e poi

git push --force

8
Nel mio caso git push origin <BRANCH-NAME>non ha funzionato, ho dovuto usare git push --forcecome spiegato nella risposta accettata.
Gabriel,

1
questo non funziona per me. ci devo git push --force, altrimenti la spinta non passa.
ahnbizcad,

4
@ahnbizcad, dovrebbe funzionare. Assicurati solo che il nome del ramo sia corretto.
William,

3
Faccio il tifo per la semplicità nella tua spiegazione! Lo uso più spesso
Vasikos

3
Ho applicato con successo questi comandi solo dopo aver temporaneamente "non protetto" il mio ramo, che è accaduto sul mio progetto ospitato da GitLab. Se hai questo problema, prima di applicare questi comandi, fai riferimento a questo stackoverflow.com/a/32267118/1423345 per "rimuovere la protezione" dal ramo e puoi "proteggerlo" dopo aver modificato il messaggio di commit :)
John

262

Per modificare un commit diverso dal più recente:

Step1 : git rebase -i HEAD~neseguire il rebase interattivo per gli ultimi ncommit interessati. (ad es. se si desidera modificare un messaggio di commit 3 esegue nuovamente il commit, fare git rebase -i HEAD~3)

git farà apparire un editor per gestire tali commit, nota questo comando:

#  r, reword = use commit, but edit the commit message

questo è esattamente ciò di cui abbiamo bisogno!

Passaggio 2 : passarepick a rper i commit a cui si desidera aggiornare il messaggio. Non preoccuparti di modificare il messaggio di commit qui, verrà ignorato. Lo farai al passaggio successivo. Salva e chiudi l'editor.

Nota che se modifichi il tuo 'piano' di rebase ma non inizia il processo che ti consente di rinominare i file, esegui:

git rebase --continue

Se si desidera modificare l'editor di testo utilizzato per la sessione interattiva (ad es. Da vi predefinito a nano), eseguire:

GIT_EDITOR=nano git rebase -i HEAD~n

Step3 : Git mostrerà un altro editor per ogni revisione che hai inserito rprima. Aggiorna il messaggio di commit come preferisci, quindi salva e chiudi l'editor.

Step4 : Dopo che tutti i commit sono stati aggiornati i msg. potresti voler fare git push -fper aggiornare il telecomando.


21
Questa dovrebbe essere una risposta accettata in quanto offre la possibilità di modificare altri commit rispetto al commit più recente, diversamente dalla risposta accettata. Mi hai salvato la giornata. Grazie!
xZero

1
Scegli n = 3 per gli ultimi 3 commit:git rebase -i HEAD~3
HeikoS

Se modifichi il tuo 'piano' di rebase, tuttavia non si avvia il processo che ti consente di rinominare i file, eseguilo git rebase --continue. E se si desidera modificare l'editor di testo utilizzato per la sessione interattiva (ad esempio, dal valore predefinito via nano), eseguire GIT_EDITOR=nano git rebase -i HEAD~n.
Jamie Birch,

L'ho modificato per aggiungere qualche informazione in più. Per favore dai un'occhiata. Questa era la risposta per quello che volevo fare, ma ho fatto scorrere lo schermo perché non aveva l'intestazione.
Kip

Ho fatto una modifica suggerita per inserire nella risposta l'utile commento di @JamieBirch, potrebbe essere utile rivederlo.
Notts90 supporta Monica il

44

Utilizzare questi due passaggi nella console:

git commit --amend -m "new commit message"

e poi

git push -f

Fatto :)


Grazie, questi passaggi sono solo per modificare l'ultimo commento o possono essere utilizzati anche per commenti più vecchi?
Jay,

@Jay mi dispiace per la risposta tardiva, questi passaggi solo per modificare l'ultimo messaggio di commit.
Abdul Rizwan,

19

Va notato che se si usano push --forcecon ref multipli, di conseguenza verranno TUTTI modificati. Assicurati di prestare attenzione a dove è configurato il tuo repository git. Fortunatamente esiste un modo per salvaguardare leggermente il processo, specificando un singolo ramo da aggiornare. Leggi dalle pagine man di git:

Si noti che --force si applica a tutti i ref che vengono inviati, quindi utilizzandolo con push.default impostato su matching o con destinazioni push multiple configurate con remote. *. Push può sovrascrivere ref diversi dal ramo corrente (inclusi ref locali che sono strettamente dietro la loro controparte remota). Per forzare una spinta verso un solo ramo, usa un + davanti al refspec per premere (ad es. Git push origin + master per forzare una spinta sul ramo master).


3
Nota molto importante
Peter - Ripristina Monica il

nessuna delle risposte forzate funziona per me, perché non ho autorizzazioni ForcePush sul server. Invece, voglio eseguire un commit che modifica un precedente messaggio di commit. Potrei scrivere "messaggio di commit modificato" nella sezione commenti di quel commit.
Nurettin,

11

Se si desidera modificare un vecchio commit, non l'ultimo, è necessario utilizzare rebaseil comando come spiegato qui, pagina di aiuto Github , sulla modifica del messaggio di età superiore o multipla messaggi di commit sezione


11

Comando 1 .

git commit --amend -m "New and correct message"

Poi,

Comando 2 .

git push origin --force

8
git commit --amend

quindi modifica e modifica il messaggio nella finestra corrente. Dopodiché

git push --force-with-lease

2

Un'altra opzione è quella di creare un ulteriore "commit errata" (e push) che faccia riferimento all'oggetto commit che contiene l'errore - il nuovo commit errata fornisce anche la correzione. Un commit errata è un commit senza modifiche sostanziali al codice ma un messaggio di commit importante - ad esempio, aggiungi un carattere spazio al tuo file readme e commetti quella modifica con il messaggio di commit importante oppure usa l'opzione git --allow-empty. È sicuramente più facile e sicuro della rigenerazione, non modifica la cronologia vera e mantiene pulito l'albero del ramo (usandoamendè anche una buona scelta se stai correggendo il commit più recente, ma un commit errata potrebbe essere una buona scelta per i commit più vecchi). Questo tipo di cose accade così raramente che semplicemente documentare l'errore è abbastanza buono. In futuro, se è necessario cercare un log git per una parola chiave della funzione, il commit originale (errato) potrebbe non essere visualizzato perché è stata utilizzata la parola chiave errata in quel commit originale (il refuso originale) - tuttavia, la parola chiave verrà visualizzata nel commit errata che ti indicherà il commit originale che aveva il refuso. Ecco un esempio:

$ git log
commit 0c28141c68adae276840f17ccd4766542c33cf1d
Autore: primo ultimo 
Data: mer 8 agosto 15:55:52 2018 -0600

    Commissione Errata:
    Questo commit non ha modifiche sostanziali al codice.
    Questo commit viene fornito solo per documentare una correzione a un precedente messaggio di commit.
    Questo riguarda l'oggetto di commit e083a7abd8deb5776cb304fa13731a4182a24be1
    Messaggio di commit errato originale:
        Il colore di sfondo è cambiato in rosso
    Correzione (* modifica evidenziata *):
        Colore dello sfondo modificato in * blu *

commit 032d0ff0601bff79bdef3c6f0a02ebfa061c4ad4
Autore: primo ultimo 
Data: mer 8 agosto 15:43:16 2018 -0600

    Qualche messaggio di commit temporaneo

commit e083a7abd8deb5776cb304fa13731a4182a24be1
Autore: primo ultimo 
Data: mer 8 agosto 13:31:32 2018 -0600

    Il colore di sfondo è cambiato in rosso

rob, questo sembra promettente. puoi mostrare i comandi necessari per eseguire un "errata commit". solo questo post appare in google a questi termini.
Jim

1
Un "commit errata" è semplicemente un commit normale con un messaggio che fa riferimento al precedente commit errato, documentando e fornendo una correzione per l'errore precedente. git commit -m “fixed feature A”(Supponiamo che git dia a questo un ID commit di e3ab7312 ... ... (in seguito ti rendi conto che il tuo messaggio era errato, quindi ora fai una modifica non significativa a un file come aggiungere uno spazio al file readme o usa l' —allow-emptyopzione git). .. git commit -m “Errata commit for previous commit e3ab7312... original message should have been ‘fixed feature *B*’'' '
rob_7cc

1
... se in seguito è necessario cercare nel registro git i riferimenti alla "caratteristica B", il commit errata verrà visualizzato, ma il messaggio di commit errata contiene un riferimento all'ID commit originale che fornisce la tracciabilità completa. A proposito, il termine "errata commit" non è niente di speciale (non esiste un comando "errata" né un'opzione in git) ... è solo la mia terminologia per un commit normale che fornisce una correzione a un commit precedente che aveva un errore / errore di battitura.
rob_7cc,

rob, ha funzionato benissimo. Sono stato in grado di aggiungere un nuovo commit vuoto con la descrizione corretta, che punta al commit originale, utilizzando SHA. ora, entrambi sono mostrati nella mia 'catena git' per i moduli. Grazie!
Jim,

Sono contento che abbia funzionato per te. Uso la stessa tecnica per correggere errori nei messaggi di commit. In alternativa, ho scoperto di recente che git notes questo avrebbe lo stesso scopo di un "errata commit". Aggiungi semplicemente una nota a un commit precedente per annotare o correggere eventuali errori nel messaggio di commit: https://git-scm.com/docs/git-notes
rob_7cc

0

Questo funziona per me abbastanza bene,

git checkout origine / nome filiale

se sei già nel ramo, allora è meglio fare pull o rebase

git pull

o

git -c core.quotepath=false fetch origin --progress --prune

Successivamente puoi semplicemente usare

git commit --amend -m "Your message here"

o se ti piace aprire l'editor di testo, allora usa

git commit --amend

Preferirò usare l'editor di testo se hai molti commenti. Puoi impostare il tuo editor di testo preferito con il comando

git config --global core.editor your_preffered_editor_here

Ad ogni modo, quando hai finito di cambiare il messaggio di commit, salvalo ed esci

e poi corri

git push --force

E hai finito


0

ulteriori informazioni per lo stesso problema se si utilizza la pipeline bitbucket

modifica il tuo messaggio

git commit --amend

spingere al server

git push --force <repository> <branch>

quindi aggiungere --force al comando push sulla pipeline

git ftp push --force

Questo eliminerà i tuoi precedenti commit e spingerà quelli attuali.

rimuovere --force dopo la prima spinta

l'ho provato sulla pipeline bitbucket e funziona benissimo

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.