1614 votes

Comment grep (recherche) commis de code dans l'historique de git?

J'ai supprimé un fichier ou un peu de code dans un fichier à un moment du passé. Puis-je grep dans le contenu (et non dans les messages de validation)?

Une très mauvaise solution est de filtrer le journal:

git log -p | grep <pattern>

Mais ce n'est pas le retour de la validation de hachage tout de suite. J'ai joué un peu avec git grep , en vain.

2143voto

Jeet Points 10514

À la recherche pour la validation du contenu (c'est à dire, de véritables lignes de la source, par opposition à des messages de commit et autres), ce que vous devez faire est de:

git grep <regexp> $(git rev-list --all)

Mises à jour: git rev-list --all | xargs git grep expression ne fonctionnera que si vous exécutez dans une "liste d'arguments trop longue" erreur

Ce sera grep à travers tous vos commettre de texte pour les regexp.

Voici quelques autres façons utiles de la recherche de votre source:

Recherche arbre de travail pour le texte correspondant de l'expression régulière regexp:

git grep <regexp>

Recherche arbre de travail pour les lignes de texte expression régulière correspondante regexp1 ou regexp2:

git grep -e <regexp1> [--or] -e <regexp2>

Recherche arbre de travail pour les lignes de texte expression régulière correspondante regexp1 et regexp2, les rapports sur les chemins que:

git grep -e <regexp1> --and -e <regexp2>

Recherche arbre de travail pour les fichiers qui ont des lignes de texte expression régulière correspondante regexp1 et les lignes de texte expression régulière correspondante regexp2:

git grep -l --all-match -e <regexp1> -e <regexp2>

Recherche de toutes les révisions pour le texte correspondant de l'expression régulière regexp:

git grep <regexp> $(git rev-list --all)

Recherche de toutes les révisions entre rev1 et rev2 pour le texte correspondant de l'expression régulière regexp:

git grep <regexp> $(git rev-list <rev1>..<rev2>)

615voto

VonC Points 414372

Vous devez utiliser la pioche (-S) option d' git log

À la recherche d' Foo:

git log -SFoo -- path_containing_change 
git log -SFoo --since=2009.1.1 --until=2010.1.1 -- path_containing_change

Voir l' historique de Git - trouver perdu de ligne par mot-clé pour plus.


Comme Jakub Narębski commentaires:

  • cette recherche de différences que d'introduire ou de supprimer une instance de <string>.
    Cela signifie généralement "révisions où vous avez ajouté ou supprimé de la ligne avec 'Foo'".

  • l' --pickaxe-regex option permet l'utilisation prolongée regex POSIX au lieu de rechercher une chaîne de caractères.

286voto

Tyler Holien Points 1645

Ma façon préférée de le faire est avec git logs' -G option (ajouté dans la version 1.7.4).

-G<regex>
       Look for differences whose added or removed line matches the given <regex>.

Il y a une subtile différence entre la façon dont l' -G et -S options de déterminer si un commit correspond à:

  • L' -S option essentiellement compte le nombre de fois votre recherche correspond à un fichier avant et après une validation. La livraison est indiqué dans le journal si l'avant et l'après des comptages sont différents. Ce ne sera pas, par exemple, montre s'engage, où une ligne correspondant à votre recherche a été déplacé.
  • Avec l' -G option, la livraison est indiqué dans le journal si votre recherche correspond à une ligne qui a été ajouté, supprimé ou modifié.

Prendre cette commettre un exemple:

diff --git a/test b/test
index dddc242..60a8ba6 100644
--- a/test
+++ b/test
@@ -1 +1 @@
-hello hello
+hello goodbye hello

Parce que le nombre de fois "hello" s'affiche dans le fichier est le même avant et après cette validation, il ne sera pas de correspondance à l'aide d' -Shello. Cependant, puisqu'il y avait un changement à une ligne de correspondance hello, la livraison sera indiqué à l'aide d' -Ghello.

60voto

Bartlomiej Skwira Points 193

Si vous souhaitez parcourir les changements de code (voir réellement ce qui a été changé avec le mot donné dans l'ensemble de l'histoire) aller pour patch mode - j'ai trouvé un très utile la combinaison de l'action:

git log -p
# hit '/' for search mode
# type in the word you are searching
# if the first search is not relevant hit 'n' for next (like in vim ;) )

25voto

ripper234 Points 39314

J'ai pris @Jeet réponse et adaptée à Windows (merci pour cette réponse):

FOR /F %x IN ('"git rev-list --all"') DO @git grep <regex> %x > out.txt

À noter que pour moi, pour une raison quelconque, le commit qui a supprimé cette expression n'apparaît pas dans le résultat de la commande, mais plutôt de s'engager au préalable.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X