Est-il possible d'exécuter git grep
dans toutes les branches d’un projet issu du contrôle Git? Ou y a-t-il une autre commande à exécuter?
La question " Comment grep (recherche) le code engagé dans l'historique git? " recommande:
git grep <regexp> $(git rev-list --all)
Cela recherche dans tous les commits, ce qui devrait 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, procédez comme suit:
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 aussi aider:
git config --global alias.g "grep --break --heading --line-number"
Remarque: chernjiesuggéré que git rev-list --all
est une overkill.
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: R.M. recommande dans les commentaires
J'ai un "
fatal: bad flag '->' used after filename
"en essayant legit branch
version. L'erreur était associée à une notation d'aliasingHEAD
.Je l'ai résolu en ajoutant un
sed '/->/d'
dans le tuyau, entre les commandestr
etxargs
.
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 log
Peut être un moyen plus efficace de rechercher du texte dans toutes les branches, en particulier s'il y a beaucoup de correspondances et que vous souhaitez voir les modifications les plus récentes (pertinentes) en premier.
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) la plus récente en premier. L'option -p
Permet d'afficher le diff pertinent là où le motif a été ajouté ou supprimé, afin que vous puissiez le voir en contexte.
Après avoir trouvé un commit pertinent qui ajoute le texte que vous recherchiez (par exemple, 8beeff00d), recherchez les branches contenant 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 devez ajuster les derniers arguments selon que vous voulez uniquement regarder les branches distantes par rapport aux branches locales, c.-à-d .:
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/)'
Il est possible de le faire de deux manières communes: alias Bash ou Git
Voici trois commandes:
git grep-branch
- Recherche dans toutes les branches locales et distantesgit grep-branch-local
- Recherche dans les agences locales uniquementgit grep-branch-remote
- branches distantes seulementL'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 fichier ~/.gitconfig
, Car git config --global alias
Évalue le code complexe que vous ajoutez et le gâche.
[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 que leur exécution échoue, vérifiez les barres obliques inverses \
, Elles peuvent nécessiter un échappement supplémentaire \\
Par rapport aux commandes bash.
git branch -a
- Affiche toutes les branches;sed -e 's/[ \\*]*//'
- Découpe espaces (à partir de branch -a
) Et * (le nom de la branche active l’a);grep -v -e '\\->'
- Ignore les noms complexes comme remotes/Origin/HEAD -> Origin/master
;grep '^remotes'
- Obtenez toutes les branches distantes;grep -v -e '^remotes'
- Récupère les branches sauf les branches 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 la suivante:
:
- 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 scripts .sh
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"
Voici comment je le fais:
git for-each-ref --format='%(*refname)' | xargs git grep SEARCHTERM
Si vous donnez un commit SHA1 à git grep
vous avez la recherche en eux, au lieu de la copie de travail.
Pour rechercher toutes les branches, vous pouvez obtenir all les arbres avec git rev-list --all
. Mettre le tout avec
git grep "regexp" $(git rev-list --all)
... et avoir de la patience