115 votes

Comment trouver le commit quand la ligne a été supprimée/supprimée ?

J'ai une ligne supprimée dans un fichier de mon référentiel Git. Je connaissais une partie du texte manquant, et le fichier dans lequel il se trouvait, donc j'ai utilisé git log -S'missingtext' /path/to/file .

Cependant, la seule chose qui est revenue est le commit dans lequel j'ai ajouté la ligne contenant le texte manquant. Le texte n'était pas présent dans HEAD, et le commit qui l'a ajouté était présent dans ma branche, donc je savais que l'un des commits dans l'historique de ma branche devait l'avoir supprimé, mais il n'apparaissait pas.

Après quelques recherches manuelles, il s'est avéré que la ligne a été supprimée accidentellement lors de la résolution d'un conflit pour une fusion. Je me demande donc :

  1. Est-ce la raison pour laquelle la pioche n'a pas pu trouver le commit qui a supprimé la ligne ?
  2. Comment aurais-je pu trouver où "missingtext" a été supprimé sans fouiller manuellement dans l'historique ?

Tout commentaire sur le numéro 1 serait le bienvenu (j'ai supposé que le numéro 1 était le numéro 2). git log -S me donnerait la réponse), mais ma vraie question est le point 2, car j'aimerais pouvoir éviter cela à l'avenir.

154voto

lettertwo Points 488

git log -c -S'missingtext' /path/to/file

git log ne montre pas de différence pour les commits de fusion par défaut. Essayez le -c ou --cc drapeaux.

Plus de discussion/explication :
https://git-scm.com/docs/git-log
nabble.com

D'après la documentation de git-log :

-c Avec cette option, la sortie de diff pour un commit de fusion montre les différences de chacun des parents au résultat de la fusion simultanément au lieu d'afficher les différences par paire entre un parent et le résultat un par un. De plus, il ne liste que les fichiers qui ont été modifiés depuis tous les parents.

--cc Ce drapeau implique l'option -c et compresse davantage la sortie du patch en omettant les hunks inintéressants dont le contenu dans les parents n'a que deux variantes. parents n'ont que deux variantes et le résultat de la fusion choisit l'une d'entre elles sans modification.

23voto

r_j Points 283

Il existe une excellente réponse à cette question sur Super User : Git : Comment trouver quel commit a supprimé une ligne ?

git blame --reverse START.. file.ext

Ceci montrera, pour chaque ligne, le dernier commit où la ligne était présente - disons hash 0123456789. Le prochain commit à suivre sera celui qui l'a supprimée. Utiliser git log et rechercher le hash 0123456789 et ensuite son successeur commit.

6voto

wolverdude Points 823

Méthode rapide et sale #2 - utiliser une boucle for.

for commit in $(git log --pretty='%H'); do
    git diff -U0 --ignore-space-change "$commit^" "$commit" | grep '^-.*missingtext' > /dev/null && echo "$commit"
done

Cela inclura toutes les modifications de fusion parce que cela spécifie explicitement le commit de base pour le diff. J'ai trouvé cela parce que git log -c -S... me donnait un tas de faux positifs. De plus, lorsque j'ai spécifié un chemin de fichier dans le fichier initial git log il a sauté le commit que je cherchais.

Comme cela peut fonctionner pendant un certain temps, vous pouvez spécifier -n sur le git log ou mettre un && break à la fin de la boucle si vous n'avez besoin que d'un seul résultat.

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