12

在这个网站上很好地回答了 Bram Cohen 的耐心差异在 bazaar 中作为默认差异和 git diff 的一个选项,但我发现很难找到一个独立的独立程序来实现这个特定的差异算法。

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

在此处输入图像描述

右边的终端调用了git diff带有--patience标志的 。

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

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

4

5 回答 5

8

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

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

$P4DIFF变量定义了外部差异......我们只是把git diff --patience --no-index它塞进去。

于 2013-04-17T18:09:45.833 回答
4

我冒昧地将耐心移植到一个有点独立的库中,它在 C# 中。图书馆还处于早期阶段。它主要是一个逐行端口;所以希望它具有 Python 的大部分稳定性。

请记住,耐心只会找到最长的公共子序列(在差异方面,这意味着文件中未更改的部分)。您将需要自己确定添加和删除

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

  • C 版本:似乎更看重性能而不是清晰度,通过阅读本文您将不容易理解算法。Python 互操作也有很多代码开销。
  • Python 版本:算法的参考实现。似乎主要看重清晰度而不是性能。

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

Git仓库里应该也有实现,但是我没有去搜。

于 2013-05-09T09:25:14.703 回答
3

Cohen 自己的 Python 实现只需要稍作调整(如下)即可独立运行。它在两个文件中,我通过谷歌搜索“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$
于 2014-01-11T01:15:56.963 回答
1

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

于 2019-07-26T23:57:19.187 回答
0

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

于 2018-08-02T17:05:31.593 回答