[PATCH] patch: deprecate ui.patch / external patcher feature

Patrick Mezard pmezard at gmail.com
Tue Mar 22 16:29:37 CDT 2011


# HG changeset patch
# User Patrick Mezard <pmezard at gmail.com>
# Date 1300829287 -3600
# Node ID 297d013ac291ded7aba00f6e8f802fcdfe55c1a0
# Parent  7f53ce232d638ee55dcae1f57ebb1e5f250e95b6
patch: deprecate ui.patch / external patcher feature

Why?
- Mercurial internal patcher works correctly for regular patches and git
  patches, is much faster at least on Windows and is more extensible.
- In theory, the external patcher can be used to handle exotic patch formats. I
  do not know any and have not heard about any such use in years.
- Most patch programs cannot handle git format patches, which makes the API
  caller to decide either to ignore ui.patch by calling patch.internalpatch()
  directly, or take the risk of random failures with valid inputs.
- One thing a patch program could do Mercurial patcher cannot is applying with
  --reverse. Apparently several shelve like extensions try to use that,
  including passing the "reverse" option to Mercurial patcher, which has been
  removed mid-2009. I never heard anybody complain about that, and would prefer
  reimplementing it anyway.

And from the technical perspective:
- The external patcher makes everything harder to maintain and implement. EOL
  normalization is not implemented, and I would bet file renames, if supported
  by the patcher, are not correctly recorded in the dirstate.
- No tests.

How?
- Remove related documentation
- Clearly mark patch.externalpatch() as private
- Remove the debuginstall check. This deprecation request was actually
  triggered by this last point. debuginstall is the only piece of code patching
  without a repository. When migrating to an integrated patch() + updatedir()
  call, this was really a showstopper, all workarounds were either ugly or
  uselessly complicated to implement. If we do not support external patcher
  anymore, the debuginstall check is not useful anymore.
- Remove patch.externalpatch() after 1.9 release.

diff -r 7f53ce232d63 -r 297d013ac291 doc/hgrc.5.txt
--- a/doc/hgrc.5.txt	Sun Mar 20 20:17:57 2011 -0500
+++ b/doc/hgrc.5.txt	Tue Mar 22 22:28:07 2011 +0100
@@ -911,9 +911,6 @@
     The conflict resolution program to use during a manual merge.
     For more information on merge tools see :hg:`help merge-tools`.
     For configuring merge tools see the merge-tools_ section.
-``patch``
-    command to use to apply patches. Look for ``gpatch`` or ``patch`` in
-    PATH if unset.
 ``quiet``
     Reduce the amount of output printed. True or False. Default is False.
 ``remotecmd``
diff -r 7f53ce232d63 -r 297d013ac291 mercurial/commands.py
--- a/mercurial/commands.py	Sun Mar 20 20:17:57 2011 -0500
+++ b/mercurial/commands.py	Tue Mar 22 22:28:07 2011 +0100
@@ -1484,45 +1484,6 @@
         ui.write(_(" (templates seem to have been installed incorrectly)\n"))
         problems += 1
 
-    # patch
-    ui.status(_("Checking patch...\n"))
-    patchproblems = 0
-    a = "1\n2\n3\n4\n"
-    b = "1\n2\n3\ninsert\n4\n"
-    fa = writetemp(a)
-    d = mdiff.unidiff(a, None, b, None, os.path.basename(fa),
-        os.path.basename(fa))
-    fd = writetemp(d)
-
-    files = {}
-    try:
-        patch.patch(fd, ui, cwd=os.path.dirname(fa), files=files)
-    except util.Abort, e:
-        ui.write(_(" patch call failed:\n"))
-        ui.write(" " + str(e) + "\n")
-        patchproblems += 1
-    else:
-        if list(files) != [os.path.basename(fa)]:
-            ui.write(_(" unexpected patch output!\n"))
-            patchproblems += 1
-        a = open(fa).read()
-        if a != b:
-            ui.write(_(" patch test failed!\n"))
-            patchproblems += 1
-
-    if patchproblems:
-        if ui.config('ui', 'patch'):
-            ui.write(_(" (Current patch tool may be incompatible with patch,"
-                       " or misconfigured. Please check your configuration"
-                       " file)\n"))
-        else:
-            ui.write(_(" Internal patcher failure, please report this error"
-                       " to http://mercurial.selenic.com/wiki/BugTracker\n"))
-    problems += patchproblems
-
-    os.unlink(fa)
-    os.unlink(fd)
-
     # editor
     ui.status(_("Checking commit editor...\n"))
     editor = ui.geteditor()
diff -r 7f53ce232d63 -r 297d013ac291 mercurial/patch.py
--- a/mercurial/patch.py	Sun Mar 20 20:17:57 2011 -0500
+++ b/mercurial/patch.py	Tue Mar 22 22:28:07 2011 +0100
@@ -1156,7 +1156,7 @@
         return -1
     return err
 
-def externalpatch(patcher, patchname, ui, strip, cwd, files):
+def _externalpatch(patcher, patchname, ui, strip, cwd, files):
     """use <patcher> to apply <patchname> to the working directory.
     returns whether patch was applied with fuzz factor."""
 
@@ -1240,7 +1240,7 @@
         files = {}
     try:
         if patcher:
-            return externalpatch(patcher, patchname, ui, strip, cwd, files)
+            return _externalpatch(patcher, patchname, ui, strip, cwd, files)
         return internalpatch(patchname, ui, strip, cwd, files, eolmode)
     except PatchError, err:
         raise util.Abort(str(err))
diff -r 7f53ce232d63 -r 297d013ac291 tests/test-install.t
--- a/tests/test-install.t	Sun Mar 20 20:17:57 2011 -0500
+++ b/tests/test-install.t	Tue Mar 22 22:28:07 2011 +0100
@@ -3,7 +3,6 @@
   Checking encoding (ascii)...
   Checking installed modules (*/mercurial)... (glob)
   Checking templates...
-  Checking patch...
   Checking commit editor...
   Checking username...
   No problems detected
@@ -13,7 +12,6 @@
   Checking encoding (ascii)...
   Checking installed modules (*/mercurial)... (glob)
   Checking templates...
-  Checking patch...
   Checking commit editor...
   Checking username...
    no username supplied (see "hg help config")


More information about the Mercurial-devel mailing list