2013-04-17 10 views
10

In questo sito è ben risposto che il diff di pazienza di Bram Cohen si trova in bazaar come diff predefinito e come opzione con git diff, ma trovo difficile trovare un programma autonomo indipendente che implementa questo particolare algoritmo di diff.Dove posso trovare la differenza di pazienza implementata?

Per esempio mi piacerebbe applicare la pazienza diff per per forza diff, ed è abbastanza chiaro con la "frobnitz" esempio canonico di codice come la pazienza diff è meglio:

enter image description here

Il terminale a destra ha invocato lo git diff con il flag --patience.

Ho anche impostato lo script perl diff-highlight, il cui compito è quello di invertire i colori su linee abbinate tra la prima e l'ultima sezione diversa di quelle linee. Il lato sinistro ha un esempio in cui questo non aiuta molto ma lo lascio scorrere perché almeno lo è quel punto e virgola ... Comunque, apportare miglioramenti allo script di evidenziazione diff non è l'argomento di questa domanda.

In aggiunta alla domanda su dove trovare una differenza di pazienza standalone, se qualcuno sa come forzare p4 utilizzare un programma diff esterno, anche questo è qualcosa che deve essere fatto.

+0

cosa, io uso git per passare su due file? sembra solo brutto. Non è mai successo a me. Ora vedo che funziona abbastanza bene e lo userò sicuramente. Ma molti sistemi non hanno git installato ... –

risposta

8

Forse non è l'ideale come mi piacerebbe, ma la soluzione è perfettamente valida dal punto di vista pratico (e questa è una prospettiva dannatamente buona da avere).

git diff --no-index --patience file1 file2 fa il lavoro. (grazie a @StevenPenny)

$P4DIFF variabile definisce la differenza esterna ... abbiamo appena roba git diff --patience --no-index in quello.

4

Mi sono preso la libertà di portare pazienza a un somewhat standalone library, è in C#. È ancora presto per la biblioteca. È principalmente un porto linea per linea; quindi si spera che abbia la maggior parte della stabilità di Python.

Ricordare che patience trova solo le sottosequenze più lunghe comuni (in termini di differenza che indica parti del file che non sono state modificate). Avrai bisogno di determine the additions and removals yourself.

Ricordiamo inoltre che all'interno del repository Bazaar ci sono anche implementazioni in Python e in C (ancora una volta, le implementazioni risolvere solo il problema LCS):

  • C version: sembra di valutare le prestazioni sopra la chiarezza, hai vinto' t facilmente essere in grado di capire l'algoritmo leggendo questo. C'è anche un sacco di code-overhead per l'interoperabilità di Python.
  • Python version: l'implementazione di riferimento dell'algoritmo. Sembra apprezzare soprattutto la chiarezza sulle prestazioni.

Se è necessario scrivere la propria implementazione, consigliamo di eseguire prima il porting della versione Python, quindi esaminare l'implementazione C per suggerimenti su come accelerarlo.

Ci dovrebbe essere anche un'implementazione nel repository Git, ma non l'ho cercata.

+0

Da allora mi sono spostato su un'implementazione di carattere per carattere in C++ trovato [qui] (http://code.google.com/p/google-diff- match-patch/issues/detail? id = 25), insieme a molti miglioramenti (utf8 e binari) dei miei. L'ho soprannominato 'sift'. Speriamo che un giorno sarà rivelato al mondo. Grazie per aver condiviso la tua versione però! (Il mio potrebbe davvero fallire nel fare una vera pazienza-diff, benché si comporti bene nell'esempio di frobnitz) –

+0

Piacere @StevenLu, felice che tu abbia fatto bene. Sarei interessato a sapere quali sono gli effetti di alcuni dei miglioramenti apportati (se hai aperto dei problemi sul progetto GitHub). –

+0

realtà ho appena scoperto questo: https://github.com/leutloff/diff-match-patch-cpp-stl Ora quello che ho è basato fuori la versione leggermente più vecchio sulla base di 'wstring' ed ero in grado di correttamente convertirlo per usare 'string'. Tuttavia non ritengo che gran parte di una limitazione in quanto supporta completamente utf8 (e io non sono sicuro di quanto bene una vasta 'implementazione non STRING' in grado di gestire utf8 in un modo che è a conoscenza dei punti di codice). –

3

L'implementazione Python di Python richiede solo piccole modifiche (di seguito) per l'esecuzione autonoma.E 'in due file, copie dei quali ho portato a casa da googling "pazienza difflib":

http://stuff.mit.edu/afs/athena/system/i386_deb50/os/usr/share/pyshared/bzrlib/patiencediff.py e http://stuff.mit.edu/afs/athena/system/i386_deb50/os/usr/share/pyshared/bzrlib/_patiencediff_py.py

Il primo file può essere eseguito da linea di comando o meno così diff. Il secondo è l'implementazione Python dei loop interni. (File singolo ?? Esercizio per lettore!) In bzrlib c'è anche un'implementazione C dei loop interni.

Qui (con l'aiuto del programma stesso) sono le mie patch per farli funzionare standalone: ​​

Sandy$ patiencediff.py --patience orig/patiencediff.py patiencediff.py 
--- orig/patiencediff.py 
+++ patiencediff.py 
@@ -15,14 +15,20 @@ 
# along with this program; if not, write to the Free Software 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 

+try: 
+ from bzrlib.lazy_import import lazy_import 
+ lazy_import(globals(), """ 
+ import os 
+ import sys 
+ import time 
+ import difflib 
+ """) 
+except: 
+ import os 
+ import sys 
+ import time 
+ import difflib 

-from bzrlib.lazy_import import lazy_import 
-lazy_import(globals(), """ 
-import os 
-import sys 
-import time 
-import difflib 
-""") 


__all__ = ['PatienceSequenceMatcher', 'unified_diff', 'unified_diff_files'] 
@@ -135,11 +141,18 @@ 
     PatienceSequenceMatcher_c as PatienceSequenceMatcher 
     ) 
except ImportError: 
- from bzrlib._patiencediff_py import (
-  unique_lcs_py as unique_lcs, 
-  recurse_matches_py as recurse_matches, 
-  PatienceSequenceMatcher_py as PatienceSequenceMatcher 
-  ) 
+ try: 
+  from bzrlib._patiencediff_py import (
+   unique_lcs_py as unique_lcs, 
+   recurse_matches_py as recurse_matches, 
+   PatienceSequenceMatcher_py as PatienceSequenceMatcher 
+   ) 
+ except ImportError: 
+  from _patiencediff_py import (
+   unique_lcs_py as unique_lcs, 
+   recurse_matches_py as recurse_matches, 
+   PatienceSequenceMatcher_py as PatienceSequenceMatcher 
+   ) 


def main(args): 
Sandy$ patiencediff.py --patience orig/_patiencediff_py.py _patiencediff_py.py 
--- orig/_patiencediff_py.py 
+++ _patiencediff_py.py 
@@ -15,11 +15,16 @@ 
# along with this program; if not, write to the Free Software 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 

- 
+from __future__ import print_function 
from bisect import bisect 
import difflib 

-from bzrlib.trace import mutter 
+try: 
+ from bzrlib.trace import mutter 
+except: 
+ import sys 
+ def mutter(msg): 
+  print (msg, file=sys.stderr) 


__all__ = ['PatienceSequenceMatcher', 'unified_diff', 'unified_diff_files'] 
Sandy$ 
+0

Questo è perfetto - grazie! Non vedo la patch versione standalone su TIAC o GitHub - l'hai postata ovunque? Se no, lo farò quando avrò la possibilità :). – cxw

+0

Non ho ancora una copia del file con patch, ma credo che si possa applicare la patch sopra all'originale usando l'utility "patch". – FutureNerd

+0

E ho perso parte della tua domanda. No, non li ho mai combinati in un singolo file. – FutureNerd

Problemi correlati