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

login
register
mail settings
Submitter Augie Fackler
Date March 11, 2016, 6:25 p.m.
Message ID <7d53477e4496e8f2b16b.1457720750@arthedain.pit.corp.google.com>
Download mbox | patch
Permalink /patch/13808/
State Accepted
Headers show

Comments

Augie Fackler - March 11, 2016, 6:25 p.m.
# HG changeset patch
# User Augie Fackler <augie@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.
Martin von Zweigbergk - March 11, 2016, 6:28 p.m.
On Fri, Mar 11, 2016 at 10:25 AM, Augie Fackler <raf@durin42.com> wrote:
> # HG changeset patch
> # User Augie Fackler <augie@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.

Yes, please! But it's unclear to me exactly what metadata it allows to
be lost. I would use it to make sure the parent is correct, so I know
there patches should apply cleanly. Anything else it will make sure is
correct?

>
> 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
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Augie Fackler - March 11, 2016, 7:57 p.m.
On Fri, Mar 11, 2016 at 1:28 PM, Martin von Zweigbergk
<martinvonz@google.com> wrote:
> On Fri, Mar 11, 2016 at 10:25 AM, Augie Fackler <raf@durin42.com> wrote:
>> # HG changeset patch
>> # User Augie Fackler <augie@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.
>
> Yes, please! But it's unclear to me exactly what metadata it allows to
> be lost. I would use it to make sure the parent is correct, so I know
> there patches should apply cleanly. Anything else it will make sure is
> correct?


I believe (but cannot promise) that it will ensure parents are
correct, and will bail as usual if the presented diff fails to apply.
It won't make sure things like branches or extra are correct, and if
the diff got mangled in transit in some way that happens to apply it
also won't catch that.

(--exact ensures that the imported commit is byte-for-byte identical
to the exported one, whereas --faithful is merely best-effort and
won't complain)
Pierre-Yves David - March 11, 2016, 8:11 p.m.
On 03/11/2016 06:25 PM, Augie Fackler wrote:
> # HG changeset patch
> # User Augie Fackler <augie@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.

In my opinion, the key part here is to:
1) bypass working copy
2) use the parent informations

I would rather see a name related to parents that "faithful". I don't 
"faithful" is very explicite and it mostly make sense in regards with 
--exact.


On a wider topic. I woudl rather see extra properly exported so that 
--exact get mostly useful than "yet another flag". But that another flag 
is probably needed as a fallback anyway so…

Cheers,
Sean Farley - March 11, 2016, 8:26 p.m.
Augie Fackler <raf@durin42.com> writes:

> # HG changeset patch
> # User Augie Fackler <augie@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.

It's unclear to me that we need a new option for this. As a user, the
presence of --partial, --exact, and --import-branch is a bit overloaded.
I have many times wondered why as much as possible metadata isn't
already imported and why --no-commit or --partial don't relax those
checks already.
Augie Fackler - March 11, 2016, 9:12 p.m.
On Fri, Mar 11, 2016 at 3:11 PM, Pierre-Yves David
<pierre-yves.david@ens-lyon.org> wrote:
>
>
> On 03/11/2016 06:25 PM, Augie Fackler wrote:
>>
>> # HG changeset patch
>> # User Augie Fackler <augie@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.
>
>
> In my opinion, the key part here is to:
> 1) bypass working copy
> 2) use the parent informations
>
> I would rather see a name related to parents that "faithful". I don't
> "faithful" is very explicite and it mostly make sense in regards with
> --exact.

I'm not in love with the name "faithful", so I'd love constructive
suggestions about what we could name the flag.

>
>
> On a wider topic. I woudl rather see extra properly exported so that --exact
> get mostly useful than "yet another flag". But that another flag is probably
> needed as a fallback anyway so…

Yes, the diff format is known to be lossy, so even when you're
exporting changeset extra perfectly, you're still going to have
problems where diff (even git-diff) loses some data, and something
like --exact that doesn't verify nodeids is really what you need.
Pierre-Yves David - March 27, 2016, 6:16 p.m.
On 03/11/2016 01:12 PM, Augie Fackler wrote:
> On Fri, Mar 11, 2016 at 3:11 PM, Pierre-Yves David
> <pierre-yves.david@ens-lyon.org> wrote:
>>
>>
>> On 03/11/2016 06:25 PM, Augie Fackler wrote:
>>>
>>> # HG changeset patch
>>> # User Augie Fackler <augie@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.
>>
>>
>> In my opinion, the key part here is to:
>> 1) bypass working copy
>> 2) use the parent informations

I'm not sure we should automatically turn the bypassing here. Having a 
flag that make sure a patch is applied on parent.

(On the same "perpendicular" but important topic, there is the question 
of updating on the result or not).

>> I would rather see a name related to parents that "faithful". I don't
>> "faithful" is very explicite and it mostly make sense in regards with
>> --exact.
>
> I'm not in love with the name "faithful", so I'd love constructive
> suggestions about what we could name the flag.

The important part here is the fact we read and use the parent 
information in the patch. So I think having "parent" in the name make sense:

   --originalparents
   --useparents
   --onparents
   --parents
   --onorigin

I think --useparents is my favorite but I don't have a strong opinion.

Cheers,
Matt Mackall - April 12, 2016, 11:59 p.m.
On Tue, 2016-03-29 at 09:23 -0500, Kevin Bullock wrote:
> > 
> > On Mar 27, 2016, at 13:16, Pierre-Yves David <pierre-yves.david@ens-lyon.org
> > > wrote:
> > 
> > On 03/11/2016 01:12 PM, Augie Fackler wrote:
> > > 
> > > On Fri, Mar 11, 2016 at 3:11 PM, Pierre-Yves David
> > > <pierre-yves.david@ens-lyon.org> wrote:
> > > > 
> > > > 
> > > > 
> > > > On 03/11/2016 06:25 PM, Augie Fackler wrote:
> > > > > 
> > > > > 
> > > > > # HG changeset patch
> > > > > # User Augie Fackler <augie@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.
> > > > 
> > > > In my opinion, the key part here is to:
> > > > 1) bypass working copy
> > > > 2) use the parent informations
> > I'm not sure we should automatically turn the bypassing here. Having a flag
> > that make sure a patch is applied on parent.
> > 
> > (On the same "perpendicular" but important topic, there is the question of
> > updating on the result or not).
> > 
> > > 
> > > > 
> > > > I would rather see a name related to parents that "faithful". I don't
> > > > "faithful" is very explicite and it mostly make sense in regards with
> > > > --exact.
> > > I'm not in love with the name "faithful", so I'd love constructive
> > > suggestions about what we could name the flag.
> > The important part here is the fact we read and use the parent information
> > in the patch. So I think having "parent" in the name make sense:
> > 
> >  --originalparents
> >  --useparents
> >  --onparents
> >  --parents
> >  --onorigin
> > 
> > I think --useparents is my favorite but I don't have a strong opinion.
> It seems like we have three classes of metadata here:
> 
> 1. user, date, description, branch name - always imported, no problems here

There's definitely a set of stuff we do ok at, yes.

> 2. node id + original parent (others?) - can be used as hints in importing

This is probably one of the key things that makes this confusing. Some people
are using --exact not because they care about exactitude, but because they want
to preserve topology when they're moving commits.

This turns out to be hard.. as soon as you think about the SECOND import. If
you've failed to exactly preserve the hash, the second import's parent won't
exist (sad trombone). So --faithful as implemented here ends up disappointing.

Which is why parents has always been tied to --exact. Even though --exact isn't
"about" parents per se, it was always the only -possible- way to preserve the
DAG topology with import/export.

But obsmarkers actually might allow us to do something reasonable here by
importing the second commit onto the successor of whatever it thinks its parent
should be. If we do something in that direction, we could have an option like --
topo ("preserve topology").

> 3. extra data that is part of the commit hash but not the patch - causes
> problems with --exact

We should try harder here (probably by default), but it'll be a long way from
perfect because:

4. the numerous classic and git diff corner cases
   - linefeed style
   - empty vs missing files
   - exec bits and symlinks
   - funky filenames
   - merge/copy/rename cases that git doesn't care about
   - etc.

5. the numerous edges of our own metadata hashing
   - dates with floating point seconds
   - unsorted extra
   - unsorted file-level metadata
   - pre-UTF8 commits
   - etc.

6. all the awful things that email clients do


And it's unlikely we'll fix all of those.. ever.

-- 
Mathematics is the supreme nostalgia of our time.
Matt Mackall - April 13, 2016, 12:01 a.m.
On Fri, 2016-03-11 at 12:26 -0800, Sean Farley wrote:
> Augie Fackler <raf@durin42.com> writes:
> 
> > 
> > # HG changeset patch
> > # User Augie Fackler <augie@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.
> It's unclear to me that we need a new option for this. As a user, the
> presence of --partial, --exact, and --import-branch is a bit overloaded.
> I have many times wondered why as much as possible metadata isn't
> already imported and why --no-commit or --partial don't relax those
> checks already.

A very common use-case for import is cherry-picking. Importing topology or
branch name data by default would actively break that use case, a major BC. 

-- 
Mathematics is the supreme nostalgia of our time.

Patch

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