2011-08-22 6 views
85

Używając git, jak mogę wyszukać we wszystkich plikach we wszystkich lokalnych oddziałach dla danego ciągu znaków?Używając git, jak mogę wyszukać ciąg we wszystkich gałęziach?

Github specific: czy można wykonać powyższe wyszukiwanie we wszystkich gałęziach Github? (Istnieje kilka zdalnych oddziałów na moim zdalnego github repo że idealnie bym nie obniżyć dla tego wyszukiwania ..)

+1

[git-grep] (http://www.kernel.org/pub/software/scm/git/docs/git-grep.html) może być tym, czego szukasz, ale nie jestem jeszcze pewien, który opcje, których potrzebujesz ... – johnny

+0

Możliwy duplikat [Jak grep (szukaj) popełniony kod w historii git?] (https://stackoverflow.com/questions/2928584/how-to-grep-search-committed- code-in-the-git-history) – nekketsuuu

Odpowiedz

94

Można to zrobić na Git repo:

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

Github szukanie zaawansowane ma funkcję wyszukiwania kodu:

Wyszukiwanie kodu obejrzy cały kod publicznie hostowany na GitHub. Można także filtrować według:

  • język: language:
  • nazwę repozytorium (łącznie z nazwą użytkownika): repo:
  • ścieżka pliku: path:
+0

Powoduje to u mnie błąd segmentacji. Może jednak być tortoisegitmerge (Windows). – bean5

+1

To naprawdę nie jest najlepszy sposób na zrobienie tego. Nie kontroluje ona ilości git refs, które są przekazywane do 'git grep ...'. Spójrz na inne odpowiedzi, są one znacznie lepsze od tego, nawet jeśli jest to zaakceptowana odpowiedź! – slm

+0

Byłoby wspaniale, gdybyś mógł dodać przykład swoich filtrów, np. 'ścieżka:', ponieważ dokumentacja na pierwszy rzut oka nie wyjaśnia, gdzie zastosować ten filtr, zakładając, że jest on przed cytatami w przykładzie zapytania? – blamb

61

Jeśli używasz @manojlds git grep polecenie i błąd:

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

to powinieneś se xargs:

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

zobaczyć również How to grep (search) committed code in the git history?

+0

Ponadto, wydaje się być bardziej kompatybilny z konsolami innego rodzaju, takimi jak fishshell – Daniel

+0

Dzięki! używając ZSH i działało to, gdy polecenie @manojlds podało błąd, o którym wspomniałeś! Ale ostrzeżenie to może zająć BARDZO dużo czasu na duże repozytorium z długą historią. – lacostenycoder

22

W wielu przypadkach git rev-list --all może powrócić ogromną liczbę zatwierdzeń biorących zawsze skanować. Jeśli zamiast przeszukiwać każde zatwierdzenie w każdym oddziale w historii repozytorium, wystarczy przeszukać wszystkie porady oddziału, można 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" 

wskazówka: Można pisać wyjście w pliku do wyświetlenia w edytorze.

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

'git show-ref -heads' wylicza hash i nazwę ref, więc (druga linia) wyszuka dwa razy. więc 'git show-ref - główki | cut -d '' -f2' jest lepszy, ponieważ wyświetla listę tylko nazw ref. – hIpPy

+1

Nie mogę uwierzyć, ile razy to pytanie zostało zadane i na które odpowiedziałeś, ale jesteś jedyny z * poprawną * odpowiedzią. – Sammitch

+0

'git show-ref -heads -s' wypisuje tylko skrót SHA1. Ponadto, jeśli istnieje wiele gałęzi wskazujących na ten sam commit, będziesz mieć duplikaty. Możesz je usunąć za pomocą 'sort -u', tak jak w przypadku' git show-ref - heads -s | sort -u | xargs git grep ... ' – Steve

6

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

  1. Nie musisz wyświetlać wszystkich skrótów, ponieważ otrzymasz duplikaty, a także zajmuje więcej czasu.

Opiera się ona na to, gdzie można wyszukać ciąg "test -f /" na wielu oddziałach master i dev jak

git grep "test -f /" master dev 

która jest taka sama jak

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

Więc tu idzie.

Znajduje to hashy na końcu wszystkich lokalnych oddziałów i wyszukuje tylko te zatwierdzenia.

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

Jeśli trzeba szukać w odległych oddziałach zbyt następnie dodać -a:

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

Aktualizacja:

# 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- | xargs git grep "string" 

# search in branches, and tags 
git show-ref | grep -v "refs/stash" | cut -d' ' -f2 | xargs git grep "string" 
+1

przynajmniej dla wyszukiwania we wszystkich oddziałach powinno być: ' git branch -a | cut -c3- | cut -d '' -f 1 | xargs git grep "string" ' lub nie powiedzie się z symbolem' -> 'na liście plików, co oznacza relacje lokalne do odległych gałęzi –

0

Można spróbować tej

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