Usando Git, come potrei cercare una stringa tra tutti i rami?


170

Usando Git, come posso cercare una data stringa in tutti i file in tutti i rami locali?

Specifico per GitHub: è possibile eseguire la ricerca di cui sopra su tutti i rami di GitHub? (Esistono diversi rami remoti sul mio repository GitHub remoto che idealmente non dovrei abbattere per questa ricerca ...)


1
git-grep potrebbe essere quello che stai cercando, ma non sono ancora sicuro di quali opzioni avresti bisogno ...
johnny

Risposte:


170

Puoi farlo su un repository Git:

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

La ricerca avanzata di GitHub ha funzionalità di ricerca del codice:

La ricerca del codice esaminerà tutto il codice ospitato pubblicamente su GitHub. Puoi anche filtrare per:

  • la lingua: language:
  • il nome del repository (incluso il nome utente): repo:
  • il percorso del file: path:

Questo mi provoca un errore di segmentazione. Potrebbe essere tortoisegitmerge (Windows), però.
bean5

6
Questo non è davvero il modo migliore per farlo. Non controlla la quantità di riferimenti git a cui viene passato git grep .... Guarda le altre risposte, sono molto meglio di questa anche se è contrassegnata come risposta accettata!
slm

1
sarebbe bello se puoi aggiungere un esempio per i tuoi filtri, ad es path:. perché la documentazione a colpo d'occhio non sembra chiara dove applicare questo filtro, supponendo che sia prima delle virgolette nel tuo esempio di query?
blamb

3
come posso elencare solo il nome del ramo. Attualmente, elenca tutti gli hash che contengono la stringa.
harryfeng,

4
Github ricerca è sul ramo maestro unico . Da help.github.com/articles/searching-code : "Solo il ramo predefinito è indicizzato per la ricerca del codice. Nella maggior parte dei casi, questo sarà il ramo principale."
RedPanda,

124

Se si utilizza il comando Git grep di @manojlds e si ottiene un errore:

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

allora dovresti usare xargs :

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

Vedi anche Come eseguire il grep (ricerca) del codice di commit nella cronologia di Git


Inoltre, questo sembra essere più compatibile con altri tipi di console come il guscio di pesce
Daniel

1
Grazie!!! usando ZSH e questo ha funzionato mentre il comando @manojlds ha dato l'errore che hai citato! Ma attenzione, questo può richiedere MOLTO tempo per un repository di grandi dimensioni con una lunga storia.
lacostenycoder,

54

In molti casi git rev-list --allpuò restituire un numero enorme di commit, impiegando un'eternità a scansionare. Se invece di cercare tutti i commit su ogni ramo nella cronologia del repository, vuoi solo cercare tutti i suggerimenti sui rami, puoi sostituirlo con git show-ref --heads. Quindi in totale:

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

o:

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

Suggerimento: è possibile scrivere l'output nel file per visualizzarlo in un editor:

nano ~/history.txt
git show-ref --heads | xargs git grep "search string here" >> ~/history.txt

6
git show-ref --headselenca l'hash e il nome ref in modo che (2a riga) cercherà due volte. quindi git show-ref --heads | cut -d' ' -f2è meglio in quanto elencherà solo i nomi di riferimento.
hIpPy

4
Non riesco a credere quante volte questa domanda è stata posta e risposta, eppure sei l'unico con la risposta corretta .
Sammitch,

1
git show-ref --heads -sgenera solo l'hash SHA1. Inoltre, se ci sono più rami che puntano allo stesso commit, avrai duplicati. Puoi rimuoverli con sort -u, in questo modogit show-ref --heads -s | sort -u | xargs git grep ...
Steve

Ecco la funzione che ho aggiunto al mio bashrc. Spero che aiuti qualcuno:function gsearch { git grep $1 $(git show-ref --heads) | grep "refs/heads" | grep $1 } # last grep to keep grep color highlight
AFP_555,

Questa dovrebbe essere la risposta accettata. Far passare una stringa su tutti i rami ma solo per il contenuto più recente è un caso d'uso molto comune.
dr_11

21

Ci sono alcuni problemi con le soluzioni elencate qui (anche accettate).

Non è necessario elencare tutti gli hash poiché otterrai duplicati. Inoltre, ci vuole più tempo.

Si basa su questo dove è possibile cercare una stringa "test -f /"su più rami mastere devcome

git grep "test -f /" master dev

che è lo stesso di

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

Quindi ecco qui.

Questo trova gli hash per la punta di tutte le filiali locali e cerca solo in quei commit:

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

Se devi cercare anche in filiali remote, aggiungi -a:

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

Ulteriore:

# 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"

5
almeno per la ricerca in tutti i rami dovrebbe essere: git branch -a | cut -c3- | cut -d' ' -f 1 | xargs git grep "string" o fallirà con il ->simbolo nell'elenco dei file, che indica la relazione tra rami locali e remoti
Ilya Sheershoff

7

Puoi provare questo:

git log -Sxxxx  # Search all commits
git log -Sxxxx  --branches[=<pattern>]   # Search branches

1
In tutte le filiali:git log --all -s"search_string"
Tim Kuipers,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.