Ist es möglich, git grep
in allen Zweigen eines Git-Steuerungsprojekts zu laufen ? Oder gibt es einen anderen Befehl zum Ausführen?
Ist es möglich, git grep
in allen Zweigen eines Git-Steuerungsprojekts zu laufen ? Oder gibt es einen anderen Befehl zum Ausführen?
Antworten:
Die Frage " Wie kann man festgeschriebenen Code in der Git-Historie durchsuchen? " Empfiehlt:
git grep <regexp> $(git rev-list --all)
Das durchsucht alle Commits, die alle Zweige enthalten sollten.
Eine andere Form wäre:
git rev-list --all | (
while read revision; do
git grep -F 'yourWord' $revision
done
)
Weitere Beispiele finden Sie in diesem Artikel :
Ich habe das oben genannte bei einem Projekt ausprobiert, das groß genug ist, dass sich git über die Argumentgröße beschwert. Wenn Sie also auf dieses Problem stoßen, gehen Sie wie folgt vor:
git rev-list --all | (while read rev; do git grep -e <regexp> $rev; done)
(Siehe eine Alternative im letzten Abschnitt dieser Antwort unten)
Vergessen Sie diese Einstellungen nicht, wenn Sie sie möchten:
# Allow Extended Regular Expressions
git config --global grep.extendRegexp true
# Always Include Line Numbers
git config --global grep.lineNumber true
Dieser Alias kann auch helfen:
git config --global alias.g "grep --break --heading --line-number"
Hinweis: Chernjie schlug vor, dass dies git rev-list --all
ein Overkill ist.
Ein verfeinerter Befehl kann sein:
git branch -a | tr -d \* | xargs git grep <regexp>
Damit können Sie nur Zweige durchsuchen (einschließlich entfernter Zweige).
Sie können sogar einen Bash / Zsh-Alias dafür erstellen:
alias grep_all="git branch -a | tr -d \* | xargs git grep"
grep_all <regexp>
Update August 2016: RM empfiehlt in den Kommentaren
Ich habe ein "
fatal: bad flag '->' used after filename
" bekommen, als ich diegit branch
Version ausprobiert habe . Der Fehler war mit einerHEAD
Aliasing-Notation verbunden.Ich habe es gelöst, indem ich ein
sed '/->/d'
in die Pipe zwischen demtr
und demxargs
Befehl eingefügt habe.
git branch -a | tr -d \* | sed '/->/d' | xargs git grep <regexp>
Das ist:
alias grep_all="git branch -a | tr -d \* | sed '/->/d' | xargs git grep"
grep_all <regexp>
git branch
in tr oder sed zu leiten. git branch
ist ein Porzellankommando für den menschlichen Verzehr. Bevorzugte Alternativen finden Sie unter stackoverflow.com/a/3847586/2562319 .
git log
Dies kann eine effektivere Methode sein, um in allen Zweigen nach Text zu suchen, insbesondere wenn es viele Übereinstimmungen gibt und Sie zuerst neuere (relevante) Änderungen sehen möchten.
git log -p --all -S 'search string'
git log -p --all -G 'match regular expression'
Diese Protokollbefehle listen Commits auf, mit denen die angegebene Suchzeichenfolge / Regex (im Allgemeinen) zuerst hinzugefügt oder entfernt wird. Die -p
Option bewirkt, dass das relevante Diff dort angezeigt wird, wo das Muster hinzugefügt oder entfernt wurde, sodass Sie es im Kontext sehen können.
Nachdem Sie ein relevantes Commit gefunden haben, das den gesuchten Text hinzufügt (z. B. 8beeff00d), suchen Sie die Zweige, die das Commit enthalten:
git branch -a --contains 8beeff00d
Ich fand das am nützlichsten:
git grep -i foo `git for-each-ref --format='%(refname)' refs/`
Sie müssen die letzten Argumente anpassen, je nachdem, ob Sie nur entfernte oder lokale Zweige betrachten möchten, dh:
git grep -i foo $(git for-each-ref --format='%(refname)' refs/remotes)
git grep -i foo $(git for-each-ref --format='%(refname)' refs/heads)
Der von mir erstellte Alias sieht folgendermaßen aus:
grep-refs = !sh -c 'git grep "$0" "$@" "$(git for-each-ref --format=\"%(refname)\"" refs/)'
git for-each-ref
mit aktualisiert --sort=-committerdate --count=100
! Danke für die ursprüngliche Idee!
Es gibt zwei Möglichkeiten: Bash- oder Git-Aliase
Hier sind drei Befehle:
git grep-branch
- Suche in allen Filialen lokal & remotegit grep-branch-local
- Suche nur in lokalen Filialengit grep-branch-remote
- Nur entfernte ZweigeDie Verwendung ist die gleiche wie git grep
git grep-branch "find my text"
git grep-branch --some-grep-options "find my text"
Befehle sollten manuell zur ~/.gitconfig
Datei hinzugefügt werden , da git config --global alias
Sie den von Ihnen hinzugefügten komplexen Code auswerten und durcheinander bringen.
[alias]
grep-branch = "!f(){ git branch -a | sed -e 's/[ \\*]*//' | grep -v -e '\\->' | xargs git grep $@; };f "
grep-branch-remote = "!f(){ git branch -a | sed -e 's/[ \\*]*//' | grep -v -e '\\->' | grep '^remotes' | xargs git grep $@; };f"
grep-branch-local = "!f(){ git branch -a | sed -e 's/[ \\*]*//' | grep -v -e '\\->' -e '^remotes' | xargs git grep $@; };f "
Hinweis: Wenn Sie Aliase hinzufügen und diese nicht ausgeführt werden können - überprüfen Sie die Backslashes \
, für die \\
im Vergleich zu Bash- Befehlen möglicherweise ein zusätzliches Escape erforderlich ist .
git branch -a
- Alle Zweige anzeigen;sed -e 's/[ \\*]*//'
- Trim Leerzeichen (von branch -a
) und * (Name des aktiven Zweigs haben es);grep -v -e '\\->'
- Ignorieren Sie komplexe Namen wie remotes/origin/HEAD -> origin/master
;grep '^remotes'
- Holen Sie sich alle Remote-Filialen;grep -v -e '^remotes'
- Holen Sie sich Filialen außer Remote-Filialen;git grep-branch-local -n getTastyCookies
-n
Stellen Sie die Zeilennummer den übereinstimmenden Zeilen voran.
[user@pc project]$ git grep-branch-local -n getTastyCookies
dev:53:modules/factory/getters.php:function getTastyCookies($user);
master:50:modules/factory/getters.php:function getTastyCookies($user)
Die aktuelle Struktur ist:
:
- Trennzeichen
dev
53
modules/factory/getters.php
function getTastyCookies($user)
Wie Sie wissen sollten: Bash-Befehle sollten in .sh
Skripten gespeichert oder in einer Shell ausgeführt werden.
git branch -a | sed -e 's/[ \*]*//' | grep -v -e '\->' -e '^remotes' | xargs git grep "TEXT"
git branch -a | sed -e 's/[ \*]*//' | grep -v -e '\->' | grep '^remotes' | xargs git grep "TEXT"
git branch -a | sed -e 's/[ \*]*//' | grep -v -e '\->' | xargs git grep "TEXT"
git grep-branch "find my text"
fatal: ambiguous argument 'client': both revision and filename
-a
, die alle Zweige zeigt? Ich würde vorschlagen, Optionen für den git branch
Befehl zu verwenden, um Klammern zu trennen. Wenn Sie sich lokale Niederlassungen ansehen, gibt es nur eine einzige *
, sodass Sie nicht für sed entkommen müssen. Also: nur git branch | sed -e 's/*/ /' | xargs git grep "TEXT"
für lokale Filialen, nur git branch -r | grep -v -- "->" | xargs git grep "TEXT"
für entfernte Filialen und git branch -a | grep -v -- "->" | xargs git grep "TEXT"
für alle Filialen
So mache ich das:
git for-each-ref --format='%(*refname)' | xargs git grep SEARCHTERM