web-dev-qa-db-fra.com

Comment rechercher une chaîne dans tous les commits Git et Mercurial dans le référentiel?

J'ai un référentiel Git avec peu de branches et des commits en suspens. Je voudrais rechercher tous ces commits dans le référentiel pour une chaîne spécifique.

Je sais comment obtenir un journal de tous les commits de l'histoire, mais ceux-ci n'incluent pas les branches ni les blobs pendantes, mais uniquement l'historique de HEAD. Je veux tous les trouver, trouver un commit spécifique qui a été égaré.

J'aimerais aussi savoir comment faire cela dans Mercurial, car j'envisage un changement.

287
Josip

Vous pouvez voir les commits en suspens avec git log -g.

-g, --walk-reflogs
 Instead of walking the commit ancestry chain, walk reflog entries from
 the most recent one to older ones. 

Donc, vous pouvez faire ceci pour trouver une chaîne particulière dans un message de commit qui est suspendu:

git log -g --grep=search_for_this

Alternativement, si vous souhaitez rechercher les modifications pour une chaîne particulière, vous pouvez utiliser l'option de recherche de pioche, "-S":

git log -g -Ssearch_for_this
# this also works but may be slower, it only shows text-added results
git grep search_for_this $(git log -g --pretty=format:%h)

Git 1.7.4 va ajouter l'option -G , ce qui vous permet de passer -G <regexp> pour rechercher le moment où une ligne contenant <regexp> a été déplacée, ce que -S ne peut pas faire. -S ne vous indiquera que lorsque le nombre total de lignes contenant la chaîne a changé (c'est-à-dire l'ajout/la suppression de la chaîne).

Enfin, vous pouvez utiliser gitk pour visualiser les commits pendants avec:

gitk --all $(git log -g --pretty=format:%h)

Et utilisez ensuite ses fonctionnalités de recherche pour rechercher le fichier égaré. Tous ces travaux supposent que le commit manquant n’a pas "expiré" et a été collecté, ce qui peut se produire s’il est suspendu pendant 30 jours et que vous expirez les réflexions ou exécutez une commande qui les expire.

327
richq

Dans Mercurial, vous utilisez hg log --keyword pour rechercher des mots-clés dans les messages de validation et hg log --user pour rechercher un utilisateur particulier. Voir hg help log pour d'autres moyens de limiter le journal.

54
Martin Geisler

En plus de richq answer d'utilisation de _git log -g --grep=<regexp>_ ou git grep -e <regexp> $(git log -g --pretty=format:%h): jetez un oeil aux messages suivants de Junio ​​C Hamano, mainteneur actuel de git


Sommaire

(git grep) et git log --grep sont orientés ligne , en ce sens qu'ils recherchent des lignes correspondant au modèle spécifié.

Vous pouvez utiliser _git log --grep=<foo> --grep=<bar>_ (ou _git log --author=<foo> --grep=<bar>_ qui se traduit en interne par deux _--grep_) pour rechercher les validations qui correspondent soit de motifs (implicite OU sémantique).

En raison de son orientation ligne, la sémantique utile ET consiste à utiliser _git log --all-match --grep=<foo> --grep=<bar>_ pour rechercher commit qui a à la fois la première ligne et la deuxième ligne quelque part.

Avec _git grep_, vous pouvez combiner plusieurs motifs (tous ceux qui doivent utiliser le formulaire _-e <regexp>_) avec _--or_ (qui est la valeur par défaut), _--and_, _--not_, _(_ et _)_. Pour grep _--all-match_ signifie que le fichier doit comporter des lignes correspondant à chacune des alternatives.

22
Jakub Narębski

En me basant sur la réponse de rq, j'ai trouvé que cette ligne faisait ce que je voulais:

git grep "search for something" $(git log -g --pretty=format:%h -S"search for something")

Ce qui rapportera l'ID de validation, le nom du fichier, et affichera la ligne correspondante, comme ceci:

91ba969:testFile:this is a test

... Quelqu'un est-il d'accord pour dire que ce serait une option intéressante à inclure dans la commande standard git grep?

11
Sam Hiatt

Toute commande utilisant des références en tant qu'arguments acceptera l'option --all décrite dans la page de manuel relative à git rev-list comme suit:

   --all
       Pretend as if all the refs in $GIT_DIR/refs/ are listed on the
       command line as <commit>.

Ainsi, par exemple, git log -Sstring --all affichera tous les commits qui mentionnent string et qui sont accessibles à partir d'une branche ou d'une balise (je suppose que vos commits pendants sont au moins nommés avec une balise).

5
adl

Avec Mercurial vous faites un

$ hg grep "search for this" [file...]

Il existe d'autres options permettant de réduire la gamme de révisions recherchées.

5
Yawar

Je ne sais pas pour git, mais dans Mercurial, je me contenterais de diriger la sortie du journal hg vers un script sed/Perl/quelconque pour rechercher ce que vous cherchiez. Vous pouvez personnaliser la sortie du journal hg en utilisant un modèle ou un style pour faciliter la recherche, si vous le souhaitez.

Cela inclura toutes les branches nommées dans le repo. Mercurial n'a pas quelque chose comme des blobs pendantes.

2
Kurt Schelfthout

Pour ajouter juste une solution non encore mentionnée, je devais dire que l’utilisation du champ de recherche graphique de gitg était la solution la plus simple pour moi. Il sélectionnera la première occurrence et vous pourrez trouver la suivante avec Ctrl-G.

1
icarito

si vous êtes un utilisateur de vim, vous pouvez installer tig (apt-get install tig) et utiliser /, la même commande pour rechercher sur vim

https://blogs.atlassian.com/2013/05/git-tig/

1
jacktrade

Une commande dans git que je pense qu'il est beaucoup plus facile de trouver une chaîne:

git log --pretty=oneline --grep "string to search"

fonctionne dans Git 2.0.4

1
Adriano Rosa