J'ai supprimé un fichier ou un code dans un fichier par le passé. Puis-je grep dans le contenu (pas dans les messages de validation)?
Une très mauvaise solution consiste à graper le journal:
git log -p | grep <pattern>
Cependant, cela ne retourne pas le hachage de commit immédiatement. J'ai joué avec git grep
en vain.
Pour rechercher commit content (c'est-à-dire les lignes de source réelles, par opposition aux messages de commit, etc.), vous devez procéder comme suit:
git grep <regexp> $(git rev-list --all)
git rev-list --all | xargs git grep <expression>
fonctionnera si vous rencontrez une erreur "Liste d'arguments trop longue".
Si vous souhaitez limiter la recherche à un sous-arbre (par exemple, "lib/util"), vous devrez le transmettre à la sous-commande rev-list
et à la variable grep
:
git grep <regexp> $(git rev-list --all -- lib/util) -- lib/util
Ceci couvrira tout votre texte de validation pour regexp
.
La raison de passer le chemin dans les deux commandes est parce que rev-list
renverra la liste des révisions contenant tous les changements apportés à lib/util
, mais vous devez également passer à grep
pour qu'il ne contienne que recherche dans lib/util
.
Imaginez simplement le scénario suivant: grep
pourrait trouver le même <regexp>
sur d'autres fichiers contenus dans la même révision renvoyée par rev-list
(même si aucun changement n'a été apporté à ce fichier lors de cette révision. ).
Voici d'autres moyens utiles de rechercher votre source:
Recherche dans l'arborescence de travail pour la correspondance du texte dans l'expression régulière regexp:
git grep <regexp>
Rechercher dans l'arborescence de travail des lignes de texte correspondant à l'expression régulière regexp1 ou regexp2:
git grep -e <regexp1> [--or] -e <regexp2>
Recherchez dans l’arbre de travail les lignes de texte correspondant à l’expression régulière regexp1 et regexp2, indiquant les chemins de fichier uniquement:
git grep -e <regexp1> --and -e <regexp2>
Rechercher dans l'arborescence de travail les fichiers dont les lignes de texte correspondent à l'expression régulière regexp1 et celles correspondant à l'expression régulière regexp2:
git grep -l --all-match -e <regexp1> -e <regexp2>
Rechercher dans l'arborescence de travail les lignes modifiées du modèle de correspondance de texte:
git diff --unified=0 | grep <pattern>
Recherchez dans toutes les révisions les expressions correspondantes correspondant à l'expression régulière regexp:
git grep <regexp> $(git rev-list --all)
Rechercher dans toutes les révisions entre rev1 et rev2 le texte correspondant à l'expression régulière regexp:
git grep <regexp> $(git rev-list <rev1>..<rev2>)
Vous devez utiliser l'option pioche (_-S
_) de 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 Historique Git - Trouver la ligne perdue par mot-clé pour plus d'informations.
Comme Jakub Narębski a commenté:
this recherche les différences qui introduisent ou suppriment une instance de _<string>
_ .
Cela signifie généralement "révisions pour lesquelles vous avez ajouté ou supprimé une ligne avec 'Foo'".
l'option _--pickaxe-regex
_ vous permet d'utiliser une expression rationnelle POSIX étendue au lieu de rechercher une chaîne.
Comme Rob a commenté, cette recherche est sensible à la casse - il a ouvert une question suivante sur la recherche de la casse.
Ma façon préférée de le faire est d'utiliser l'option git log
de -G
(ajoutée à 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 manière dont les options -G
et -S
déterminent si un commit correspond:
-S
compte essentiellement le nombre de correspondances de votre recherche dans un fichier avant et après une validation. La validation est indiquée dans le journal si les nombres 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.-G
, la validation est affichée dans le journal si votre recherche correspond à une ligne ajoutée, supprimée ou modifiée.Prenons 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
Etant donné que le nombre de fois que "hello" apparaît dans le fichier est identique avant et après cette validation, il ne correspondra pas avec -Shello
. Cependant, comme il y a eu un changement dans une ligne correspondant à hello
, la validation sera affichée à l'aide de -Ghello
.
Si vous voulez parcourir les modifications de code (voyez ce qui a réellement été changé avec le mot donné dans toute l'historique), choisissez le mode patch
- j'ai trouvé une combinaison très utile de ce qui suit:
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 ;) )
Je pris réponse de @ Jeet et l'adpated à Windows (grâce à 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, la validation qui a supprimé cette expression rationnelle n'apparaissait pas dans le résultat de la commande, mais plutôt une validation antérieure.
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
Rechercher dans toute révision, tous les fichiers:
git rev-list --all | xargs git grep <regexp>
Rechercher uniquement dans certains fichiers, pour exemple fichiers XML:
git rev-list --all | xargs -I{} git grep <regexp> {} -- "*.xml"
Les lignes de résultat doivent ressembler à ceci: 6988bec26b1503d45eb0b2e8a4364afb87dde7af: bla.xml: texte de la ligne trouvée ...
Vous pouvez alors obtenir plus d’informations comme auteur, date, diff en utilisant git show
:
git show 6988bec26b1503d45eb0b2e8a4364afb87dde7af
Pour tous ceux qui essaient de le faire dans Sourcetree, il n'y a pas de commande directe dans l'interface utilisateur pour cela (à 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 dessus.
Remarque: La vue Search de Sourcetree peut partiellement rechercher du texte pour vous. presse Ctrl + 3 accéder à la vue Recherche (ou cliquez sur l’onglet Recherche disponible en bas). De l'extrême droite, définissez Type de recherche sur Fichier Modifications, puis tapez la chaîne que vous souhaitez rechercher. Cette méthode présente les limitations suivantes par rapport à la commande ci-dessus:
Pour plus de simplicité, je suggérerais d'utiliser une interface graphique: gitk - le navigateur de référentiel Git . C'est assez flexible
Et vous pouvez naviguer dans les résultats en utilisant les flèches haut/bas.
La réponse de @ Jeet fonctionne dans PowerShell.
git grep -n <regex> $(git rev-list --all)
Ce qui suit affiche tous les fichiers, dans n’importe quelle livraison, contenant un password
.
# store intermediate result
$result = git grep -n "password" $(git rev-list --all)
# display unique file names
$result | select -unique { $_ -replace "(^.*?:)|(:.*)", "" }
Alors essayez-vous de passer par les anciennes versions du code en cherchant où quelque chose existe?
Si je le faisais, j'utiliserais probablement git bisect . En utilisant une bissecte, 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 incorrecte (dans ce cas, un grep pour voir si le code que vous recherchez est présent. ). En cours d’exécution, vous découvrirez quand le code a été supprimé.
git rev-list --all | xargs -n 5 git grep EXPRESSION
est une solution de Tweak to @ Jeet, de sorte qu'elle affiche les résultats pendant la recherche et pas seulement à la fin (ce qui peut prendre beaucoup de temps dans un grand référentiel).
Dans mon cas, je devais rechercher un court engagement et les solutions listées ne fonctionnaient malheureusement pas.
J'ai réussi à le faire avec: (remplace le jeton REGEX)
for commit in $(git rev-list --all --abbrev-commit)
do
if [[ $commit =~ __REGEX__ ]]; then
git --no-pager show -s --format='%h %an - %s' $commit
fi
done
Scénario: Vous avez fait un grand nettoyage de votre code en utilisant votre IDE. Problème: Le IDE a nettoyé plus qu'il ne devrait et maintenant votre code ne compile pas (ressources manquantes, etc.)
Solution:
git grep --cached "text_to_find"
Il trouvera le fichier où "text_to_find" a été changé.
Vous pouvez maintenant annuler cette modification et compiler votre code.
Chaque fois que je me trouve chez vous. J'utilise la ligne de commande suivante:
git log -S "<words/phrases i am trying to find>" --all --oneline --graph
Explication:
git log
- J'ai besoin d'écrire plus ici, il montre les logs dans un ordre chronologique.-S "<words/phrases i am trying to find>"
- Il montre tous les commits git où n'importe quel fichier (ajouté/modifié/supprimé) contient les mots/phrases que j'essaie de trouver sans les symboles '<>'.--all
- Pour appliquer et rechercher dans toutes les branches.--oneline
- Compresse le journal git en une ligne.--graph
- Il crée le graphe des commits ordonnés dans l'ordre chronologique.