This is an archive of the discontinued Mercurial Phabricator instance.

update: added support for --abort flag(issue4404)
Needs RevisionPublic

Authored by taapas1128 on Aug 17 2019, 12:13 PM.

Details

Reviewers
durin42
mharbison72
Group Reviewers
hg-reviewers
Summary

This patch adds functionality to abort a conflicted
update. A new function hg.abortupdate() is added for
the purpose which has a helper function
hg._unmarkandresolvelocal() which deals with the
conflicts occured.

Results are shown in tests.

Diff Detail

Repository
rHG Mercurial
Lint
Lint Skipped
Unit
Unit Tests Skipped

Event Timeline

taapas1128 created this revision.Aug 17 2019, 12:13 PM
taapas1128 updated this revision to Diff 16251.Aug 17 2019, 3:16 PM
pulkit added a subscriber: pulkit.Aug 17 2019, 3:28 PM
pulkit added inline comments.
tests/test-merge-tools.t
2092

I suggest taking update --abort tests in a new file as we will need to extensively test that.

2129

we need to hide this, maybe use more low level APIs. I haven't look at code in details, will try to look soon.

taapas1128 updated this revision to Diff 16261.Aug 18 2019, 9:07 AM
taapas1128 marked an inline comment as done.Aug 18 2019, 9:08 AM
taapas1128 added inline comments.
tests/test-merge-tools.t
2092

I have created a separate file will add more tests.

taapas1128 marked an inline comment as done.Aug 18 2019, 9:31 AM
taapas1128 updated this revision to Diff 16262.

Nice start! If I remember correctly, the mergestate stores the local version of the file. We can use that directly instead.

mercurial/hg.py
992

this line is not required.

mharbison72 added inline comments.
tests/test-merge-tools.t
2092

When you add more tests, please include some with 1 dirty subrepo, and then another where the first subrepo is already merged/resolved, and the second subrepo is dirty and pending a merge/resolve. If it simplifies the initial implementation to detect a dirty subrepo and then abort the --abort before it starts, that seems fine.

taapas1128 marked an inline comment as done.Aug 22 2019, 10:20 AM
taapas1128 marked an inline comment as done.
taapas1128 added inline comments.
tests/test-merge-tools.t
2092

@mharbison72 Have a look. I have updated the diff.

durin42 accepted this revision as: durin42.Sep 11 2019, 11:24 AM
durin42 added a subscriber: durin42.

This looks good to me. Does anyone else have comments? @mharbison72 are you happy with the subrepo test coverage?

taapas1128 marked an inline comment as done.Sep 11 2019, 12:27 PM

@durin42 I don't think the subrepos are properly initialized in the tests. I would be updating them soon.

This looks good to me. Does anyone else have comments? @mharbison72 are you happy with the subrepo test coverage?

I forgot about this, thanks for the reminder. @taapas1128 is correct- the subrepos aren't being initialized as subrepos (i.e. there's no .hgsub file). I'll try to play with this more Friday or over the weekend.

mharbison72 requested changes to this revision.Sep 12 2019, 1:34 AM

Oops, meant to flag changes needed too.

This revision now requires changes to proceed.Sep 12 2019, 1:34 AM

Here's a case I stumbled upon that is a problem. It looks like it thinks it isn't in the middle of an update, but .hgsubstate isn't put back to the pre-update state.

diff --git a/tests/test-subrepo.t b/tests/test-subrepo.t
--- a/tests/test-subrepo.t
+++ b/tests/test-subrepo.t
@@ -1027,10 +1027,38 @@ filesystem (see also issue4583))
   > [extensions]
   > fakedirstatewritetime = $TESTDIR/fakedirstatewritetime.py
   > EOF
+  $ hg -R repo st -S
+  ? s/b
+  $ hg -R repo diff -S
+  $ hg -R repo log -r .
+  changeset:   0:c4018e9aea1b
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     1
+
+  $ cat repo/.hgsubstate
+  f7b1eb17ad24730a1651fccd46c43826d1bbc2ac s
   $ hg -R repo update
   b: untracked file differs
   abort: untracked files in working directory differ from files in requested revision (in subrepository "s")
   [255]
+  $ hg -R repo update --abort
+  abort: no update in progress
+  [255]
+  $ hg -R repo diff -S
+  diff -r c4018e9aea1b .hgsubstate
+  --- a/.hgsubstate Thu Jan 01 00:00:00 1970 +0000
+  +++ b/.hgsubstate Thu Jan 01 00:00:00 1970 +0000
+  @@ -1,1 +1,1 @@
+  -f7b1eb17ad24730a1651fccd46c43826d1bbc2ac s
+  +cc505f09a8b2644adffa368adb4abc6f70d07bc0 s
+  $ hg -R repo log -r .
+  changeset:   0:c4018e9aea1b
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     1
+
+
   $ cat >> repo/.hg/hgrc <<EOF
   > [extensions]
   > fakedirstatewritetime = !

Another good way to induce this .hgsubstate issue is to hg pull -u on a repo, where the remote subrepo isn't available. You don't need http for this- you can just rename the remote subrepo.

Here's a case I stumbled upon that is a problem. It looks like it thinks it isn't in the middle of an update, but .hgsubstate isn't put back to the pre-update state.

diff --git a/tests/test-subrepo.t b/tests/test-subrepo.t
--- a/tests/test-subrepo.t
+++ b/tests/test-subrepo.t
@@ -1027,10 +1027,38 @@ filesystem (see also issue4583))
   > [extensions]
   > fakedirstatewritetime = $TESTDIR/fakedirstatewritetime.py
   > EOF
+  $ hg -R repo st -S
+  ? s/b
+  $ hg -R repo diff -S
+  $ hg -R repo log -r .
+  changeset:   0:c4018e9aea1b
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     1
+
+  $ cat repo/.hgsubstate
+  f7b1eb17ad24730a1651fccd46c43826d1bbc2ac s
   $ hg -R repo update
   b: untracked file differs
   abort: untracked files in working directory differ from files in requested revision (in subrepository "s")

@mharbison72 I am bit confused here.

  1. Since hg -R repo update resulted with an abort then why we have dirty working directory now? Isn't transaction rollback worked correctly?
  2. Also if you run hg status it says "To continue: run hg update ." but I don't think it's really a "continue", since we are still on the same changeset where we ran the first update command and running hg update . won't take us to the changeset we wanted to go.
  3. I found that for interrupted update (only for some particular kind of interrupted update) we store target node value in .hg/updatestate but I couldn't find where we exactly use that value. I found some code which check if that file exists but not one where we use the value stored in that file.
[255]

+ $ hg -R repo update --abort
+ abort: no update in progress
+ [255]
+ $ hg -R repo diff -S
+ diff -r c4018e9aea1b .hgsubstate
+ --- a/.hgsubstate Thu Jan 01 00:00:00 1970 +0000
+ +++ b/.hgsubstate Thu Jan 01 00:00:00 1970 +0000
+ @@ -1,1 +1,1 @@
+ -f7b1eb17ad24730a1651fccd46c43826d1bbc2ac s
+ +cc505f09a8b2644adffa368adb4abc6f70d07bc0 s
+ $ hg -R repo log -r .
+ changeset: 0:c4018e9aea1b
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: 1
+
+

$ cat >> repo/.hg/hgrc <<EOF
> [extensions]
> fakedirstatewritetime = !
Another good way to induce this .hgsubstate issue is to `hg pull -u` on a repo, where the remote subrepo isn't available.  You don't need http for this- you can just rename the remote subrepo.

Here's a case I stumbled upon that is a problem. It looks like it thinks it isn't in the middle of an update, but .hgsubstate isn't put back to the pre-update state.

diff --git a/tests/test-subrepo.t b/tests/test-subrepo.t
--- a/tests/test-subrepo.t
+++ b/tests/test-subrepo.t
@@ -1027,10 +1027,38 @@ filesystem (see also issue4583))
   > [extensions]
   > fakedirstatewritetime = $TESTDIR/fakedirstatewritetime.py
   > EOF
+  $ hg -R repo st -S
+  ? s/b
+  $ hg -R repo diff -S
+  $ hg -R repo log -r .
+  changeset:   0:c4018e9aea1b
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     1
+
+  $ cat repo/.hgsubstate
+  f7b1eb17ad24730a1651fccd46c43826d1bbc2ac s
   $ hg -R repo update
   b: untracked file differs
   abort: untracked files in working directory differ from files in requested revision (in subrepository "s")

@mharbison72 I am bit confused here.

  1. Since hg -R repo update resulted with an abort then why we have dirty working directory now? Isn't transaction rollback worked correctly?

Two things to keep in mind.

  1. updates aren't transactions
  2. even if they were, a transaction is within *one* repo.

When you update with subrepos, you check for dirty from the top, recurse to the bottom, and on the way up you update the subrepo. So in the simple case of parent repo P and subrepo S, you check P for dirty (recursively), then update S, then update P. If something goes wrong updating P, S is not rolled back.

  1. Also if you run hg status it says "To continue: run hg update ." but I don't think it's really a "continue", since we are still on the same changeset where we ran the first update command and running hg update . won't take us to the changeset we wanted to go.

Maybe it needs to continue if it did a partial checkout? IDK when the parent in dirstate is updated- before or after all files are checked out.

  1. I found that for interrupted update (only for some particular kind of interrupted update) we store target node value in .hg/updatestate but I couldn't find where we exactly use that value. I found some code which check if that file exists but not one where we use the value stored in that file.

Sorry, I'm not sure about that either. I'd imagine it's for the --continue case though. Maybe that isn't fully implemented yet?