git tag push




Comment grep(rechercher) code commis dans l'histoire git? (9)

@ La réponse de Jeet fonctionne dans PowerShell.

git grep -n <regex> $(git rev-list --all)

Ce qui suit affiche tous les fichiers, dans toute validation, qui contiennent un password .

# store intermediate result
$result = git grep -n "password" $(git rev-list --all)

# display unique file names
$result | select -unique { $_ -replace "(^.*?:)|(:.*)", "" }

J'ai supprimé un fichier ou du code dans un fichier par le passé. Puis-je grep dans le contenu (pas dans les messages de validation)?

Une solution très pauvre est de grep le journal:

git log -p | grep <pattern>

Cependant, cela ne retourne pas le hash de commit tout de suite. J'ai joué avec git grep en vain.


Alors essayez-vous de parcourir les anciennes versions du code pour voir où il y a quelque chose en dernier?

Si je faisais cela, j'utiliserais probablement git bisect . En utilisant bisect, vous pouvez spécifier une bonne version connue, une mauvaise version connue, et un script simple qui vérifie si la version est bonne ou mauvaise (dans ce cas, un grep pour voir si le code que vous cherchez est présent) ). L'exécution de ceci trouvera quand le code a été enlevé.


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

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

Notez que pour moi, pour une raison quelconque, le commit réel qui a supprimé cette regex n'apparaissait pas dans la sortie de la commande, mais plutôt un commit avant celui-ci.


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

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

Il existe une différence subtile entre la façon dont les options -G et -S déterminent si un commit correspond:

  • L'option -S compte essentiellement le nombre de fois que votre recherche correspond dans un fichier avant et après une validation. La validation est affichée dans le journal si les comptes avant et après sont différents. Cela ne montrera pas, par exemple, les commits où une ligne correspondant à votre recherche a été déplacée.
  • Avec l'option -G , la validation est affichée dans le journal si votre recherche correspond à une ligne ajoutée, supprimée ou modifiée.

Prenez ce commit comme 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 que "bonjour" apparaît dans le fichier est le même avant et après cette validation, il ne correspondra pas en utilisant -Shello . Cependant, comme il y avait un changement à une ligne correspondant à hello , le commit sera montré en utilisant -Ghello .


Pour simplifier, je suggère d'utiliser l'interface graphique: gitk - Le navigateur du référentiel Git , c'est assez flexible

  1. pour rechercher le code:
  2. pour rechercher le fichier:
  3. de cause, il prend également en charge regex:

et vous pouvez naviguer dans les résultats en utilisant la flèche haut / bas


Pour toute personne essayant de le faire dans SourceTree , il n'y a pas de commande directe dans l'interface utilisateur (à partir de la version 1.6.21.0). Cependant, vous pouvez utiliser les commandes spécifiées dans la réponse acceptée en ouvrant la fenêtre Terminal (bouton disponible dans la barre d'outils principale) et en les copiant / collant.

Remarque: La vue Recherche de SourceTree peut partiellement effectuer une recherche de texte pour vous. Appuyez sur Ctrl + 3 pour accéder à l'affichage Recherche (ou cliquez sur l'onglet Recherche disponible en bas). De l'extrême droite, définissez le type de recherche sur File Changes , puis tapez la chaîne que vous souhaitez rechercher. Cette méthode a les limitations suivantes par rapport à la commande ci-dessus:

  1. SourceTree affiche uniquement les validations qui contiennent le mot recherché dans l'un des fichiers modifiés. Trouver le fichier exact qui contient le texte de recherche est encore une tâche manuelle.
  2. RegEx n'est pas supporté.

Si vous voulez parcourir les changements de code (voir ce qui a réellement été changé avec le mot donné dans l'histoire entière) allez en mode patch - J'ai trouvé une combinaison très utile de faire:

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 ;) )

Vous devez utiliser l'option pickaxe ( -S ) du git log

Pour rechercher 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 - trouvez la ligne perdue par mot-clé pour plus.

Comme Jakub Narębski a commenté:

  • cela recherche les différences qui introduisent ou suppriment une instance de <string> .
    Cela signifie généralement "révisions où vous avez ajouté ou supprimé la ligne avec" Foo "".

  • l'option --pickaxe-regex vous permet d'utiliser une extension regex POSIX au lieu de rechercher une chaîne.

Comme Rob remarquer, cette recherche est sensible à la casse - il a ouvert une question de suivi sur la façon de rechercher insensible à la casse.


git rev-list --all | xargs -n 5 git grep EXPRESSION

est un tweak à la solution de @ Jeet, donc il montre les résultats pendant qu'il cherche et pas seulement à la fin (ce qui peut prendre beaucoup de temps dans un grand dépôt).





diff