我在哪里可以找到实施的耐心差异?

时间:2013-04-17 17:22:57

标签: git version-control diff perforce

在这个网站上得到了很好的回答,Bram Cohen的耐心差异在集市中被发现为默认差异,并且作为git diff的一个选项,但我发现很难找到一个实现这种特殊diff算法的独立独立程序。

例如,我想将耐心差异应用于强制差异,并且使用规范的“frobnitz”代码示例非常清楚耐心差异如何更好:

enter image description here

右侧的终端已使用git diff标志调用--patience

我还设置了diff-highlight perl脚本,其作用是在这些行的第一个和最后一个不同部分之间的匹配行上反转颜色。左侧有一个例子,这对我说不太有帮助,但我会让它滑动,因为至少那里那个分号......无论如何,改进了diff-highlight脚本不是这个问题的主题。

除了在哪里找到独立的耐心差异之外,如果有人知道如何使perforce p4使用外部差异程序,那么这也是必须要做的事情。

5 个答案:

答案 0 :(得分:8)

它可能不像我想的那样理想,但从实用的角度来看解决方案是非常好的(这是一个非常好的观点)。

git diff --no-index --patience file1 file2完成这项工作。 (感谢@StevenPenny)

$P4DIFF变量定义了外部差异...我们只是将git diff --patience --no-index填入其中。

答案 1 :(得分:4)

我冒昧地将耐心移植到somewhat standalone library,它在C#中。这仍然是图书馆的早期日子。它主要是一个逐行端口;所以它希望拥有Python的大部分稳定性。

请记住,patience只能找到最长的公共子序列(在diff术语中,这意味着文件的一部分没有改变)。您需要determine the additions and removals yourself

还要记住,在Bazaar存储库中,还有Python和C语言的实现(同样,这些实现只能解决LCS问题):

  • C version:似乎重视性能而非清晰度,通过阅读本文,您将无法轻易理解算法。 Python互操作也有很多代码开销。
  • Python version:算法的参考实现。似乎主要关注绩效的清晰度。

如果您需要编写自己的实现,我建议首先移植Python版本,然后查看C实现以获取有关如何加速它的提示。

Git存储库中也应该有一个实现,但我还没有搜索过它。

答案 2 :(得分:3)

Cohen自己的Python实现只需要稍微调整(下面)就可以独立运行。它有两个文件,我用google搜索“difflib耐心”来抓住这些文件的副本:

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

第一个文件可以从命令行大致像diff一样运行。第二个是内部循环的Python实现。 (单个文件??为读者练习!)在bzrlib中,还有一个内部循环的C实现。

这里(在程序本身的帮助下)是我的补丁,让它们独立运行:

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$

答案 3 :(得分:1)

对于javascript实现,对PatienceDiff进行了增强,以确定可能移动的行(称为“ PatienceDiffPlus”),请参见https://github.com/jonTrent/PatienceDiff

答案 4 :(得分:0)

patiencediff的Bazaar实现也可以作为单独的Python模块使用。