2010-02-11 5 views
328

Voglio cambiare qualcosa nel primo commit del mio progetto senza perdere tutti i commit successivi. C'è un modo per fare questo?Modifica il primo commit del progetto con Git?

Ho accidentalmente elencato la mia email non elaborata in un commento all'interno del codice sorgente, e vorrei modificarlo mentre ricevo spammato dai robot che indicizzano GitHub.

risposta

484

Come menzionato da ecdpalmabelow, git 1.7.12+ (Agosto 2012) ha migliorato l'opzione --root per git rebase:

"git rebase [-i] --root $tip" ora può essere utilizzato per riscrivere tutta la cronologia che porta a "$tip" fino al commit radice.

Questo nuovo comportamento è stato inizialmente discussed here:

Personalmente ritengo "git rebase -i --root" dovrebbe essere fatto per funzionare senza richiedere "--onto" e lasciare che "modifica", anche il primo nella storia.
È comprensibile che nessuno si sia preoccupato, poiché le persone si riscrivono molto meno spesso all'inizio della storia piuttosto che altrimenti.

patch followed.


(risposta originale, febbraio 2010)

Come menzionato nel Git FAQ (e questo SO question), l'idea è:

  1. Crea nuovo ramo temporaneo
  2. riavvolgerlo alla ti impegni a cambiare usando git reset --hard
  3. Cambia quel commit (sarebbe superiore al corrente HEAD, e tu puoi modificare il contenuto di qualsiasi file)
  4. ramo Rebase in cima cambiato impegnarsi, utilizzando:

    git rebase --onto <tmp branch> <commit after changed> <branch>` 
    

Il trucco è quello di essere che le informazioni che si desidera rimuovere non è reintrodotto da una successiva commettere da qualche altra parte nel tuo file. Se si sospetta che, quindi è necessario utilizzare filter-branch --tree-filter per assicurarsi che il contenuto di tale file non contenga in alcun commit le informazioni sensibili.

In entrambi i casi, si finisce per riscrivere lo SHA1 di ogni commit, quindi fare attenzione se si è già pubblicato il ramo di cui si sta modificando il contenuto.Probabilmente non dovresti farlo a meno che il tuo progetto non sia ancora pubblico e altre persone non abbiano basato il lavoro sui commit che stai per riscrivere.

+4

su OS X Mountain Lion con git installato il sistema-1.7.9.6 (Apple Git-31.1) I set '' per essere lo stesso hash che ho usato nel comando 'git reset --hard'. A parte questo piccolo cambiamento, questo funziona magnificamente per aggiornare le informazioni dell'autore su tutti i commit in un repository. – berto

+4

puoi fornire un esempio di cosa dovrebbe essere $ tip. 'git rebase -i --root' ha funzionato per me. –

+0

@ RémiBenoit yes, '$ tip' può essere qualsiasi commit desiderato. 'master' (che significa 'master HEAD' commit) va bene. – VonC

0

Se si desidera modificare solo la prima di impegnarsi, si può provare git rebase e modificare il commit, che è simile a questo post: How to modify a specified commit in git?

E se si desidera modificare tutti i commit che contengono le materie prime email, filter-branch è la scelta migliore. V'è un esempio di come cambiare l'indirizzo di posta elettronica a livello globale sul libro Pro Git, e si può trovare questo link utile http://git-scm.com/book/en/Git-Tools-Rewriting-History

71

git rebase -i consente di modificare comodamente qualsiasi commit precedente, ad eccezione del commit radice. I seguenti comandi mostrano come farlo manualmente.

# tag the old root, "git rev-list ..." will return the hash of first commit 
git tag root `git rev-list HEAD | tail -1` 

# switch to a new branch pointing at the first commit 
git checkout -b new-root root 

# make any edits and then commit them with: 
git commit --amend 

# check out the previous branch (i.e. master) 
git checkout @{-1} 

# replace old root with amended version 
git rebase --onto new-root root 

# you might encounter merge conflicts, fix any conflicts and continue with: 
# git rebase --continue 

# delete the branch "new-root" 
git branch -d new-root 

# delete the tag "root" 
git tag -d root 
+10

Ho seguito queste istruzioni come un n00b e hanno funzionato perfettamente - grazie! Potresti voler menzionare l'aggiunta di '-a' a' git commit --amend' o usando 'git add' perché l'ho dimenticato per la prima volta! –

+1

Questo non è più vero, si prega di fare riferimento alla risposta accettata –

+0

Grazie mille per la risposta. Sto usando un CentOS 7 e la versione git è 1.7.1 con molte limitazioni sui comandi. La risposta accettata non ha funzionato per me e questo _ ** come ** _ ha funzionato come un incantesimo per ricostruire la cronologia del repository da _ ** commit iniziale ** _ –

126

Come indicato nel 1.7.12 Release Notes, è possibile utilizzare

$ git rebase -i --root 
+2

git versione 1.7.9 si lamenta: 'È necessario specificare - -onto quando si usa --root' –

+2

Funziona perfettamente con git 1.9.4 –

+2

Ha funzionato magnificamente anche per me, usando git 1.9.4. –