Patchwork [6,of,6,v2] import: relax import --exact if there is no # Node

login
register
mail settings
Submitter timeless@mozdev.org
Date Dec. 31, 2015, 6:47 a.m.
Message ID <b9f3eb03b1a009dc4a95.1451544440@waste.org>
Download mbox | patch
Permalink /patch/12445/
State Changes Requested
Delegated to: Yuya Nishihara
Headers show

Comments

timeless@mozdev.org - Dec. 31, 2015, 6:47 a.m.
# HG changeset patch
# User timeless <timeless@mozdev.org>
# Date 1451521862 0
#      Thu Dec 31 00:31:02 2015 +0000
# Node ID b9f3eb03b1a009dc4a95a063a612c816ee4821f4
# Parent  37c3ba3d2f3678daa5439947f20d89496282d8b0
import: relax import --exact if there is no # Node

This allows for a patch where the # Parent node is correct,
and # Node is ommitted, allowing for memory based
grafting against alternative Nodes merely by doing:
hg export REV | rewrite Parent | grep -v '# Node ' | \
hg import --exact --bypass -

This is a poor man's cross between graft and rebase for
when your working directory is dirty.
Yuya Nishihara - Jan. 3, 2016, 2:58 p.m.
On Thu, 31 Dec 2015 00:47:20 -0600, timeless wrote:
> # HG changeset patch
> # User timeless <timeless@mozdev.org>
> # Date 1451521862 0
> #      Thu Dec 31 00:31:02 2015 +0000
> # Node ID b9f3eb03b1a009dc4a95a063a612c816ee4821f4
> # Parent  37c3ba3d2f3678daa5439947f20d89496282d8b0
> import: relax import --exact if there is no # Node
> 
> This allows for a patch where the # Parent node is correct,
> and # Node is ommitted, allowing for memory based
> grafting against alternative Nodes merely by doing:
> hg export REV | rewrite Parent | grep -v '# Node ' | \
> hg import --exact --bypass -
> 
> This is a poor man's cross between graft and rebase for
> when your working directory is dirty.
> 
> diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
> --- a/mercurial/cmdutil.py
> +++ b/mercurial/cmdutil.py
> @@ -874,6 +874,7 @@
>      date = opts.get('date') or extractdata.get('date')
>      branch = extractdata.get('branch')
>      nodeid = extractdata.get('nodeid')
> +    hgpatch = extractdata.get('hgpatch')
>      p1 = extractdata.get('p1')
>      p2 = extractdata.get('p2')
>  
> @@ -906,7 +907,7 @@
>          if len(parents) == 1:
>              parents.append(repo[nullid])
>          if usenode:
> -            if not nodeid or not p1:
> +            if not p1 or not (nodeid or hgpatch):
>                  raise error.Abort(_('not a Mercurial patch'))

"hgpatch" flag won't be necessary.

This error was introduced by 47ba52121433 with --exact flag. So we can assume
that it checks if the patch has enough meta data to do exact commit. Because
this patch relaxes the --exact flag to allow missing nodeid, the remaining
requirement is "if not p1".

Patch

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -874,6 +874,7 @@ 
     date = opts.get('date') or extractdata.get('date')
     branch = extractdata.get('branch')
     nodeid = extractdata.get('nodeid')
+    hgpatch = extractdata.get('hgpatch')
     p1 = extractdata.get('p1')
     p2 = extractdata.get('p2')
 
@@ -906,7 +907,7 @@ 
         if len(parents) == 1:
             parents.append(repo[nullid])
         if usenode:
-            if not nodeid or not p1:
+            if not p1 or not (nodeid or hgpatch):
                 raise error.Abort(_('not a Mercurial patch'))
             p1 = repo[p1]
             p2 = repo[p2 or nullid]
@@ -1010,7 +1011,7 @@ 
             # --exact with --no-commit is still useful in that it does merge
             # and branch bits
             ui.warn(_("warning: can't check exact import with --no-commit\n"))
-        elif exact and hex(n) != nodeid:
+        elif exact and not (nodeid is None and hgpatch) and hex(n) != nodeid:
             raise error.Abort(_('patch is damaged or loses information'))
         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
@@ -4598,11 +4598,12 @@ 
     body. Values given on command line with -m/--message and -u/--user
     override these.
 
-    If --exact is specified, import will set the working directory to
-    the parent of each patch before applying it, and will abort if the
-    resulting changeset has a different ID than the one recorded in
-    the patch. This may happen due to character set problems or other
-    deficiencies in the text patch format.
+    If --exact is specified, import will apply the changes based on the
+    parent specified in each patch (setting the working directory
+    unless --bypass). If there is a `# Node ID ` line in the patch, it
+    will abort if the resulting changeset has a different Node ID.
+    This may happen due to character set problems or other deficiencies
+    in the text patch format.
 
     Use --partial to ensure a changeset will be created from the patch
     even if some hunks fail to apply. Hunks that fail to apply will be
diff --git a/tests/test-import-bypass.t b/tests/test-import-bypass.t
--- a/tests/test-import-bypass.t
+++ b/tests/test-import-bypass.t
@@ -306,6 +306,44 @@ 
   |/
   o  0:07f494440405 test 0 0 - default - adda
   
+Test --bypass --exact for a modified Parent node
+
+  $ cat ../patch1.diff | env \
+  > DEST=`hg log -r 3 --template '{node}'` \
+  > sh -c 'sed -e "s/^\(# Parent  \).*/\1$DEST/"' \
+  > ../patch1.diff > ../patch1m.diff
+  $ mkdir e
+  $ hg import ../patch1m.diff
+  applying ../patch1m.diff
+  abort: Is a directory: $TESTTMP/repo-multi2/e
+  [255]
+  $ rmdir e
+  $ echo a >> a
+  $ hg import ../patch1m.diff
+  abort: uncommitted changes
+  [255]
+  $ hg import --bypass --exact ../patch1m.diff
+  applying ../patch1m.diff
+  transaction abort!
+  rollback completed
+  abort: patch is damaged or loses information
+  [255]
+  $ egrep -v '^# Node ID ' ../patch1m.diff > ../patch1p.diff
+  $ hg import --bypass --exact ../patch1p.diff
+  applying ../patch1p.diff
+  $ shortlog
+  o  4:4e6b5d637a35 test 0 0 - default - adde
+  |
+  o  3:d60cb8989666 test 0 0 - foo - addf
+  |
+  | o  2:16581080145e test 0 0 - default - adde
+  | |
+  @ |  1:4e322f7ce8e3 test 0 0 - foo - changea
+  |/
+  o  0:07f494440405 test 0 0 - default - adda
+  
+  $ hg rollback
+  repository tip rolled back to revision 3 (undo import)
 
   $ cd ..