2013-01-15 10 views
15

ho una abbastanza grande repository Git con 1000s di commit, originariamente importati da SVN. Prima di rendere pubblico il mio repo, vorrei ripulire alcune centinaia di messaggi di commit che non hanno senso nel mio nuovo repository, oltre a rimuovere tutto il testo informativo git-svn che è stato aggiunto.Qual è il modo più veloce per modificare centinaia di messaggi di commit Git?

So che posso usare 'git rebase -i' e quindi 'git commit --amend' per modificare ogni singolo messaggio di commit, ma con centinaia di messaggi da modificare, questo è un grande dolore per te -che cosa.

Esiste un modo più veloce per modificare tutti questi messaggi di commit? Idealmente avrei ogni messaggio di commit elencato in un singolo file in cui potrei modificarli tutti in un unico posto.

Grazie!

risposta

11

Questo è facile da fare come segue:

  • Eseguire prima importazione.
  • Export tutte le impegna in testo:

    git format-patch -10000 
    

    numero dovrebbe essere più di commit totali. Ciò creerà molti file denominati NNNNN-commit-description.patch.

  • modificare questi file utilizzando alcuni script. (Non toccare nulla in essi tranne che in alto con messaggi di commit).
  • copiare o spostare file modificati al repo git vuoto o ramo.
  • Importa tutti a cura commette indietro:

    git am *.patch 
    

Questo funziona solo con singolo ramo, ma funziona molto bene.

+0

sembra promettente, grazie! Sfortunatamente ricevo un errore "Numero file errato" durante l'esecuzione di "git am * .patch". Sono su Windows 7 e una rapida ricerca su Google sembra suggerire che è correlata al superamento del numero massimo di argomenti della riga di comando, il che ha senso dato che c'è un file di patch per ogni commit. Lo proverò sul mio Mac un po 'più tardi. –

+0

Puoi farlo in piccoli gruppi, assicurati solo che la sequenza aumenti di – mvp

+0

'ls * .patch | xargs git am' lo automatizza. – jthill

0

In alternativa, si consideri saltare l'importazione di tutta la repository. Vorrei semplicemente effettuare il checkout, pulire e impegnare punti importanti nella storia.

9

che è una vecchia questione, ma in quanto non v'è alcuna menzione di git filter-branch, ho solo aggiungere i miei due centesimi.

Recentemente ho dovuto rimpiazzare il testo nel messaggio di commit, sostituendo un blocco di testo con un altro senza modificare il resto dei messaggi di commit. Per esempio, ho dovuto sostituire Rif: #xxxxx con Rif .: # 22917.

Ho usato git filter-branch come questo

git filter-branch --msg-filter 'sed "s/Refs: #xxxxx/Refs: #22917/g"' master..my_branch 
  • ho usato l'opzione --msg-filter per modificare solo il messaggio di commit, ma è possibile utilizzare altri filtri per modificare i file, modificare piena commettere informazioni, ecc
  • I limitato filter-branch applicandolo solo ai commit che non erano nel master (master..my_branch) ma è possibile applicarlo all'intero ramo omettendo l'intervallo di commit.

Come suggerito nel documento, prova questo su una copia del tuo ramo. Spero che questo aiuti.


fonti utilizzate per la risposta

+1

--msg-filter option output invia un messaggio su STDOUT e prende il nuovo messaggio di commit su STDIN quindi è necessario utilizzare "sed" invece di "sed -i":

git filter-branch --msg-filter 'sed "s/Refs: #xxxxx/Refs: #22917/g"' master..my_branch

+1

@SimonDesfarges Hai assolutamente ragione! Non funziona, aggiorno subito la mia risposta –

1

È possibile utilizzare git rebase -i e sostituire pick con reword (o solo r). Quindi git rebasing si ferma su ogni commit dandoti la possibilità di modificare il messaggio.

Gli unici svantaggi sono che non si vedono tutti i messaggi contemporaneamente e che non si può tornare indietro quando si individua un errore.

+0

Questa non è la strada da percorrere. Aprire 1000 messaggi di commit uno alla volta richiede circa 8,5 ore per eseguirli tutti. Calcolando circa 30 secondi un messaggio – Whitecat

+0

@Whitecat ho frainteso la domanda in modo che tu voglia eseguire una pulizia manuale, ma tu vuoi qualcosa di automatizzato. Allora qual è il problema con 'git filter-branch' menzionato in [un'altra risposta] (http://stackoverflow.com/a/37941403/581205)? – maaartinus

+0

Sto riscontrando un problema con 'git filter-patch', mostra solo le patch e non i commit. Ho più di 6000 messaggi di commit che voglio cambiare. Ma quando faccio 'git filter-patch -100000 HEAD' ottengo solo 500 file di patch. – Whitecat

2

Un ottimo e semplice modo per farlo sarebbe utilizzare git filter-branch --msg-filter "" con uno script python.

lo script Python sarebbe simile a questa:

import os 
import sys 
import re 

pattern = re.compile("(?i)Issue-\d{1,4}") 


commit_id = os.environ["GIT_COMMIT"] 
message = sys.stdin.read() 

if len(message) > 0: 

    if pattern.search(message): 
     message = pattern_conn1.sub("Issue",message) 

print message 

La riga di comando chiamata si dovrebbe fare è git filter-branch -f --msg-filter "python /path/to/git-script.py"

Problemi correlati