Modifica il commit di root in Git?


328

Esistono modi per modificare il messaggio da commit successivi:

git commit --amend                    # for the most recent commit
git rebase --interactive master~2     # but requires *parent*

Come puoi modificare il messaggio di commit del primo commit (che non ha un genitore)?



In particolare: l'uso della variabile d'ambiente GIT_COMMIT nello script digit filter-branch --msg-filter
fork0

Risposte:


284

Supponendo di avere un albero di lavoro pulito, è possibile effettuare le seguenti operazioni.

# checkout the root commit
git checkout <sha1-of-root>

# amend the commit
git commit --amend

# rebase all the other commits in master onto the amended root
git rebase --onto HEAD HEAD master

23
Credo che dovrebbe essere git rebase --onto HEAD <sha1-of-root> master.
Andrew,

5
Giusto, ma vuoi il commit root originale per <upstream> di git rebase. git rebaseapplica i commit in <branch> ( master) che non sono in <upstream>; HEADnon è presente master, quindi la tua versione tenta di applicare tutti master.
Andrew,

7
Sì, assicurati che sia git rebase --onto HEAD <sha1-of-root>master, dove <sha1-of-root>è utilizzato lo stesso git checkout <sha1-of-root>. Altrimenti, avrai 2 first commit.
Andy,

2
@Cupcake: hai provato la vecchia versione del comando? Dovrebbe funzionare bene. La modifica sta cambiando il messaggio di commit solo in modo che i commit di root vecchi e nuovi introducano esattamente le stesse modifiche in modo che il vecchio commit di root venga saltato automaticamente. Il secondo HEADassicura che tutti i commit siano considerati e che possiamo usare la versione a due parametri di rebase per tornare al master. Si noti che questa risposta precede l'esistenza --rootdell'opzione di rebase.
CB Bailey,

9
La risposta di ecdpalma di seguito è molto più facile e semplice e ha più voti, scorri verso il basso le persone!
Flimm,

567

A partire dalla versione 1.7.12 di Git , ora puoi usare

git rebase -i --root

Documentazione


2
è possibile rifare la radice di tutti i rami usando questo comando? Sembra che questo staccherà il ramo corrente sulla nuova radice e tutti gli altri rami rimarranno sulla vecchia radice
woojoo666

@ woojoo666 allora dovrai rifare i rami su una nuova radice. come di solito.
berkus,

@Antcold non funziona se non c'è root a monte
Kai

Avvertenza: ho erroneamente supposto che questo avrebbe fatto la radice del mio ramo estratto, ma ci vuole un po 'di tempo per caricare tutti i commit, quindi rimetterli tutti.
Leone,

2
@Leo cosa significa il tuo commento? Non riesco a vedere il collegamento tra la prima parte e la seconda: cosa c'entra un po 'con esso?
boicottaggio

66

Per espandere la risposta di ecdpalma , ora puoi usare l' --rootopzione per dire rebaseche vuoi riscrivere il root / primo commit:

git rebase --interactive --root

Quindi il commit di root apparirà nell'elenco TODO rebase e puoi scegliere di modificarlo o riformularlo:

reword <root commit sha> <original message>
pick <other commit sha> <message>
...

Questa è la spiegazione --rootda docs Git REBASE (sottolineatura mia):

Sostituisci tutti i commit raggiungibili da <branch>, invece di limitarli con un <upstream>. Ciò consente di modificare il commit dei commit di root su un ramo .


12

Solo per fornire un'alternativa alle risposte più votate:

Se stai creando un repository e sai in anticipo che in futuro ti rifarai in cima al suo "primo" vero commit, puoi evitare del tutto questo problema facendo un commit vuoto esplicito all'inizio:

git commit --allow-empty -m "Initial commit"

e solo allora inizia a fare commit "reali". Quindi puoi facilmente rifare la parte superiore di questo commit nel modo standard, ad esempiogit rebase -i HEAD^


4
Questo non significa che, affinché questo funzioni, devi avere la lungimiranza (o essere psichico) per fare un impegno vuoto proprio all'inizio del tuo progetto ? Questo sembra essere estremamente situazionale , per me, e generalmente non pratico . Cosa ne pensi? Cosa succede se ho già effettuato 100 commit e improvvisamente ho bisogno di modificare il commit root. Funzionerà comunque, in quel caso, se non avessi fatto quel commit vuoto all'inizio?

2
La modifica del messaggio del commit root probabilmente non è qualcosa che faresti dopo averne centinaia. A volte mi viene solo voglia di avere un repository git, fare alcuni commit trash, sapendo che una volta raggiunto uno stato utilizzabile, li schiaccerei in uno per esempio, e riscrivo il messaggio. Comunque, ora ho cambiato idea e penso che la cosa assolutamente più utile per il primo commit sarebbe mettere .gitattributesfile invece di fare un commit vuoto.
jakub.g,

4

Puoi usare git filter-branch:

cd test
git init

touch initial
git add -A
git commit -m "Initial commit"

touch a
git add -A
git commit -m "a"

touch b
git add -A
git commit -m "b"

git log

-->
8e6b49e... b
945e92a... a
72fc158... Initial commit

git filter-branch --msg-filter \
"sed \"s|^Initial commit|New initial commit|g\"" -- --all

git log
-->
c5988ea... b
e0331fd... a
51995f1... New initial commit

Sto usando il filtro-ramo per cambiare l'autore / committer, e in -- --alleffetti l' opzione è la chiave in questo caso per essere in grado di gestire anche il commit root.
sschuberth
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.