web-dev-qa-db-fra.com

Est-il possible d'effectuer une "recherche grep" dans toutes les branches d'un projet Git?

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?

115
epsilones

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 le git branch version. L'erreur était associée à une notation d'aliasing HEAD.

Je l'ai résolu en ajoutant un sed '/->/d' dans le tuyau, entre les commandes tr et xargs.

 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>
163
VonC

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
48
Edward Anderson

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/)'
19
errordeveloper

Il est possible de le faire de deux manières communes: alias Bash ou Git

Voici trois commandes:

  1. git grep-branch - Recherche dans toutes les branches locales et distantes
  2. git grep-branch-local - Recherche dans les agences locales uniquement
  3. git grep-branch-remote - branches distantes seulement

L'utilisation est la même que git grep

git grep-branch "find my text"
git grep-branch --some-grep-options "find my text"

GREP utilisant: les alias de Git

Fichier ~/.gitconfig

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;

Exemple 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

  1. Branche: dev
  2. Numéro de ligne: 53
  3. Chemin du fichier: modules/factory/getters.php
  4. Ligne correspondante: function getTastyCookies($user)

GREP utilisant: BASH

Comme vous devez le savoir: les commandes Bash doivent être stockées dans des scripts .sh Ou exécutées dans un shell.

Branches locales seulement

git branch -a | sed -e 's/[ \*]*//' | grep -v -e '\->' -e '^remotes' | xargs git grep "TEXT"

Branches distantes seulement

git branch -a | sed -e 's/[ \*]*//' | grep -v -e '\->' | grep '^remotes' | xargs git grep "TEXT"

Branches locales et distantes

git branch -a | sed -e 's/[ \*]*//' | grep -v -e '\->' | xargs git grep "TEXT"
5
Devaldo

Voici comment je le fais:

git for-each-ref --format='%(*refname)' | xargs git grep SEARCHTERM
4
William Entriken

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

3
CharlesB