[PATCH 3 of 3 RFC] import: add new --faithful flag to use metadata but relax checks

Augie Fackler raf at durin42.com
Fri Mar 11 13:25:50 EST 2016


# HG changeset patch
# User Augie Fackler <augie at google.com>
# Date 1457539063 18000
#      Wed Mar 09 10:57:43 2016 -0500
# Node ID 7d53477e4496e8f2b16b12ed445407e79bbb787b
# Parent  602504c64084d85820c883a43b02951a61e992f5
# EXP-Topic import
import: add new --faithful flag to use metadata but relax checks

Sometimes it's helpful to import a patch with as much of the metadata
(especially parents) intact as possible, but some bit of extra didn't
make the trip through the exported patch. This gives users a tool to
preserve as much metadata as possible without having to get an exact
byte-for-byte match on the import process.

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -935,7 +935,7 @@ def tryimportone(ui, repo, hunk, parents
 
         if len(parents) == 1:
             parents.append(repo[nullid])
-        if opts.get('exact'):
+        if opts.get('exact') or opts.get('faithful'):
             if not nodeid or not p1:
                 raise error.Abort(_('not a Mercurial patch'))
             p1 = repo[p1]
@@ -954,7 +954,8 @@ def tryimportone(ui, repo, hunk, parents
                 p1, p2 = parents
             if p2.node() == nullid:
                 ui.warn(_("warning: import the patch as a normal revision\n"
-                          "(use --exact to import the patch as a merge)\n"))
+                          "(use --exact or --faithful to import the patch "
+                          "as a merge)\n"))
         else:
             p1, p2 = parents
 
@@ -965,7 +966,7 @@ def tryimportone(ui, repo, hunk, parents
             if p2 != parents[1]:
                 repo.setparents(p1.node(), p2.node())
 
-            if opts.get('exact') or importbranch:
+            if opts.get('exact') or opts.get('faithful') or importbranch:
                 repo.dirstate.setbranch(branch or 'default')
 
             partial = opts.get('partial', False)
@@ -984,7 +985,7 @@ def tryimportone(ui, repo, hunk, parents
                 if message:
                     msgs.append(message)
             else:
-                if opts.get('exact') or p2:
+                if opts.get('exact') or opts.get('faithful') or p2:
                     # If you got here, you either use --force and know what
                     # you are doing or used --exact or a merge patch while
                     # being updated to its first parent.
@@ -992,7 +993,7 @@ def tryimportone(ui, repo, hunk, parents
                 else:
                     m = scmutil.matchfiles(repo, files or [])
                 editform = mergeeditform(repo[None], 'import.normal')
-                if opts.get('exact'):
+                if opts.get('exact') or opts.get('faithful'):
                     editor = None
                 else:
                     editor = getcommiteditor(editform=editform, **opts)
@@ -1011,7 +1012,7 @@ def tryimportone(ui, repo, hunk, parents
                 finally:
                     repo.ui.restoreconfig(allowemptyback)
         else:
-            if opts.get('exact') or importbranch:
+            if opts.get('exact') or opts.get('faithful') or importbranch:
                 branch = branch or 'default'
             else:
                 branch = p1.branch()
@@ -1023,7 +1024,7 @@ def tryimportone(ui, repo, hunk, parents
                                     files, eolmode=None)
                 except patch.PatchError as e:
                     raise error.Abort(str(e))
-                if opts.get('exact'):
+                if opts.get('exact') or opts.get('faithful'):
                     editor = None
                 else:
                     editor = getcommiteditor(editform='import.bypass')
@@ -1042,7 +1043,7 @@ def tryimportone(ui, repo, hunk, parents
             ui.warn(_("warning: can't check exact import with --no-commit\n"))
         elif opts.get('exact') and hex(n) != nodeid:
             raise error.Abort(_('patch is damaged or loses information'),
-                              hint=_('try again without --exact, as the data'
+                              hint=_('try again using --faithful, as the data'
                                      ' loss may be minor'))
         msg = _('applied to working directory')
         if n:
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -4683,6 +4683,8 @@ def identify(ui, repo, source=None, rev=
      _('commit even if some hunks fail')),
     ('', 'exact', None,
      _('abort if patch would apply lossily')),
+    ('', 'faithful', None,
+     _('use metadata like commit parent from patch header')),
     ('', 'prefix', '',
      _('apply patch to subdirectory'), _('DIR')),
     ('', 'import-branch', None,
diff --git a/tests/test-import-merge.t b/tests/test-import-merge.t
--- a/tests/test-import-merge.t
+++ b/tests/test-import-merge.t
@@ -73,7 +73,7 @@ Test without --exact and diff.p1 != work
   $ hg import ../merge.diff
   applying ../merge.diff
   warning: import the patch as a normal revision
-  (use --exact to import the patch as a merge)
+  (use --exact or --faithful to import the patch as a merge)
   $ tipparents
   2:890ecaa90481 addc
   $ hg strip --no-backup tip
@@ -108,7 +108,7 @@ Test with --bypass and diff.p1 != workin
   $ hg import --bypass ../merge.diff
   applying ../merge.diff
   warning: import the patch as a normal revision
-  (use --exact to import the patch as a merge)
+  (use --exact or --faithful to import the patch as a merge)
   $ tipparents
   2:890ecaa90481 addc
   $ hg strip --no-backup tip
@@ -156,7 +156,7 @@ Test that --exact on a bad header doesn'
   transaction abort!
   rollback completed
   abort: patch is damaged or loses information
-  (try again without --exact, as the data loss may be minor)
+  (try again using --faithful, as the data loss may be minor)
   [255]
   $ hg verify
   checking changesets
@@ -164,3 +164,18 @@ Test that --exact on a bad header doesn'
   crosschecking files in changesets and manifests
   checking files
   1 files, 2 changesets, 2 total revisions
+
+Using --faithful allows the slight damage to be imported:
+  $ hg revert --all
+  reverting a
+  $ hg import --faithful ../a.patch
+  applying ../a.patch
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  patching file a
+  Hunk #1 succeeded at 1 with fuzz 1 (offset -1 lines).
+  $ hg verify
+  checking changesets
+  checking manifests
+  crosschecking files in changesets and manifests
+  checking files
+  1 files, 3 changesets, 3 total revisions


More information about the Mercurial-devel mailing list