497 votes

Comment trouver le commit Git qui a introduit une chaîne dans n'importe quelle branche ?

Je veux pouvoir trouver une certaine chaîne qui a été introduite dans n'importe quel commit dans n'importe quelle branche, comment puis-je faire ça? J'ai trouvé quelque chose (que j'ai modifié pour Win32), mais git whatchanged ne semble pas regarder dans les différentes branches (ignorez le morceau py3k, c'est juste une correction de saut de ligne msys/win)

git whatchanged --  | \
grep "^commit " | \
python -c "exec(\"import sys,msvcrt,os\nmsvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)\nfor l in sys.stdin: print(l.split()[1])\")" | \
xargs -i% git show origin % -- 

Peu importe si votre solution est lente.

0 votes

887voto

Mark Longair Points 93104

Vous pouvez faire :

git log -S  --source --all

Pour trouver tous les commits qui ont ajouté ou supprimé la chaîne fixe search string. Le paramètre --all signifie de partir de chaque branche et --source signifie de montrer quelles de ces branches ont mené à trouver ce commit. Il est souvent utile d'ajouter -p pour montrer également les patchs que chacun de ces commits introduirait.

Les versions de git depuis 1.7.4 ont également une option similaire -G, qui prend une expression régulière. Cela a en fait des sémantiques différentes (et plutôt plus évidentes), expliquées dans ce billet de blog de Junio Hamano.

Comme thameera le souligne dans les commentaires, vous devez mettre des guillemets autour du terme de recherche s'il contient des espaces ou d'autres caractères spéciaux, par exemple :

git log -S 'hello world' --source --all
git log -S "dude, where's my car?" --source --all

Voici un exemple utilisant -G pour trouver les occurrences de function foo() {:

git log -G "^(\s)*function foo[(][)](\s)*{$" --source --all

30 votes

+1 pour l'excellence. Indiquer -S est une chose, expliquer les choses, c'est mieux. De plus, j'aime utiliser --decorate pour voir de quelles branches viennent les choses

9 votes

@sehe : Merci pour votre commentaire positif. Je suppose que cela vaut la peine de noter que --decorate ajoute uniquement le nom de la branche au commit en bout de chaque branche. En pratique, je n'utilise pas vraiment --source ou --decorate, et utilise plutôt git branch -a --contains pour trouver quelles branches contiennent le commit qui m'intéresse.

6 votes

Ajouter -p pour voir la différence en ligne, également, FWIW

118voto

Ciro Santilli Points 3341

--reverse est également utile car vous voulez le premier commit qui a apporté le changement :

git log --all -p --reverse --source -S 'needle'

De cette manière, les anciens commit apparaîtront en premier.

27voto

albfan Points 2333

Se balader avec les mêmes réponses :

$ git config --global alias.find '!git log --color -p -S '
  • ! est nécessaire car sinon, git ne transmet pas correctement l'argument à -S. Voir cette réponse
  • --color et -p aident à afficher exactement "whatchanged"

Maintenant vous pouvez faire

$ git find 

ou

$ git find  --all
$ git find  master develop

0 votes

La couleur a l'air bien!

22voto

Steven Penny Points 18523

La réponse de Mark Longair est excellente, mais j'ai trouvé cette version plus simple qui fonctionne pour moi.

git log -S whatever

26 votes

Juste pour clarifier, cela fonctionne bien si le commit que vous recherchez est dans HEAD, mais cette question particulière demandait spécifiquement de regarder à travers toutes les branches d'un dépôt.

9voto

ribamar Points 50
git log -S"chaîne_à_rechercher" # options like --source --reverse --all etc

Faites attention de ne pas utiliser d'espaces entre S et "chaîne_à_rechercher". Dans certaines configurations (git 1.7.1), vous obtiendrez une erreur comme :

fatal: argument ambigu 'chaîne_à_rechercher' : révision inconnue ou chemin non présent dans l'arborescence de travail.
Utilisez '--' pour séparer les chemins des révisions

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