Używając Git, jak mogę wyszukać ciąg znaków we wszystkich gałęziach?

170

Korzystając z Git, jak mogę przeszukiwać wszystkie pliki we wszystkich gałęziach lokalnych dla danego ciągu?

Specyficzne dla GitHub: czy można przeprowadzić powyższe wyszukiwanie we wszystkich oddziałach GitHub? (W moim zdalnym repozytorium GitHub jest kilka zdalnych oddziałów, których idealnie nie musiałbym opuszczać podczas tego wyszukiwania ...)

Ivar
źródło
1
git grep może być to, czego szukasz, ale nie jestem pewien, ale które opcje należałoby ...
Johnny

Odpowiedzi:

170

Możesz to zrobić w repozytorium Git:

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

Zaawansowane wyszukiwanie GitHub ma możliwość wyszukiwania kodu:

Wyszukiwanie kodu przejrzy cały kod publicznie hostowany na GitHub. Możesz też filtrować według:

  • język: language:
  • nazwa repozytorium (łącznie z nazwą użytkownika): repo:
  • ścieżka do pliku: path:
manojlds
źródło
To powoduje błąd segmentacji. Może to być jednak tortoisegitmerge (Windows).
fasola5
6
To naprawdę nie jest najlepszy sposób na zrobienie tego. Nie kontroluje ilości przekazywanych referencji git git grep .... Spójrz na inne odpowiedzi, są znacznie lepsze niż ta, mimo że jest oznaczona jako zaakceptowana!
slm
1
byłoby wspaniale, gdybyś mógł dodać przykład dla swoich filtrów, np. path:ponieważ dokumentacja na pierwszy rzut oka nie wygląda jasno, gdzie zastosować ten filtr, zakładam, że jest on przed cudzysłowami w przykładzie zapytania?
blamb
3
jak wyświetlić tylko nazwę oddziału. Obecnie wyświetla listę wszystkich skrótów zawierających ciąg.
harryfeng
4
Wyszukiwanie Github odbywa się tylko w gałęzi głównej . Z help.github.com/articles/searching-code : „W celu wyszukiwania kodu indeksowana jest tylko gałąź domyślna. W większości przypadków będzie to gałąź główna”.
RedPanda
124

Jeśli użyjesz polecenia @manojlds Git grep i pojawi się błąd:

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

wtedy powinieneś użyć xargs :

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

Zobacz także Jak grep (przeszukiwać) zatwierdzony kod w historii Git

Teastburn
źródło
Wydaje się również, że jest to bardziej kompatybilne z innymi rodzajami konsol, takimi jak fishshell
Daniel
1
Dzięki!!! używając ZSH i to działało, podczas gdy polecenie @manojlds spowodowało błąd, o którym wspomniałeś! Ale ostrzeżenie, może to zająć BARDZO dużo czasu w przypadku dużego repozytorium z długą historią.
lacostenycoder
54

W wielu przypadkach git rev-list --allmoże zwrócić ogromną liczbę zatwierdzeń, a skanowanie trwa wieczność. Jeśli zamiast przeszukiwać wszystkie zmiany w każdej gałęzi w historii repozytorium, chcesz po prostu przeszukać wszystkie wskazówki dotyczące gałęzi, możesz je zastąpić git show-ref --heads. Więc w sumie:

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

lub:

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

Porada: Możesz zapisać dane wyjściowe w pliku, aby wyświetlić je w edytorze:

nano ~/history.txt
git show-ref --heads | xargs git grep "search string here" >> ~/history.txt
Zitrax
źródło
6
git show-ref --headswyświetla hash i nazwę odniesienia, więc (druga linia) przeszuka dwukrotnie. więc git show-ref --heads | cut -d' ' -f2jest lepsze, ponieważ wyświetli tylko nazwy referencyjne.
hIpPy
4
Nie mogę uwierzyć, ile razy zadawano to pytanie i odpowiadano na nie, ale tylko Ty masz poprawną odpowiedź.
Sammitch
1
git show-ref --heads -swyświetla tylko skrót SHA1. Ponadto, jeśli istnieje wiele gałęzi wskazujących na to samo zatwierdzenie, będziesz mieć duplikaty. Możesz je usunąć sort -u, na przykładgit show-ref --heads -s | sort -u | xargs git grep ...
Steve
Oto funkcja, którą dodałem do mojego bashrc. Mam nadzieję, że to komuś pomoże:function gsearch { git grep $1 $(git show-ref --heads) | grep "refs/heads" | grep $1 } # last grep to keep grep color highlight
AFP_555
To powinna być akceptowana odpowiedź. Grepowanie łańcucha we wszystkich gałęziach, ale tylko w przypadku najnowszej zawartości, jest bardzo częstym przypadkiem użycia.
dr_,
21

Istnieje kilka problemów z rozwiązaniami wymienionymi tutaj (nawet zaakceptowanymi).

Nie musisz wymieniać wszystkich skrótów, ponieważ otrzymasz duplikaty. Ponadto zajmuje to więcej czasu.

Opiera się na tym, gdzie można wyszukiwać ciąg "test -f /"w wielu gałęziach masteri devjako

git grep "test -f /" master dev

który jest taki sam jak

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

Więc oto idzie.

Znajduje skróty końcówek wszystkich lokalnych oddziałów i wyszukuje tylko w tych zatwierdzeniach:

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

Jeśli chcesz szukać również w zdalnych oddziałach, dodaj -a:

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

Dalej:

# 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"
hIpPy
źródło
5
przynajmniej dla wyszukiwania we wszystkich gałęziach powinno być: git branch -a | cut -c3- | cut -d' ' -f 1 | xargs git grep "string" lub zakończy się niepowodzeniem z ->symbolem na liście plików, co oznacza relację oddziałów lokalnych do zdalnych
Ilya Sheershoff
7

Możesz spróbować tego:

git log -Sxxxx  # Search all commits
git log -Sxxxx  --branches[=<pattern>]   # Search branches
Victor Choy
źródło
1
We wszystkich oddziałach:git log --all -s"search_string"
Tim Kuipers