Patchwork [5,of,5] import: introduce --inexact

login
register
mail settings
Submitter timeless@mozdev.org
Date Dec. 30, 2015, 10:47 p.m.
Message ID <1d608b49e9ec5cec469d.1451515671@waste.org>
Download mbox | patch
Permalink /patch/12431/
State Superseded
Headers show

Comments

timeless@mozdev.org - Dec. 30, 2015, 10:47 p.m.
# HG changeset patch
# User timeless <timeless@mozdev.org>
# Date 1451509906 0
#      Wed Dec 30 21:11:46 2015 +0000
# Node ID 1d608b49e9ec5cec469d24b8d008f5accd806ed3
# Parent  a2350aab89ddc6ddffc556f8ecb0c2398ad348d8
import: introduce --inexact

This allows for a patch where the # Parent node is correct,
but the # Node is incorrect, allowing for memory based
grafting against alternative Nodes merely by doing:
hg export REV | rewrite Parent | hg import --inexact --bypass -

This is a poor man's cross between graft and rebase for
when your working directory is dirty.
Matt Mackall - Jan. 16, 2016, 6:16 p.m.
On Wed, 2015-12-30 at 16:47 -0600, timeless wrote:
> # HG changeset patch
> # User timeless <timeless@mozdev.org>
> # Date 1451509906 0
> #      Wed Dec 30 21:11:46 2015 +0000
> # Node ID 1d608b49e9ec5cec469d24b8d008f5accd806ed3
> # Parent  a2350aab89ddc6ddffc556f8ecb0c2398ad348d8
> import: introduce --inexact

There are so many timeless patches in my inbox that I've lost the plot on all of
them.

But I'm not excited by this one. My first question here would be: why doesn't --
bypass just work for this use case? Oh, because --bypass defaults to "." rather
than the patch parent without --exact.

> This allows for a patch where the # Parent node is correct,
> but the # Node is incorrect, allowing for memory based
> grafting against alternative Nodes merely by doing:
> hg export REV | rewrite Parent | hg import --inexact --bypass -

If that's your goal, wouldn't something like:

hg export REV | hg import --bypass --dest <somerev>

..be much better?

-- 
Mathematics is the supreme nostalgia of our time.
timeless - Jan. 17, 2016, 9:57 p.m.
Matt Mackall wrote:
> There are so many timeless patches in my inbox that I've lost the plot on all of
> them.

Sorry about that. Many of them aren't related. There were a few
attempts at a command for this one, but none of them were liked. Your
suggestion below sounds great.

> But I'm not excited by this one. My first question here would be: why doesn't --
> bypass just work for this use case? Oh, because --bypass defaults to "." rather
> than the patch parent without --exact.

Right.

>> This allows for a patch where the # Parent node is correct,
>> but the # Node is incorrect, allowing for memory based
>> grafting against alternative Nodes merely by doing:
>> hg export REV | rewrite Parent | hg import --inexact --bypass -
>
> If that's your goal, wouldn't something like:
>
> hg export REV | hg import --bypass --dest <somerev>
>
> ..be much better?

Yes. I can't send that before Wednesday, so I think I'll queue it
after the freeze.

Patch

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -888,7 +888,7 @@ 
 
     rejects = False
     exact = opts.get('exact')
-    usenode = exact
+    usenode = exact or opts.get('inexact')
 
     try:
         cmdline_message = logmessage(ui, opts)
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -4562,6 +4562,8 @@ 
      _('commit even if some hunks fail')),
     ('', 'exact', None,
      _('apply patch to the nodes from which it was generated')),
+    ('', 'inexact', None,
+     _('allow the patch to succeed even if the resulting Node differs')),
     ('', 'prefix', '',
      _('apply patch to subdirectory'), _('DIR')),
     ('', 'import-branch', None,
@@ -4604,6 +4606,9 @@ 
     the patch. This may happen due to character set problems or other
     deficiencies in the text patch format.
 
+    If --inexact is specified, import will set the working directory to
+    the parent of each patch before applying it.
+
     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
     written to a <target-file>.rej file. Conflicts can then be resolved
@@ -4671,6 +4676,7 @@ 
         opts['date'] = util.parsedate(date)
 
     exact = opts.get('exact')
+    inexact = opts.get('inexact')
     update = not opts.get('bypass')
     if not update and opts.get('no_commit'):
         raise error.Abort(_('cannot use --no-commit with --bypass'))
@@ -4687,6 +4693,11 @@ 
             raise error.Abort(_('cannot use --exact with --edit'))
         if opts.get('prefix'):
             raise error.Abort(_('cannot use --exact with --prefix'))
+    if inexact:
+        if opts.get('edit'):
+            raise error.Abort(_('cannot use --inexact with --edit'))
+        if opts.get('prefix'):
+            raise error.Abort(_('cannot use --inexact with --prefix'))
 
     base = opts["base"]
     wlock = dsguard = lock = tr = None
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
@@ -22,12 +22,15 @@ 
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
 
 Test importing an existing revision
-(this also tests that "hg import" disallows combination of '--exact'
-and '--edit')
+(this also tests that "hg import" disallows combination of '--edit'
+and '--exact'/'--inexact')
 
   $ hg import --bypass --exact --edit ../test.diff
   abort: cannot use --exact with --edit
   [255]
+  $ hg import --bypass --inexact --edit ../test.diff
+  abort: cannot use --inexact with --edit
+  [255]
   $ hg import --bypass --exact ../test.diff
   applying ../test.diff
   $ shortlog
@@ -195,6 +198,9 @@ 
   $ hg import --exact --prefix dir/ ../test.diff
   abort: cannot use --exact with --prefix
   [255]
+  $ hg import --inexact --prefix dir/ ../test.diff
+  abort: cannot use --inexact with --prefix
+  [255]
 
 Test commit editor
 (this also tests that editor is invoked, if the patch doesn't contain
@@ -306,6 +312,42 @@ 
   |/
   o  0:07f494440405 test 0 0 - default - adda
   
+Test --bypass --inexact
+Without bypass, another object by the same name would
+break imports.
+Exact insists the the Node of the constructed change
+matches that of the patch, but if you are grafting,
+you will not know that node, so you can not use it.
+
+  $ cat ../patch1.diff | \
+  > sed -e 's/07f4944404050f47db2e5c5071e0e84e7a27bba9/d60cb898966615f4364e3e58c880e12d0e651c7d/' \
+  > ../patch1.diff > ../patch1m.diff
+  $ mkdir e
+  $ hg import ../patch1m.diff
+  applying ../patch1m.diff
+  abort: Is a directory: $TESTTMP/repo-multi2/e
+  [255]
+  $ hg import --bypass --exact ../patch1m.diff
+  applying ../patch1m.diff
+  transaction abort!
+  rollback completed
+  abort: patch is damaged or loses information
+  [255]
+  $ hg import --bypass --inexact ../patch1m.diff
+  applying ../patch1m.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 ..