Para que serve o `git diff --patience`?

219

Como o algoritmo de paciência difere do git diffalgoritmo padrão e quando eu gostaria de usá-lo?

Gabe Moothart
fonte
1
Talvez ele corresponde código comovido e linhas modificadas que podem ser muito mais lento
codymanix
Eu extraí um script autônomo para Patience Diff do Bazaar, você pode encontrá-lo em outro tópico do SO .
TryPyPy
38
Uma pergunta de acompanhamento. Quando não devo usar a diferença de paciência?
balki
4
Há também o --histogramparâmetro que" ... se estende o algoritmo paciência para 'apoio de baixa ocorrência elementos comuns' git-scm.com/docs/git-diff.html
Robert

Respostas:

183

Você pode ler uma postagem de Bram Cohen , o autor do algoritmo diff de paciência, mas eu encontrei esta postagem no blog para resumir muito bem o algoritmo diff de paciência:

Em vez disso, a paciência Diff concentra sua energia nas linhas de alto conteúdo e baixa frequência que servem como marcadores ou assinaturas de conteúdo importante no texto. Ainda é um diferencial baseado em LCS em sua essência, mas com uma diferença importante, pois considera apenas a subsequência comum mais longa das linhas de assinatura:

Encontre todas as linhas que ocorrem exatamente uma vez em ambos os lados e faça a subsequência comum mais longa nessas linhas, combinando-as.

Quando você deve usar a diferença de paciência? Segundo Bram, a diferença de paciência é boa para esta situação:

Os casos realmente ruins são aqueles em que duas versões divergem dramaticamente e o desenvolvedor não está tomando cuidado para manter o tamanho dos patches sob controle. Nessas circunstâncias, um algoritmo diff pode ocasionalmente se tornar 'desalinhado', pois combina longas seções de colchetes, mas acaba correlacionando os colchetes de funções em uma versão com os colchetes da próxima função posterior na outra versão. Essa situação é muito feia e pode resultar em um arquivo de conflito totalmente inutilizável na situação em que você precisa que essas coisas sejam apresentadas de maneira coerente ao máximo.

Mark Rushakoff
fonte
3
Na minha experiência com XML por enquanto, ele fornece exatamente os mesmos resultados "ruins" que um diff normal.
23411 stivlo
5
Eu tive muito mais sorte com a paciência do XML; certamente o diff que estou vendo atualmente tem exatamente o problema de desalinhamento descrito com o algoritmo diff regular, mas parece absolutamente ótimo com o diff de paciência.
me_and
22
Este blog tem uma grande explicação, incluindo um GIF animado do processo: alfedenzo.livejournal.com/170301.html
Quantum7
3
Eu encontrei este blog muito interessante e proporcionando boa explicação com mais links para detalhes algoritmos: fabiensanglard.net/git_code_review/diff.php espero que seja útil para alguém
SathOkh
O frobnitz / fib / fact diff pode ser visto em gist.github.com/roryokane/6f9061d3a60c1ba41237
George V. Reilly
52

Você também pode usá-lo para mesclagens (funcionou muito bem aqui para alguns conflitos XML):

git merge --strategy-option=patience ...
robinst
fonte
51
Ou viagit config --global diff.algorithm patience
Tobu
11
Mais curto seria git merge -X patience.
PythonNut
42

O algoritmo diff de paciência é um algoritmo diff mais lento que mostra melhores resultados em alguns casos.

Suponha que você tenha o seguinte arquivo registrado no git:

.foo1 {
    margin: 0;
}

.bar {
    margin: 0;
}

Agora reordenamos as seções e adicionamos uma nova linha:

.bar {
    margin: 0;
}

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

O algoritmo diff padrão afirma que os títulos das seções foram alterados:

$ 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;
 }

Enquanto a paciência diff mostra um resultado que é sem dúvida mais intuitivo:

$ 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;
+}

uma boa discussão sobre a qualidade diff subjetiva aqui , e o git 2.11 está explorando ainda mais as heurísticas da diff .

Observe que o algoritmo diff de paciência ainda possui alguns casos patológicos conhecidos .

Wilfred Hughes
fonte