Est-il possible de s'exécuter git grep
dans toutes les branches d'un projet provenant d'un contrôle Git? Ou y a-t-il une autre commande à exécuter?
Est-il possible de s'exécuter git grep
dans toutes les branches d'un projet provenant d'un contrôle Git? Ou y a-t-il une autre commande à exécuter?
Réponses:
La question " Comment grep (rechercher) du code commis dans l'historique git? " Recommande:
git grep <regexp> $(git rev-list --all)
Cela parcourt tous les commits, qui devraient inclure toutes les branches.
Une autre forme serait:
git rev-list --all | (
while read revision; do
git grep -F 'yourWord' $revision
done
)
Vous pouvez trouver encore plus d'exemples dans cet article :
J'ai essayé ce qui précède sur un projet suffisamment grand pour que git se soit plaint de la taille de l'argument, donc si vous rencontrez ce problème, faites quelque chose comme:
git rev-list --all | (while read rev; do git grep -e <regexp> $rev; done)
(voir une alternative dans la dernière section de cette réponse, ci-dessous)
N'oubliez pas ces paramètres, si vous les voulez:
# Allow Extended Regular Expressions
git config --global grep.extendRegexp true
# Always Include Line Numbers
git config --global grep.lineNumber true
Cet alias peut également aider:
git config --global alias.g "grep --break --heading --line-number"
Remarque: chernjie a suggéré que git rev-list --all
c'est une exagération.
Une commande plus raffinée peut être:
git branch -a | tr -d \* | xargs git grep <regexp>
Ce qui vous permettra de rechercher uniquement les branches (y compris les branches distantes)
Vous pouvez même créer un alias bash / zsh pour cela:
alias grep_all="git branch -a | tr -d \* | xargs git grep"
grep_all <regexp>
Mise à jour août 2016: RM recommande dans les commentaires
J'ai eu un "
fatal: bad flag '->' used after filename
" en essayant lagit branch
version. L'erreur était associée à uneHEAD
notation d'alias.Je l'ai résolu en ajoutant un
sed '/->/d'
dans le tuyau, entre lestr
et lesxargs
commandes.
git branch -a | tr -d \* | sed '/->/d' | xargs git grep <regexp>
C'est:
alias grep_all="git branch -a | tr -d \* | sed '/->/d' | xargs git grep"
grep_all <regexp>
git branch
dans tr ou sed; git branch
est une commande en porcelaine destinée à la consommation humaine. Voir stackoverflow.com/a/3847586/2562319 pour les alternatives préférées.
git log
peut être un moyen plus efficace de rechercher du texte dans toutes les branches, surtout s'il y a beaucoup de correspondances, et que vous voulez d'abord voir les modifications les plus récentes (pertinentes).
git log -p --all -S 'search string'
git log -p --all -G 'match regular expression'
Ces commandes de journal répertorient les commits qui ajoutent ou suppriment la chaîne de recherche / expression régulière donnée, (généralement) plus récente en premier. L' -p
option permet d'afficher le diff pertinent à l'endroit où le modèle a été ajouté ou supprimé, afin que vous puissiez le voir dans son contexte.
Après avoir trouvé un commit pertinent qui ajoute le texte que vous recherchiez (par exemple 8beeff00d), trouvez les branches qui contiennent le commit:
git branch -a --contains 8beeff00d
J'ai trouvé cela très utile:
git grep -i foo `git for-each-ref --format='%(refname)' refs/`
Vous auriez besoin d'ajuster les derniers arguments selon que vous ne voulez regarder que les branches distantes ou locales, c'est-à-dire:
git grep -i foo $(git for-each-ref --format='%(refname)' refs/remotes)
git grep -i foo $(git for-each-ref --format='%(refname)' refs/heads)
L'alias que j'ai créé ressemble à ceci:
grep-refs = !sh -c 'git grep "$0" "$@" "$(git for-each-ref --format=\"%(refname)\"" refs/)'
git for-each-ref
avec --sort=-committerdate --count=100
! Merci pour l'idée originale!
Il est possible de le faire de deux manières courantes: alias Bash ou Git
Voici trois commandes:
git grep-branch
- Recherche dans toutes les succursales locales et distantesgit grep-branch-local
- Recherche dans les succursales locales uniquementgit grep-branch-remote
- Succursales distantes uniquementL'utilisation est la même que git grep
git grep-branch "find my text"
git grep-branch --some-grep-options "find my text"
Les commandes doivent être ajoutées manuellement au ~/.gitconfig
fichier, car git config --global alias
évaluer le code complexe que vous ajoutez et le gâcher.
[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 "
Remarque: lorsque vous ajoutez des alias et qu'ils ne s'exécutent pas - vérifiez les antislashs, \
ils peuvent nécessiter un échappement supplémentaire \\
par rapport aux commandes bash .
git branch -a
- Afficher toutes les branches;sed -e 's/[ \\*]*//'
- Coupez les espaces (de branch -a
) et * (le nom de la branche active l'a);grep -v -e '\\->'
- Ignorez les noms complexes comme remotes/origin/HEAD -> origin/master
;grep '^remotes'
- Obtenez toutes les branches distantes;grep -v -e '^remotes'
- Obtenez des succursales sauf les succursales distantes;git grep-branch-local -n getTastyCookies
-n
Préfixez le numéro de ligne aux lignes correspondantes.
[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)
La structure actuelle est:
:
- Séparateur
dev
53
modules/factory/getters.php
function getTastyCookies($user)
Comme vous devez le savoir: les commandes Bash doivent être stockées dans des .sh
scripts ou exécutées dans un shell.
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
, qui montre toutes les branches? Je suggérerais d'utiliser des options pour la git branch
commande pour séparer les braches. Quand on regarde les succursales locales, il n'y en a qu'une seule *
, donc pas besoin d'y échapper pour sed. Donc: git branch | sed -e 's/*/ /' | xargs git grep "TEXT"
pour les succursales locales seulement, git branch -r | grep -v -- "->" | xargs git grep "TEXT"
pour les succursales éloignées seulement et git branch -a | grep -v -- "->" | xargs git grep "TEXT"
pour toutes les succursales
Voici comment je fais:
git for-each-ref --format='%(*refname)' | xargs git grep SEARCHTERM
Si vous donnez à un commit une valeur de hachage SHA-1, git grep
vous le faites chercher à l'intérieur, au lieu de la copie de travail.
Pour rechercher toutes les branches, vous pouvez obtenir tous les arbres avec git rev-list --all
. Mettez tout cela avec
git grep "regexp" $(git rev-list --all)
... et ayez de la patience