Patchwork [3,of,4,V3] update: also suggest --merge when non-linear update is aborted

login
register
mail settings
Submitter via Mercurial-devel
Date Feb. 15, 2017, 8:56 p.m.
Message ID <c6cd58d272aee6633fba.1487192201@martinvonz.mtv.corp.google.com>
Download mbox | patch
Permalink /patch/18513/
State Superseded
Headers show

Comments

via Mercurial-devel - Feb. 15, 2017, 8:56 p.m.
# HG changeset patch
# User Martin von Zweigbergk <martinvonz@google.com>
# Date 1487140898 28800
#      Tue Feb 14 22:41:38 2017 -0800
# Node ID c6cd58d272aee6633fbad5eacdad742e2f9909cd
# Parent  542a99ede6c3ac7cb4afccd3703fcc30e3d4c90d
update: also suggest --merge when non-linear update is aborted
Augie Fackler - Feb. 15, 2017, 10:25 p.m.
On Wed, Feb 15, 2017 at 12:56:41PM -0800, Martin von Zweigbergk via Mercurial-devel wrote:
> # HG changeset patch
> # User Martin von Zweigbergk <martinvonz@google.com>
> # Date 1487140898 28800
> #      Tue Feb 14 22:41:38 2017 -0800
> # Node ID c6cd58d272aee6633fbad5eacdad742e2f9909cd
> # Parent  542a99ede6c3ac7cb4afccd3703fcc30e3d4c90d
> update: also suggest --merge when non-linear update is aborted

This makes me a touch nervous, since the merge can leave the user in
an state that's hard to recover from.

Series LG otherwise, but I won't land it since I'm also enthusiastic
about the feature added in patch 4.

>
> diff -r 542a99ede6c3 -r c6cd58d272ae mercurial/merge.py
> --- a/mercurial/merge.py	Mon Feb 13 16:03:05 2017 -0800
> +++ b/mercurial/merge.py	Tue Feb 14 22:41:38 2017 -0800
> @@ -1570,7 +1570,8 @@
>                          pass # allow updating to successors
>                      else:
>                          msg = _("uncommitted changes")
> -                        hint = _("commit or update --clean to discard changes")
> +                        hint = _("commit, or use --clean to discard changes, "
> +                                 "or use --merge to allow update")
>                          raise error.UpdateAbort(msg, hint=hint)
>                  else:
>                      # Allow jumping branches if clean and specific rev given
> diff -r 542a99ede6c3 -r c6cd58d272ae tests/test-merge5.t
> --- a/tests/test-merge5.t	Mon Feb 13 16:03:05 2017 -0800
> +++ b/tests/test-merge5.t	Tue Feb 14 22:41:38 2017 -0800
> @@ -26,7 +26,7 @@
>
>    $ hg update 1
>    abort: uncommitted changes
> -  (commit or update --clean to discard changes)
> +  (commit, or use --clean to discard changes, or use --merge to allow update)
>    [255]
>    $ mv c a
>
> diff -r 542a99ede6c3 -r c6cd58d272ae tests/test-subrepo-svn.t
> --- a/tests/test-subrepo-svn.t	Mon Feb 13 16:03:05 2017 -0800
> +++ b/tests/test-subrepo-svn.t	Tue Feb 14 22:41:38 2017 -0800
> @@ -472,7 +472,7 @@
>    $ echo "updating should (maybe) fail" > obstruct/other
>    $ hg co tip
>    abort: uncommitted changes
> -  (commit or update --clean to discard changes)
> +  (commit, or use --clean to discard changes, or use --merge to allow update)
>    [255]
>
>  Point to a Subversion branch which has since been deleted and recreated
> diff -r 542a99ede6c3 -r c6cd58d272ae tests/test-update-branches.t
> --- a/tests/test-update-branches.t	Mon Feb 13 16:03:05 2017 -0800
> +++ b/tests/test-update-branches.t	Tue Feb 14 22:41:38 2017 -0800
> @@ -123,19 +123,19 @@
>
>    $ revtest 'none dirty same'   dirty 2 3
>    abort: uncommitted changes
> -  (commit or update --clean to discard changes)
> +  (commit, or use --clean to discard changes, or use --merge to allow update)
>    parent=2
>    M foo
>
>    $ revtest 'none dirtysub same'   dirtysub 2 3
>    abort: uncommitted changes
> -  (commit or update --clean to discard changes)
> +  (commit, or use --clean to discard changes, or use --merge to allow update)
>    parent=2
>    M sub/suba
>
>    $ revtest 'none dirty cross'  dirty 3 4
>    abort: uncommitted changes
> -  (commit or update --clean to discard changes)
> +  (commit, or use --clean to discard changes, or use --merge to allow update)
>    parent=3
>    M foo
>
> @@ -147,7 +147,7 @@
>
>    $ revtest 'none dirtysub cross'  dirtysub 3 4
>    abort: uncommitted changes
> -  (commit or update --clean to discard changes)
> +  (commit, or use --clean to discard changes, or use --merge to allow update)
>    parent=3
>    M sub/suba
>
> @@ -258,7 +258,7 @@
>
>    $ revtest 'dirty cross'  dirty 3 4
>    abort: uncommitted changes
> -  (commit or update --clean to discard changes)
> +  (commit, or use --clean to discard changes, or use --merge to allow update)
>    parent=3
>    M foo
>
> @@ -476,7 +476,7 @@
>    $ hg up --quiet 2
>    $ hg up 5
>    abort: uncommitted changes
> -  (commit or update --clean to discard changes)
> +  (commit, or use --clean to discard changes, or use --merge to allow update)
>    [255]
>
>  Test that we don't crash when updating from a pruned changeset (i.e. has no
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Augie Fackler - Feb. 21, 2017, 4:08 p.m.
> On Feb 20, 2017, at 05:38, Gábor STEFANIK <Gabor.STEFANIK@nng.com> wrote:
> 
>> On Wed, Feb 15, 2017 at 12:56:41PM -0800, Martin von Zweigbergk via
>> Mercurial-devel wrote:
>>> # HG changeset patch
>>> # User Martin von Zweigbergk <martinvonz@google.com> # Date
>> 1487140898
>>> 28800
>>> #      Tue Feb 14 22:41:38 2017 -0800
>>> # Node ID c6cd58d272aee6633fbad5eacdad742e2f9909cd
>>> # Parent  542a99ede6c3ac7cb4afccd3703fcc30e3d4c90d
>>> update: also suggest --merge when non-linear update is aborted
>> 
>> This makes me a touch nervous, since the merge can leave the user in an
>> state that's hard to recover from.
> 
> Basically "hg resolve -au; hg resolve -at:local; hg update --merge -r$(head -c40 .hg/merge/state) -t:local"; but we need to expose a less hacky way of doing so. 

Not quite, because this isn't sure (I don't think) to get you back to exactly the pre-update-command state, as some files might have been merged behind your back?

> 
> "hg update --abort"?

I'd be a big fan of having an update --abort that just takes you back to where you were before the conflicts. To date, nobody has been motivated enough to do the work (I'd love to do it, but it's unlikely to be near the top of my stack for months/years).
Martin von Zweigbergk - Feb. 21, 2017, 5:09 p.m.
I agree with leaving this patch out until we have a better way of aborting.
I think I put it last in the V4, so it should be easy to skip. Thanks.

On Tue, Feb 21, 2017, 08:07 Augie Fackler <raf@durin42.com> wrote:

>
> > On Feb 20, 2017, at 05:38, Gábor STEFANIK <Gabor.STEFANIK@nng.com>
> wrote:
> >
> >> On Wed, Feb 15, 2017 at 12:56:41PM -0800, Martin von Zweigbergk via
> >> Mercurial-devel wrote:
> >>> # HG changeset patch
> >>> # User Martin von Zweigbergk <martinvonz@google.com> # Date
> >> 1487140898
> >>> 28800
> >>> #      Tue Feb 14 22:41:38 2017 -0800
> >>> # Node ID c6cd58d272aee6633fbad5eacdad742e2f9909cd
> >>> # Parent  542a99ede6c3ac7cb4afccd3703fcc30e3d4c90d
> >>> update: also suggest --merge when non-linear update is aborted
> >>
> >> This makes me a touch nervous, since the merge can leave the user in an
> >> state that's hard to recover from.
> >
> > Basically "hg resolve -au; hg resolve -at:local; hg update --merge
> -r$(head -c40 .hg/merge/state) -t:local"; but we need to expose a less
> hacky way of doing so.
>
> Not quite, because this isn't sure (I don't think) to get you back to
> exactly the pre-update-command state, as some files might have been merged
> behind your back?
>
> >
> > "hg update --abort"?
>
> I'd be a big fan of having an update --abort that just takes you back to
> where you were before the conflicts. To date, nobody has been motivated
> enough to do the work (I'd love to do it, but it's unlikely to be near the
> top of my stack for months/years).
Jun Wu - Feb. 21, 2017, 10:15 p.m.
Excerpts from Augie Fackler's message of 2017-02-21 11:08:05 -0500:
> > "hg update --abort"?
> 
> I'd be a big fan of having an update --abort that just takes you back to
> where you were before the conflicts. To date, nobody has been motivated
> enough to do the work (I'd love to do it, but it's unlikely to be near the
> top of my stack for months/years).

I think that could be hard if the user do touch some files being updated -
it seems to me like a "recursive" update/merge situation, that requires
comprehensive transaction support which works for non-append-only files (and
maybe directories).

My intuition is that it's impossible to implement such fancy transaction
cleanly with the POSIX APIs, unless we control the filesystem (like fuse
etc). So I'd prefer simple and straightfoward solutions. "update --clean" to
go back looks good enough to me.
Denis Laxalde - Feb. 22, 2017, 7:55 a.m.
Augie Fackler a écrit :
> On Wed, Feb 15, 2017 at 12:56:41PM -0800, Martin von Zweigbergk via Mercurial-devel wrote:
>> # HG changeset patch
>> # User Martin von Zweigbergk <martinvonz@google.com>
>> # Date 1487140898 28800
>> #      Tue Feb 14 22:41:38 2017 -0800
>> # Node ID c6cd58d272aee6633fbad5eacdad742e2f9909cd
>> # Parent  542a99ede6c3ac7cb4afccd3703fcc30e3d4c90d
>> update: also suggest --merge when non-linear update is aborted
> This makes me a touch nervous, since the merge can leave the user in
> an state that's hard to recover from.

Couldn't we instead point the user to "shelve" their changes? (I seem to
recall that suggesting a command from an extension is not "usual" in a
core command, but, in this very case, it looks like the most sensible
thing to do IMHO).
Matt Harbison - Feb. 25, 2017, 6:34 p.m.
On Tue, 21 Feb 2017 11:08:05 -0500, Augie Fackler <raf@durin42.com> wrote:

>
>> On Feb 20, 2017, at 05:38, Gábor STEFANIK <Gabor.STEFANIK@nng.com>  
>> wrote:
>>
>>> On Wed, Feb 15, 2017 at 12:56:41PM -0800, Martin von Zweigbergk via
>>> Mercurial-devel wrote:
>>>> # HG changeset patch
>>>> # User Martin von Zweigbergk <martinvonz@google.com> # Date
>>> 1487140898
>>>> 28800
>>>> #      Tue Feb 14 22:41:38 2017 -0800
>>>> # Node ID c6cd58d272aee6633fbad5eacdad742e2f9909cd
>>>> # Parent  542a99ede6c3ac7cb4afccd3703fcc30e3d4c90d
>>>> update: also suggest --merge when non-linear update is aborted
>>>
>>> This makes me a touch nervous, since the merge can leave the user in an
>>> state that's hard to recover from.
>>
>> Basically "hg resolve -au; hg resolve -at:local; hg update --merge  
>> -r$(head -c40 .hg/merge/state) -t:local"; but we need to expose a less  
>> hacky way of doing so.
>
> Not quite, because this isn't sure (I don't think) to get you back to  
> exactly the pre-update-command state, as some files might have been  
> merged behind your back?

Crazy thought- what if `hg update` were to do the equivalent under the  
hood:

$ hg ci --secret -m "backup for update"
$ src=$(hg log -r . -T "{rev}")
$ hg up $dest
$ hg rebase -r $src -d .

Rebase strips (or obsoletes), so the temp commit is gone.  If things go  
awry, `hg update --abort` is the equivalent of:

$ hg rebase --abort
$ hg up -C $src^
$ hg revert --all -r $src
$ hg strip --no-backup $src

This would restore files merged behind your back too.  Obviously it is  
only needed if a file changed in both branches between ancestor($src,  
$dest) -> $src and ancestor($src, $dest) -> $dest.  I've been pondering  
how to do that calculation with filesets, so at least there's an easy way  
to tell if there's a potential conflict beforehand.  Maybe a new  
'changed(rev)' fileset, that works like `hg status --change`?

>>
>> "hg update --abort"?
>
> I'd be a big fan of having an update --abort that just takes you back to  
> where you were before the conflicts. To date, nobody has been motivated  
> enough to do the work (I'd love to do it, but it's unlikely to be near  
> the top of my stack for months/years).
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

Patch

diff -r 542a99ede6c3 -r c6cd58d272ae mercurial/merge.py
--- a/mercurial/merge.py	Mon Feb 13 16:03:05 2017 -0800
+++ b/mercurial/merge.py	Tue Feb 14 22:41:38 2017 -0800
@@ -1570,7 +1570,8 @@ 
                         pass # allow updating to successors
                     else:
                         msg = _("uncommitted changes")
-                        hint = _("commit or update --clean to discard changes")
+                        hint = _("commit, or use --clean to discard changes, "
+                                 "or use --merge to allow update")
                         raise error.UpdateAbort(msg, hint=hint)
                 else:
                     # Allow jumping branches if clean and specific rev given
diff -r 542a99ede6c3 -r c6cd58d272ae tests/test-merge5.t
--- a/tests/test-merge5.t	Mon Feb 13 16:03:05 2017 -0800
+++ b/tests/test-merge5.t	Tue Feb 14 22:41:38 2017 -0800
@@ -26,7 +26,7 @@ 
 
   $ hg update 1
   abort: uncommitted changes
-  (commit or update --clean to discard changes)
+  (commit, or use --clean to discard changes, or use --merge to allow update)
   [255]
   $ mv c a
 
diff -r 542a99ede6c3 -r c6cd58d272ae tests/test-subrepo-svn.t
--- a/tests/test-subrepo-svn.t	Mon Feb 13 16:03:05 2017 -0800
+++ b/tests/test-subrepo-svn.t	Tue Feb 14 22:41:38 2017 -0800
@@ -472,7 +472,7 @@ 
   $ echo "updating should (maybe) fail" > obstruct/other
   $ hg co tip
   abort: uncommitted changes
-  (commit or update --clean to discard changes)
+  (commit, or use --clean to discard changes, or use --merge to allow update)
   [255]
 
 Point to a Subversion branch which has since been deleted and recreated
diff -r 542a99ede6c3 -r c6cd58d272ae tests/test-update-branches.t
--- a/tests/test-update-branches.t	Mon Feb 13 16:03:05 2017 -0800
+++ b/tests/test-update-branches.t	Tue Feb 14 22:41:38 2017 -0800
@@ -123,19 +123,19 @@ 
 
   $ revtest 'none dirty same'   dirty 2 3
   abort: uncommitted changes
-  (commit or update --clean to discard changes)
+  (commit, or use --clean to discard changes, or use --merge to allow update)
   parent=2
   M foo
 
   $ revtest 'none dirtysub same'   dirtysub 2 3
   abort: uncommitted changes
-  (commit or update --clean to discard changes)
+  (commit, or use --clean to discard changes, or use --merge to allow update)
   parent=2
   M sub/suba
 
   $ revtest 'none dirty cross'  dirty 3 4
   abort: uncommitted changes
-  (commit or update --clean to discard changes)
+  (commit, or use --clean to discard changes, or use --merge to allow update)
   parent=3
   M foo
 
@@ -147,7 +147,7 @@ 
 
   $ revtest 'none dirtysub cross'  dirtysub 3 4
   abort: uncommitted changes
-  (commit or update --clean to discard changes)
+  (commit, or use --clean to discard changes, or use --merge to allow update)
   parent=3
   M sub/suba
 
@@ -258,7 +258,7 @@ 
 
   $ revtest 'dirty cross'  dirty 3 4
   abort: uncommitted changes
-  (commit or update --clean to discard changes)
+  (commit, or use --clean to discard changes, or use --merge to allow update)
   parent=3
   M foo
 
@@ -476,7 +476,7 @@ 
   $ hg up --quiet 2
   $ hg up 5
   abort: uncommitted changes
-  (commit or update --clean to discard changes)
+  (commit, or use --clean to discard changes, or use --merge to allow update)
   [255]
 
 Test that we don't crash when updating from a pruned changeset (i.e. has no