2009-12-21 7 views
15

Je viens de lire la page de manuel git-blame une fois et remarqué cette partie:Comment puis-je détecter du code copié-collé à l'aide de git?

Une manière particulièrement utile est de voir si un fichier ajouté a des lignes créées par copier-coller à partir de fichiers existants. Parfois cela indique que le développeur était bâclé et n'a pas refacturé le code correctement. Vous pouvez d'abord trouver le commettras qui a introduit le fichier avec:

git log --diff-filter = A = --pretty court - foo

puis annoter le changement entre l'engagement et de ses parents, à l'aide commit ^! notation:

git blame -C -C -f $ commit ^! - foo

Cela semble très intéressant, mais je ne Grok pas tout à fait comment cela fonctionne, et pourquoi. Je me demande s'il peut être utilisé dans un crochet git pour détecter copier & code collé. Peut-être un expert git peut-être expliquer l'effet de l'utilisation des commandes git ci-dessus, et s'il est possible d'utiliser quelque chose comme ça pour faire git montrer s'il y a duplication de code (peut-être en utilisant l'indice de similarité calculé lors du renommage des fichiers)?

Répondre

10

Vous pouvez interrompre les commandes individuellement.

$ git log --diff-filter=A --pretty=short -- foo 

affiche le journal du fichier "foo". L'option --diff-filter affiche uniquement les validations dans lesquelles les fichiers ont été ajoutés ("A") et l'affiche dans un format condensé (l'option --pretty=short). (Le -- est une norme pour dire « rien qui suit est une option », et tout ce qui suit est une liste de noms de fichiers sur lesquels le journal doit être appliqué.)

Puis:

$ git blame -C -C -f $commit^! -- foo 

git blame annote chaque ligne d'un fichier avec les informations de la dernière validation. L'option double -C -C vérifie de manière agressive les lignes qui ont été copiées à partir d'autres fichiers. L'option -f affiche le nom de fichier de la validation d'origine (ce qui signifie que si une ligne a été copiée à partir d'un autre fichier, vous voyez le nom du fichier à partir duquel elle a été copiée). Le $commit^! est la notation pour un $ commit; le suffixe ^! signifie exclure tous les parents de $ commit. Donc, en gros, la première commande (git log) vous aide à trouver que les lignes copiées ont été introduites; le second (git blame) vous aide à trouver la source pour tout commits suspectes retournés par git log.

+0

Merci pour les explications! Le double drapeau '-C -C' pour git blame est vraiment intéressant –