À quoi sert «git diff --patience»?

219

En quoi l'algorithme de patience diffère-t-il de l' git diffalgorithme par défaut et quand voudrais-je l'utiliser?

Gabe Moothart
la source
1
Peut-être que cela correspond au code déplacé et aux lignes modifiées qui peuvent être beaucoup plus lentes
codymanix
J'ai extrait un script autonome pour Patience Diff de Bazaar, vous pouvez le trouver dans un autre thread SO .
TryPyPy
38
Une question de suivi. Quand ne devrais-je pas utiliser la différence de patience?
balki
4
Il y a aussi le --histogramparamètre qui "... étend l'algorithme de patience pour" prendre en charge les éléments communs à faible occurrence " git-scm.com/docs/git-diff.html
Robert

Réponses:

183

Vous pouvez lire un article de Bram Cohen , l'auteur de l'algorithme de différence de patience, mais j'ai trouvé cet article de blog pour résumer très bien l'algorithme de différence de patience:

Patience Diff, au lieu de cela, concentre son énergie sur les lignes à haute fréquence à basse fréquence qui servent de marqueurs ou de signatures de contenu important dans le texte. Il s'agit toujours d'un diff basé sur LCS, mais avec une différence importante, car il ne considère que la sous-séquence commune la plus longue des lignes de signature:

Trouvez toutes les lignes qui se produisent exactement une fois des deux côtés, puis effectuez la sous-séquence commune la plus longue sur ces lignes, en les faisant correspondre.

Quand devriez-vous utiliser la différence de patience? Selon Bram, la différence de patience est bonne pour cette situation:

Les cas vraiment mauvais sont ceux où deux versions ont divergé considérablement et le développeur ne fait pas attention à garder la taille des correctifs sous contrôle. Dans ces circonstances, un algorithme de différence peut parfois devenir `` mal aligné '' en ce qu'il correspond à de longues sections de crochets, mais il finit par corréler les crochets des fonctions dans une version avec les crochets de la fonction suivante suivante dans l'autre version. Cette situation est très laide et peut entraîner un fichier de conflit totalement inutilisable dans la situation où vous avez le plus besoin que ces choses soient présentées de manière cohérente.

Mark Rushakoff
la source
3
D'après mon expérience avec XML pour l'instant, il donne exactement les mêmes "mauvais" résultats qu'un diff normal.
stivlo
5
J'ai eu beaucoup plus de chance avec la patience avec XML; certes, le diff que je regarde actuellement a exactement le problème de désalignement décrit avec l'algorithme de diff régulier, mais il semble absolument grandiose avec la patience.
me_and
22
Ce blog a une grande explication, y compris un gif animé du processus: alfedenzo.livejournal.com/170301.html
Quantum7
3
J'ai trouvé ce blog très intéressant et fournissant de bonnes explications avec d'autres liens vers les détails des algorithmes: fabiensanglard.net/git_code_review/diff.php J'espère qu'il sera utile à quelqu'un
SathOkh
Le diff frobnitz / fib / fact peut être vu sur gist.github.com/roryokane/6f9061d3a60c1ba41237
George V. Reilly
52

Vous pouvez également l'utiliser pour les fusions (a très bien fonctionné ici pour certains conflits XML):

git merge --strategy-option=patience ...
Robinst
la source
51
Ou viagit config --global diff.algorithm patience
Tobu
11
Plus court serait git merge -X patience.
PythonNut
42

L'algorithme de différence de patience est un algorithme de différence plus lent qui montre de meilleurs résultats dans certains cas.

Supposons que vous ayez archivé le fichier suivant pour git:

.foo1 {
    margin: 0;
}

.bar {
    margin: 0;
}

Maintenant, nous réorganisons les sections et ajoutons une nouvelle ligne:

.bar {
    margin: 0;
}

.foo1 {
    margin: 0;
    color: green;
}

L'algorithme de différence par défaut prétend que les en-têtes de section ont changé:

$ git diff --diff-algorithm=myers   
diff --git a/example.css b/example.css
index 7f1bd1e..6a64c6f 100755
--- a/example.css
+++ b/example.css
@@ -1,7 +1,8 @@
-.foo1 {
+.bar {
     margin: 0;
 }

-.bar {
+.foo1 {
     margin: 0;
+    color: green;
 }

Alors que patience diff montre un résultat sans doute plus intuitif:

$ git diff --diff-algorithm=patience
diff --git a/example.css b/example.css
index 7f1bd1e..6a64c6f 100755
--- a/example.css
+++ b/example.css
@@ -1,7 +1,8 @@
-.foo1 {
-    margin: 0;
-}
-
 .bar {
     margin: 0;
 }
+
+.foo1 {
+    margin: 0;
+    color: green;
+}

Il y a une bonne discussion sur la qualité des différences subjectives ici , et git 2.11 explore davantage l'heuristique des différences .

Notez que l' algorithme de patience diff a encore quelques cas pathologiques connus .

Wilfred Hughes
la source