Patchwork [2,of,2,evolve-ext] evolve: close transaction if conflict is detected in relocate (issue4966)

login
register
mail settings
Submitter Katsunori FUJIWARA
Date Jan. 28, 2016, 11:42 a.m.
Message ID <b7e5b22726865b99b440.1453981368@feefifofum>
Download mbox | patch
Permalink /patch/12901/
State Accepted
Delegated to: Pierre-Yves David
Headers show

Comments

Katsunori FUJIWARA - Jan. 28, 2016, 11:42 a.m.
# HG changeset patch
# User FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
# Date 1453466519 -32400
#      Fri Jan 22 21:41:59 2016 +0900
# Node ID b7e5b22726865b99b4408e7d046cdac5204a3f46
# Parent  d5ac28ad9f41585be4bc35466910f2733267c332
# Available At https://foozy@bitbucket.org/foozy/hgext-evolve
#              hg pull https://foozy@bitbucket.org/foozy/hgext-evolve -r b7e5b2272686
evolve: close transaction if conflict is detected in relocate (issue4966)

Before this patch, transaction is aborted, if conflict is detected at
merging while "hg evolve".

Since 8f2ff40fe9c9 (or 3.6) of Mercurial, aborting transaction
discards all dirstate changes inside transaction scope for
"transactional dirstate" (see below wiki page for detail about it).

    https://mercurial.selenic.com/wiki/DirstateTransactionPlan

Therefore, just aborting transaction causes unchanged (and unexpected)
dirstate, even though subsequent commands require dirstate changes
while "hg evolve".

To keep dirstate changes while "hg evolve", this patch closes current
running transaction, if conflict is detected in relocate(), even
though exception is raised as usual.

Even though "save dirstate and restore it after aborting transaction"
like shelve._aborttransaction() of Mercurial can also solve this
issue, this patch chose closing transaction for similarity with
failure for conflict at "hg unshelve". In addition to it, closing
transaction can keep any previous (implicit) changes.

In newly added test, there is an additional ancestor revision, which
"will be evolved safely". It is used to examine whether failure for
conflict doesn't discard already relocated revision(s) while "hg
evolve".

It is fact for current implementation that "hg evolve" relocates each
revisions in separated transactions and already relocated ones are
never discarded, even if subsequent relocation fails. Though, this
examination is useful to detect unintentional regression in the
future.
Pierre-Yves David - Feb. 1, 2016, 4:37 p.m.
On 01/28/2016 11:42 AM, FUJIWARA Katsunori wrote:
> # HG changeset patch
> # User FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
> # Date 1453466519 -32400
> #      Fri Jan 22 21:41:59 2016 +0900
> # Node ID b7e5b22726865b99b4408e7d046cdac5204a3f46
> # Parent  d5ac28ad9f41585be4bc35466910f2733267c332
> # Available At https://foozy@bitbucket.org/foozy/hgext-evolve
> #              hg pull https://foozy@bitbucket.org/foozy/hgext-evolve -r b7e5b2272686
> evolve: close transaction if conflict is detected in relocate (issue4966)

Pushed to main, thanks

Patch

diff --git a/hgext/evolve.py b/hgext/evolve.py
--- a/hgext/evolve.py
+++ b/hgext/evolve.py
@@ -984,6 +984,7 @@  def relocate(repo, orig, dest, pctx=None
             class LocalMergeFailure(MergeFailure, exc.__class__):
                 pass
             exc.__class__ = LocalMergeFailure
+            tr.close() # to keep changes in this transaction (e.g. dirstate)
             raise
         oldbookmarks = repo.nodebookmarks(nodesrc)
         _finalizerelocate(repo, orig, dest, nodenew, tr)
diff --git a/tests/test-evolve.t b/tests/test-evolve.t
--- a/tests/test-evolve.t
+++ b/tests/test-evolve.t
@@ -1398,3 +1398,54 @@  Create a split commit
   working directory is now at 43c3f5ef149f
 
 
+Check that dirstate changes are kept at failure for conflicts (issue4966)
+----------------------------------------
+
+  $ echo "will be amended" > newfile
+  $ hg commit -m "will be amended"
+  $ hg parents
+  37	: will be amended - test
+
+  $ echo "will be evolved safely" >> a
+  $ hg commit -m "will be evolved safely"
+
+  $ echo "will cause conflict at evolve" > newfile
+  $ echo "newly added" > newlyadded
+  $ hg add newlyadded
+  $ hg commit -m "will cause conflict at evolve"
+
+  $ hg update -q 37
+  $ echo "amended" > newfile
+  $ hg amend -m "amended"
+  2 new unstable changesets
+
+  $ hg evolve --rev "37::"
+  move:[38] will be evolved safely
+  atop:[41] amended
+  move:[39] will cause conflict at evolve
+  atop:[42] will be evolved safely
+  merging newfile
+  warning: conflicts while merging newfile! (edit, then use 'hg resolve --mark')
+  evolve failed!
+  fix conflict and run "hg evolve --continue" or use "hg update -C" to abort
+  abort: unresolved merge conflicts (see hg help resolve)
+  [255]
+
+  $ glog -r "36::" --hidden
+  @  42:c904da5245b0@default(draft) will be evolved safely
+  |
+  o  41:34ae045ec400@default(draft) amended
+  |
+  | x  40:e88bee38ffc2@default(draft) temporary amend commit for 36030b147271
+  | |
+  | | o  39:02e943732647@default(draft) will cause conflict at evolve
+  | | |
+  | | x  38:f8e30e9317aa@default(draft) will be evolved safely
+  | |/
+  | x  37:36030b147271@default(draft) will be amended
+  |/
+  o  36:43c3f5ef149f@default(draft) add uu
+  |
+
+  $ hg status newlyadded
+  A newlyadded