Wie kann ich mit Git in allen Zweigen nach einer Zeichenfolge suchen?

170

Wie kann ich mit Git in allen Dateien in allen lokalen Zweigen nach einer bestimmten Zeichenfolge suchen?

GitHub-spezifisch: Ist es möglich, die obige Suche in allen GitHub-Zweigen durchzuführen? (Es gibt mehrere Remote-Zweige in meinem Remote-GitHub-Repository, die ich im Idealfall für diese Suche nicht herunterfahren müsste ...)

Ivar
quelle
1
Git-Grep könnte das sein, wonach Sie suchen, aber ich bin mir noch nicht sicher, welche Optionen Sie benötigen würden ...
Johnny

Antworten:

170

Sie können dies in einem Git-Repository tun:

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

Die erweiterte GitHub-Suche bietet Code-Suchfunktionen:

Bei der Codesuche wird der gesamte auf GitHub öffentlich gehostete Code durchsucht. Sie können auch filtern nach:

  • die Sprache: language:
  • den Repository-Namen (einschließlich des Benutzernamens): repo:
  • der Dateipfad: path:
Manojlds
quelle
Dies führt zu einem Segmentierungsfehler. Könnte aber Tortoisegitmerge (Windows) sein.
bean5
6
Dies ist wirklich nicht der beste Weg, dies zu tun. Es steuert nicht die Anzahl der Git-Refs, an die übergeben wird git grep .... Schauen Sie sich die anderen Antworten an, sie sind weitaus besser als diese, obwohl sie als akzeptierte Antwort markiert sind!
Slm
1
Es wäre großartig, wenn Sie ein Beispiel für Ihre Filter hinzufügen könnten, z. B. path:weil die Dokumentation auf einen Blick nicht klar ist, wo dieser Filter angewendet werden soll. Ich gehe davon aus, dass er vor den Anführungszeichen in Ihrem Abfragebeispiel steht.
Blamb
3
Wie kann ich nur den Filialnamen auflisten? Derzeit wird der gesamte Hash aufgelistet, der die Zeichenfolge enthält.
Harryfeng
4
Github - Suche ist auf Master - Zweig nur . Von help.github.com/articles/searching-code : "Für die Codesuche wird nur der Standardzweig indiziert. In den meisten Fällen ist dies der Hauptzweig."
RedPanda
124

Wenn Sie den Befehl @manojlds Git grep verwenden und eine Fehlermeldung erhalten:

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

dann solltest du xargs verwenden :

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

Siehe auch So suchen Sie nach festgeschriebenem Code im Git-Verlauf

Teastburn
quelle
Dies scheint auch besser mit anderen Arten von Konsolen wie Fishshell kompatibel zu sein
Daniel
1
Vielen Dank!!! mit ZSH und dies funktionierte, während der Befehl @manojlds den von Ihnen erwähnten Fehler gab! Aber Warnung, dies kann für ein großes Repo mit einer langen Geschichte SEHR lange dauern.
Lacostenycoder
54

In vielen Fällen git rev-list --allkann eine große Anzahl von Commits zurückgegeben werden, deren Scan ewig dauert. Wenn Sie nicht jedes Commit für jeden Zweig in Ihrem Repository-Verlauf durchsuchen möchten, sondern nur alle Zweigstellentipps durchsuchen möchten, können Sie ihn durch ersetzen git show-ref --heads. Also insgesamt:

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

oder:

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

Tipp: Sie können eine Ausgabe in eine Datei schreiben, um sie in einem Editor anzuzeigen:

nano ~/history.txt
git show-ref --heads | xargs git grep "search string here" >> ~/history.txt
Zitrax
quelle
6
git show-ref --headslistet den Hash und den Ref-Namen auf, damit er (2. Zeile) zweimal sucht. Dies git show-ref --heads | cut -d' ' -f2ist besser, da nur die Ref-Namen aufgelistet werden.
HPPy
4
Ich kann nicht glauben, wie oft diese Frage gestellt und beantwortet wurde, aber Sie sind der einzige mit der richtigen Antwort.
Sammitch
1
git show-ref --heads -sgibt nur den SHA1-Hash aus. Wenn mehrere Zweige auf dasselbe Commit verweisen, werden Duplikate angezeigt. Sie können sie mit entfernen sort -u, wie sogit show-ref --heads -s | sort -u | xargs git grep ...
Steve
Hier ist die Funktion, die ich meinem Bashrc hinzugefügt habe. Hoffe es hilft jemandem:function gsearch { git grep $1 $(git show-ref --heads) | grep "refs/heads" | grep $1 } # last grep to keep grep color highlight
AFP_555
Dies sollte die akzeptierte Antwort sein. Das Greifen einer Zeichenfolge über alle Zweige hinweg, jedoch nur für den neuesten Inhalt, ist ein sehr häufiger Anwendungsfall.
dr_
21

Es gibt einige Probleme mit den hier aufgeführten Lösungen (sogar akzeptiert).

Sie müssen nicht alle Hashes auflisten, da Sie Duplikate erhalten. Außerdem dauert es länger.

Darauf aufbauend können Sie eine Zeichenfolge "test -f /"in mehreren Zweigen masterund devals suchen

git grep "test -f /" master dev

das ist das gleiche wie

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

Also los geht's.

Dies findet die Hashes für die Spitze aller lokalen Zweige und sucht nur in diesen Commits:

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

Wenn Sie auch in Remote-Filialen suchen müssen, fügen Sie Folgendes hinzu -a:

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

Des Weiteren:

# 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
quelle
5
Zumindest für die Suche in allen Zweigen sollte sein: git branch -a | cut -c3- | cut -d' ' -f 1 | xargs git grep "string" oder es wird mit ->Symbol in der
Dateiliste
7

Sie können dies versuchen:

git log -Sxxxx  # Search all commits
git log -Sxxxx  --branches[=<pattern>]   # Search branches
Victor Choy
quelle
1
Über alle Branchen hinweg:git log --all -s"search_string"
Tim Kuipers