2012-03-11 18 views
32

Digamos que quiero cambiar el nombre de un método en el código fuente contenido en un repositorio de git. Podría hacerlo a mano, pero el nombre del método podría estar en varios lugares (por ejemplo, prueba de unidad, documentación, método real). Para verificar dónde se usa el método, uso 'git grep'. Obtengo 'git grep' para mostrar solo las líneas que quiero cambiar, y luego no tengo un flujo de trabajo para cambiar automáticamente esas líneas.¿Hay un 'git sed' o equivalente?

Estoy buscando una forma automatizada (con suerte usando herramientas git) para hacer este último paso. Esperaba que hubiera algún tipo de 'git sed' o equivalente, pero no puedo encontrar ninguno.

La interfaz Estoy pensando que sería bueno: sed git 's/nombre-método-viejo-nuevo método de Nombre// g'

Respuesta

11

Usted podría hacer un palo

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 

que en un archivo en algún lugar y luego alias como git sed en su configuración.

Actualización: El comentario de tchrist a continuación es una solución mucho mejor ya que evita que el perl se reproduzca repetidamente.

+5

Sospecho que necesitas un '$ i' allí al final del comando. Además, no tiene que ejecutar Perl repetidamente. Procesará todos los archivos que le das como argumento. Así 'perl -i.orig -pe 's/\ bold_method_name \ b/new_method_name/g' $ (git grep --full-name -l old_method_name)' debería ser suficiente. – tchrist

+0

Mucho mejor. He arreglado $ i en el fragmento. –

+0

introdujo esto en git-extras: https://github.com/tj/git-extras/pull/466 – anarcat

42

Se puede usar en combinación con git ls-filesxargs y sed:

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

¡Impresionante! ¿Debo preocuparme por el espacio en blanco en los nombres de archivo? –

+3

Sí. Si tiene espacios en blanco en nombres de archivos, use 'git ls-files -z | xargs -0 sed ... '. –

+1

Probablemente, pero creo que puede pasar -z a 'ls-files' y' -0' a xargs para que funcione. –

15

Gracias a Noufal y Greg por sus publicaciones. Combiné sus soluciones y encontré una que usa git grep (más robusta que git ls-files para mi repositorio, ya que parece enumerar solo los archivos que tienen código src real en ellas -no carpetas de submódulos, por ejemplo), y también tiene el antiguo nombre del método y el nuevo nombre del método en un solo lugar:

en el bloque de mi ~/.gitconfig archivo [alias]:

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

Para usar:

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

Esto funciona en Linux, pero en OS X copia todos los archivos en el repositorio y agrega '-e' a el final de ellos. Esto parece funcionar mejor: 'git grep -z - nombre completo -l '.' | xargs -0 sed -i '' '. –

9

he aquí una solución que combina las de de Noufal y claytontstanley y evita tocar archivos que no cambiarán

En el bloque de mi archivo ~/.gitconfig[alias]:

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

de usar:

git psed old_method_name new_method_name 
+0

también puedo usar esto para sustituciones generales, p. sustituciones que incluyen espacios? –

+0

Sí, pero dependiendo de su caparazón puede que tenga que ajustar la cantidad de veces que cita los argumentos. –

1

cuenta que a partir git 2.1 (Q3 2014), se puede establecer "full-name" por defecto para git grep.
(Ver commit 6453f7b por Andreas Schwab)

"git grep" aprendidas grep.fullname variable de configuración a la fuerza "--full-name" ser predeterminado.
Esto puede causar regresiones en usuarios con script que no esperan este nuevo comportamiento.

Eso significa que las soluciones anteriores pueden beneficiarse de:

git config grep.full-name true 

y 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í, hay. En Ubuntu, el paquete git-extras proporciona el comando. Instálelo:

$ sudo apt-get install git-extras 

Utilícelo como bramido, p. Ej. para corregir un problema de la ortografía de forma rápida:

$ git sed 'qoute' 'quote' 

Por desgracia, no es compatible con filtros de archivos como lo hace grep git:

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

La misma funcionalidad también existe en Mac y otros sistemas operativos. Checkout es installation page.

Cuestiones relacionadas