2012-03-11 9 views
32

Diciamo che voglio per rinominare un metodo nel codice sorgente contenuto in un repository git. Potrei farlo a mano, ma il nome del metodo potrebbe essere in più punti (ad esempio, unit test, documentazione, metodo effettivo). Per controllare dove viene usato il metodo, io uso 'git grep'. I get 'git grep' per mostrare solo le linee che voglio cambiare, e quindi non ho un flusso di lavoro per cambiare automaticamente quelle linee.Esiste una "git sed" o equivalente?

Sto cercando un modo automatico (si spera utilizzando strumenti Git) per fare questo ultimo passo. Speravo che esistesse una sorta di "git sed" o equivalente, ma non ne trovo nessuno.

L'interfaccia Sto pensando che sarebbe bello: git sed 's /-metodo-vecchio nome-metodo-nome nuovo// g'

risposta

11

si potrebbe fare un bastone

for i in $(git grep --full-name -l old_method_name) 
do 
perl -p -i -e 's/old_method_name/new_method_name/g' $i 
done 

che in un file da qualche parte e poi alias come git sed nella propria configurazione.

Aggiornamento: Il commento di tchrist di seguito è una soluzione molto migliore in quanto impedisce ripetutamente al perl di spawnare.

+5

Sospetto che sia necessario un '$ i' lì alla fine del comando. Inoltre, non è necessario avviare Perl ripetutamente. Elabora tutti i file che gli vengono assegnati come argomento. Quindi 'perl -i.orig -pe 's \ \ bold_method_name \ b/new_method_name/g' $ (git grep --full-name -l vecchio_metodo_nome)' dovrebbe essere sufficiente. – tchrist

+0

Molto meglio. Ho corretto $ i nello snippet. –

+0

lo abbiamo inserito in git-extras: https://github.com/tj/git-extras/pull/466 – anarcat

42

Si potrebbe utilizzare in combinazione con git ls-filesxargs e sed:

git ls-files -z | xargs -0 sed -i -e 's/old-method-name/new-method-name/g' 
+0

Fantastico! Devo preoccuparmi degli spazi bianchi nei nomi dei file? –

+3

Sì. Se hai spazi bianchi nei nomi dei file, usa 'git ls-files -z | xargs -0 sed ... '. –

+1

Probabilmente ma penso che puoi passare -z a 'ls-files' e' -0' a xargs per farlo funzionare. –

15

grazie sia Noufal e Greg per i loro posti. Ho unito le loro soluzioni, e ha trovato uno che usa git grep (più robusto di git LS-files per il mio repo, come sembra per elencare solo i file che hanno il codice src effettivo in loro - non sottomodulo cartelle per esempio), e ha anche il vecchio nome del metodo e il nuovo nome del metodo in un solo posto:

nel [alias] blocco della mia ~/.gitconfig lima:

sed = ! git grep -z --full-name -l '.' | xargs -0 sed -i -e 

da usare:

git sed 's/old-method-name/new-method-name/ig' 
+1

Funziona su Linux, ma su OS X copia tutti i file nel repository e aggiunge '-e' a la fine di loro. Questo sembra funzionare meglio: 'git grep -z --full-name -l '.' | xargs -0 sed -i '' '. –

9

Ecco una soluzione che combina quelli di di Noufal e claytontstanley e evita di toccare file che non cambieranno.

Nel [alias] blocco del mio file ~/.gitconfig:

psed = !sh -c 'git grep --null --full-name --name-only --perl-regexp -e \"$1\" | xargs -0 perl -i -p -e \"s/$1/$2/g\"' - 

Per utilizzare:

git psed old_method_name new_method_name 
+0

posso anche usarlo per le sostituzioni generali, ad es. sostituzioni che includono spazi? –

+0

Sì, ma a seconda della shell potrebbe essere necessario regolare quante volte si cita gli argomenti. –

1

Nota che a partire git 2.1 (Q3 2014), è possibile impostare "full-name" per impostazione predefinita per git grep.
(Vedi commit 6453f7b da Andreas Schwab)

"git grep" imparato grep.fullname variabile di configurazione per forza "--full-name" per essere di default.
Ciò può causare regressioni sugli utenti script che non si aspettano questo nuovo comportamento.

Ciò significa che le soluzioni precedenti possono beneficiare di:

git config grep.full-name true 

E l'uso:

psed = !sh -c 'git grep --null --name-only --perl-regexp -e \"$1\" | xargs -0 perl -i -p -e \"s/$1/$2/g\"' - 
1

Sì, c'è. In Ubuntu il pacchetto git-extras fornisce il comando. Install it:

$ sudo apt-get install git-extras 

Usalo come muggito per es. per correggere un problema di ortografia rapidamente:

$ git sed 'qoute' 'quote' 

Purtroppo non supporta filtri di file come quello che grep git fa:

$ git grep -e 'class' -- '*.py' 

La stessa funzionalità esiste anche su altri sistemi operativi Mac e. Acquista il suo installation page.

Problemi correlati