Usando Git, ¿cómo podría buscar una cadena en todas las ramas?

170

Usando Git, ¿cómo podría buscar dentro de todos los archivos en todas las sucursales locales una cadena dada?

Específico de GitHub: ¿es posible realizar la búsqueda anterior en todas las ramas de GitHub? (Hay varias ramas remotas en mi repositorio remoto de GitHub que idealmente no tendría que bajar para esta búsqueda ...)

Ivar
fuente
1
git-grep podría ser lo que está buscando, pero no estoy seguro todavía qué opciones que había necesidad ...
Johnny

Respuestas:

170

Puedes hacer esto en un repositorio de Git:

git grep "string/regexp" $(git rev-list --all)

La búsqueda avanzada de GitHub tiene la capacidad de búsqueda de código:

La búsqueda de código revisará todo el código alojado públicamente en GitHub. También puedes filtrar por:

  • el idioma: language:
  • el nombre del repositorio (incluido el nombre de usuario): repo:
  • la ruta del archivo: path:
manojlds
fuente
Esto me causa una falla de segmentación. Sin embargo, podría ser tortoisegitmerge (Windows).
bean5
66
Esta no es realmente la mejor manera de hacer esto. No controla la cantidad de referencias de git a las que se pasa git grep .... Mira las otras respuestas, ¡son mucho mejores que esta aunque esté marcada como la respuesta aceptada!
slm
1
sería genial si pudiera agregar un ejemplo para sus filtros, por ejemplo path:, porque la documentación de un vistazo no parece clara dónde aplicar este filtro, ¿supongo que está antes de las comillas en su ejemplo de consulta?
blamb
3
¿Cómo puedo enumerar solo el nombre de la sucursal? Actualmente, enumera todo el hash que contiene la cadena.
harryfeng
44
Github búsqueda se centra en rama maestra única . De help.github.com/articles/searching-code : "Solo la rama predeterminada está indexada para la búsqueda de código. En la mayoría de los casos, esta será la rama maestra".
RedPanda
124

Si usa el comando @manojlds Git grep y obtiene un error:

-bash: /usr/bin/git: Argument list too long" 

entonces deberías usar xargs :

git rev-list --all | xargs git grep "string/regexp"

Consulte también Cómo codificar (buscar) el código comprometido en el historial de Git

quemadura
fuente
Además, esto parece ser más compatible con otro tipo de consolas como fishshell
Daniel
1
¡¡¡Gracias!!! usando ZSH y esto funcionó mientras que el comando @manojlds dio el error que mencionaste. Pero advertencia, esto puede llevar MUY mucho tiempo para un gran repositorio con una larga historia.
lacostenycoder
54

En muchos casos, git rev-list --allpuede devolver una gran cantidad de confirmaciones, tardando una eternidad en escanear. Si, en lugar de buscar a través de cada confirmación en cada rama en su historial de repositorio, solo desea buscar todos los consejos de la rama, puede reemplazarlo por git show-ref --heads. Entonces en total:

git grep "string" `git show-ref --heads`

o:

git show-ref --heads | xargs git grep "string"

Consejo: puede escribir la salida en el archivo para verla en un editor:

nano ~/history.txt
git show-ref --heads | xargs git grep "search string here" >> ~/history.txt
Zitrax
fuente
66
git show-ref --headsenumera el hash y el nombre de referencia para que (segunda línea) busque dos veces. así que git show-ref --heads | cut -d' ' -f2es mejor ya que solo enumerará los nombres de referencia.
FELIZ
44
No puedo creer cuántas veces se ha hecho y respondido esta pregunta, sin embargo, eres el único con la respuesta correcta .
Sammitch
1
git show-ref --heads -ssolo genera el hash SHA1. Además, si hay varias ramas que apuntan a la misma confirmación, tendrá duplicados. Puede eliminarlos con sort -u, como asígit show-ref --heads -s | sort -u | xargs git grep ...
Steve
Aquí está la función que agregué a mi bashrc. Espero que ayude a alguien:function gsearch { git grep $1 $(git show-ref --heads) | grep "refs/heads" | grep $1 } # last grep to keep grep color highlight
AFP_555
Esta debería ser la respuesta aceptada. Agrupar una cadena en todas las ramas pero solo para el contenido más reciente es un caso de uso muy común.
dr_
21

Hay algunos problemas con las soluciones enumeradas aquí (incluso aceptadas).

No necesita enumerar todos los hashes ya que obtendrá duplicados. Además, lleva más tiempo.

Se basa en esto, donde puede buscar una cadena "test -f /"en varias ramas mastery devcomo

git grep "test -f /" master dev

que es lo mismo que

printf "master\ndev" | xargs git grep "test -f /"

Entonces aquí va.

Esto encuentra los hash para la punta de todas las sucursales locales y busca solo en esas confirmaciones:

git branch -v --no-abbrev | awk -F' *' '{print $3}' | xargs git grep "string/regexp"

Si necesita buscar también en sucursales remotas, agregue -a:

git branch -a -v --no-abbrev | awk -F' *' '{print $3}' | xargs git grep "string/regexp"

Más lejos:

# Search in local branches
git branch | cut -c3- | xargs git grep "string"

# Search in remote branches
git branch -r | cut -c3- | xargs git grep "string"

# Search in all (local and remote) branches
git branch -a | cut -c3- | cut -d' ' -f 1 | xargs git grep "string"

# Search in branches, and tags
git show-ref | grep -v "refs/stash" | cut -d' ' -f2 | xargs git grep "string"
FELICIDAD
fuente
55
al menos para la búsqueda en todas las ramas debe ser: git branch -a | cut -c3- | cut -d' ' -f 1 | xargs git grep "string" o fallará con el ->símbolo en la lista de archivos, que denota la relación de las ramas locales a remotas
Ilya Sheershoff
7

Puedes probar esto:

git log -Sxxxx  # Search all commits
git log -Sxxxx  --branches[=<pattern>]   # Search branches
Victor Choy
fuente
1
En todas las ramas:git log --all -s"search_string"
Tim Kuipers