changeset 929:306f67906a6c stable

merge with all other change to 3.3
author Pierre-Yves David <pierre-yves.david@fb.com>
date Sun, 11 May 2014 01:17:02 -0700
parents be39695cbfda (current diff) 154510dc4318 (diff)
children cac35bef8aee
files README
diffstat 11 files changed, 194 insertions(+), 81 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Sun May 11 01:14:34 2014 -0700
+++ b/.hgtags	Sun May 11 01:17:02 2014 -0700
@@ -19,3 +19,5 @@
 862b6b71a35836e81f090ba7229c2888e8ed2f9f 3.0.0
 cdb52bbbe5b8770d5e68943b7e73bee4ba136ecc 3.1.0
 c3ba8a965a7a173e388d84819e936ea9bae9797f 3.2.0
+83882f2fbecba0b7e7f7e5d490b57db93bd7fa22 3.3.0
+fc04758ea9f549684989ee673b04d9724756dc85 3.3.1
--- a/README	Sun May 11 01:14:34 2014 -0700
+++ b/README	Sun May 11 01:17:02 2014 -0700
@@ -29,7 +29,12 @@
 ==========
 
 The simplest way to contribute is to issue a pull request on Bitbucket
-(https://bitbucket.org/marmoute/mutable-history).
+(https://bitbucket.org/marmoute/mutable-history). Please don't forget
+to update and run the tests when you fix a bug or add a feature. To
+run the tests:
+
+    cd tests
+    python run-tests.py --with-hg=/path/to/hg
 
 However, some cutting-edge changes may be found in a mutable repository hosted
 by logilab before they are published.
@@ -42,9 +47,24 @@
 Changelog
 =========
 
-3.3.0 --
+3.3.2 --
+
+- fix a bug where evolve were creating changeset with 2 parents on windows
+  (fix issues #16, #35 and #42)
+
+3.3.1 -- 2014-04-23
+
+- various language fix
+- active bookmark now move when using prev/next (#37)
+- fix some preservation of rename information on evolve (#33)
+- abort when evolve tries to move a node on top of itself (will helps on the #35 front)
+- fold: enable --date and --user options
+
+3.3.0 -- 2014-03-04
 
 - raise Mercurial's minimal requirement to 2.7
+- drop `latercomer` and `conflicting` compatibility. Those old alias are
+  deprecated for a long time now.
 - add verbose hint about how to handle corner case by hand.
   This should help people until evolve is able to to it itself.
 - removed the qsync extension. The only user I knew about (logilab) is not
--- a/hgext/evolve.py	Sun May 11 01:14:34 2014 -0700
+++ b/hgext/evolve.py	Sun May 11 01:17:02 2014 -0700
@@ -6,7 +6,7 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
-'''Extends Mercurial feature related to Changeset Evolution
+'''extends Mercurial feature related to Changeset Evolution
 
 This extension provides several commands to mutate history and deal with
 issues it may raise.
@@ -19,7 +19,7 @@
     - improves some aspect of the early implementation in 2.3
 '''
 
-testedwith = '2.7 2.7.1 2.7.2 2.8 2.8.1'
+testedwith = '2.7 2.7.1 2.7.2 2.8 2.8.1 2.8.2 2.9 2.9.1 2.9.2 3.0'
 buglink = 'https://bitbucket.org/marmoute/mutable-history/issues'
 
 import sys
@@ -326,34 +326,6 @@
 getrevs = obsolete.getrevs
 
 #####################################################################
-### Complete troubles computation logic                           ###
-#####################################################################
-
-
-### Cache computation
-latediff = 1  # flag to prevent taking late comer fix into account
-
-### changectx method
-
-@eh.addattr(context.changectx, 'latecomer')
-def latecomer(ctx):
-    """is the changeset bumped (Try to succeed to public change)"""
-    return ctx.bumped()
-
-@eh.addattr(context.changectx, 'conflicting')
-def conflicting(ctx):
-    """is the changeset divergent (Try to succeed to public change)"""
-    return ctx.divergent()
-
-### revset symbol
-
-eh.revset('latecomer')(revset.symbols['bumped'])
-eh.revset('conflicting')(revset.symbols['divergent'])
-
-
-
-
-#####################################################################
 ### Additional Utilities                                          ###
 #####################################################################
 
@@ -766,6 +738,12 @@
 def relocate(repo, orig, dest):
     """rewrite <rev> on dest"""
     try:
+        if orig.rev() == dest.rev():
+            raise util.Abort(_('tried to relocade a node on top of itself'),
+                             hint=_("This shouldn't happen. If you still "
+                                    "need to move changesets, please do so "
+                                    "manually with nothing to rebase - working directory parent is also destination"))
+
         rebase = extensions.find('rebase')
         # dummy state to trick rebase node
         if not orig.p2().rev() == node.nullrev:
@@ -773,15 +751,18 @@
                 'no support for evolution merge changesets yet',
                 hint="Redo the merge a use `hg prune` to obsolete the old one")
         destbookmarks = repo.nodebookmarks(dest.node())
-        cmdutil.duplicatecopies(repo, orig.node(), dest.node())
         nodesrc = orig.node()
         destphase = repo[nodesrc].phase()
+        wlock = lock = None
         try:
+            wlock = repo.wlock()
+            lock = repo.lock()
             r = rebase.rebasenode(repo, orig.node(), dest.node(),
                                   {node.nullrev: node.nullrev}, False)
             if r[-1]: #some conflict
                 raise util.Abort(
                         'unresolved merge conflicts (see hg help resolve)')
+            cmdutil.duplicatecopies(repo, orig.node(), dest.node())
             nodenew = rebase.concludenode(repo, orig.node(), dest.node(),
                                           node.nullid)
         except util.Abort, exc:
@@ -789,6 +770,8 @@
                 pass
             exc.__class__ = LocalMergeFailure
             raise
+        finally:
+            lockmod.release(lock, wlock)
         oldbookmarks = repo.nodebookmarks(nodesrc)
         if nodenew is not None:
             phases.retractboundary(repo, destphase, [nodenew])
@@ -842,7 +825,7 @@
 
 
 @command('^evolve|stabilize|solve',
-    [('n', 'dry-run', False, 'do not perform actions, print what to be done'),
+    [('n', 'dry-run', False, 'do not perform actions, just print what would be done'),
     ('A', 'any', False, 'evolve any troubled changeset'),
     ('a', 'all', False, 'evolve all troubled changesets'),
     ('c', 'continue', False, 'continue an interrupted evolution'), ],
@@ -850,13 +833,13 @@
 def evolve(ui, repo, **opts):
     """Solve trouble in your repository
 
-    - rebase unstable changeset to make it stable again,
-    - create proper diff from bumped changeset,
-    - merge divergent changesets.
+    - rebase unstable changesets to make them stable again,
+    - create proper diffs from bumped changesets,
+    - merge divergent changesets,
     - update to a successor if the working directory parent is
       obsolete
 
-    By default, take the first trouble changeset that looks relevant.
+    By default, takes the first troubled changeset that looks relevant.
 
     (The logic is still a bit fuzzy)
 
@@ -866,7 +849,7 @@
 
     - For divergent, this means taking "." if applicable.
 
-    With --any, evolve picks any troubled changeset to solve.
+    With --any, evolve picks any troubled changeset to repair.
 
     The working directory is updated to the newly created revision.
     """
@@ -1154,7 +1137,7 @@
                 else:
                     phases.retractboundary(repo, bumped.phase(), [newid])
                     createmarkers(repo, [(tmpctx, (repo[newid],))],
-                                           flag=latediff)
+                                           flag=obsolete.bumpedfix)
                 bmupdate(newid)
                 tr.close()
                 repo.ui.status(_('commited as %s\n') % node.short(newid))
@@ -1305,7 +1288,12 @@
     displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate})
     if len(parents) == 1:
         p = parents[0]
-        hg.update(repo, p.rev())
+        bm = bookmarks.readcurrent(repo)
+        shouldmove = bm is not None and bookmarks.iscurrent(repo, bm)
+        ret = hg.update(repo, p.rev())
+        if not ret and shouldmove:
+            repo._bookmarks[bm] = p.node()
+            repo._bookmarks.write()
         displayer.show(p)
         return 0
     else:
@@ -1331,7 +1319,12 @@
         return 1
     if len(children) == 1:
         c = children[0]
-        hg.update(repo, c.rev())
+        bm = bookmarks.readcurrent(repo)
+        shouldmove = bm is not None and bookmarks.iscurrent(repo, bm)
+        ret = hg.update(repo, c.rev())
+        if not ret and shouldmove:
+            repo._bookmarks[bm] = c.node()
+            repo._bookmarks.write()
         displayer.show(c)
         return 0
     else:
@@ -1393,22 +1386,22 @@
     _('[OPTION] [-r] REV...'))
     # -U  --noupdate option to prevent wc update and or bookmarks update ?
 def cmdprune(ui, repo, *revs, **opts):
-    """get rid of changesets by marking them obsolete
+    """hide changesets by marking them obsolete
 
     Obsolete changesets becomes invisible to all commands.
 
-    Non-pruned descendant of pruned changesets becomes "unstable". Use the
+    Unpruned descendants of pruned changesets becomes "unstable". Use the
     :hg:`evolve` to handle such situation.
 
-    When the working directory parent is pruned the repository is updated to a
-    non obsolete parents.
+    When the working directory parent is pruned, the repository is updated to a
+    non-obsolete parent.
 
-    You can use the ``--succ`` option to informs mercurial that a newer version
+    You can use the ``--succ`` option to inform mercurial that a newer version
     of the pruned changeset exists.
 
     You can use the ``--biject`` option to specify a 1-1 (bijection) between
     revisions to prune and successor changesets. This option may be removed in
-    a future release (with the functionality absored automatically).
+    a future release (with the functionality absorbed automatically).
 
     """
     revs = set(scmutil.revrange(repo, list(revs) + opts.get('rev')))
@@ -1436,7 +1429,7 @@
         for p in sortedrevs(revs):
             cp = repo[p]
             if not cp.mutable():
-                # note: create marker would had raise something anyway
+                # note: createmarkers() would have raised something anyway
                 raise util.Abort('cannot prune immutable changeset: %s' % cp,
                                  hint='see "hg help phases" for details')
             precs.append(cp)
@@ -1606,13 +1599,13 @@
 def uncommit(ui, repo, *pats, **opts):
     """move changes from parent revision to working directory
 
-    Changes to selected files in parent revision appear again as
+    Changes to selected files in the checked out revision appear again as
     uncommitted changed in the working directory. A new revision
-    without selected changes is created, becomes the new parent and
-    obsoletes the previous one.
+    without the selected changes is created, becomes the checked out
+    revision, and obsoletes the previous one.
 
-    The --include option specify pattern to uncommit
-    The --exclude option specify pattern to keep in the commit
+    The --include option specifies patterns to uncommit.
+    The --exclude option specifies patterns to keep in the commit.
 
     Return 0 if changed files are uncommitted.
     """
@@ -1648,7 +1641,7 @@
             updatebookmarks(newid)
             if not repo[newid].files():
                 ui.warn(_("new changeset is empty\n"))
-                ui.status(_('(use "hg kill ." to remove it)\n'))
+                ui.status(_('(use "hg prune ." to remove it)\n'))
         finally:
             wlock.release()
     finally:
@@ -1690,7 +1683,7 @@
     # allow to choose the seed ?
     _('[-r] revs'))
 def touch(ui, repo, *revs, **opts):
-    """Create successors with exact same property but hash
+    """Create successors that are identical to their predecessors except for the changeset ID
 
     This is used to "resurrect" changesets
     """
@@ -1740,16 +1733,16 @@
 
 @command('^fold',
     [('r', 'rev', [], _("explicitly specify the full set of revision to fold")),
-    ],
+    ] + commitopts2,
     # allow to choose the seed ?
     _('rev'))
 def fold(ui, repo, *revs, **opts):
     """Fold multiple revisions into a single one
 
-    Revision from your current working directory to the specified one are fold
-    as a new one replacing the other
+    The revisions from your current working directory to the given one are folded
+    into a single successor revision.
 
-    you can alternatively use --rev to explicitly specify revision to be fold
+    you can alternatively use --rev to explicitly specify revisions to be folded,
     ignoring the current working directory parent.
     """
     revs = list(revs)
@@ -1781,12 +1774,13 @@
         lock = repo.lock()
         tr = repo.transaction('touch')
         try:
+            commitopts = opts.copy()
             allctx = [repo[r] for r in revs]
             targetphase = max(c.phase() for c in allctx)
             msgs = ["HG: This is a fold of %d changesets." % len(allctx)]
             msgs += ["HG: Commit message of changeset %s.\n\n%s\n" %
                      (c.rev(), c.description()) for c in allctx]
-            commitopts = {'message': "\n".join(msgs)}
+            commitopts['message'] = "\n".join(msgs)
             commitopts['edit'] = True
             newid, _ = rewrite(repo, root, allctx, head,
                              [root.p1().node(), root.p2().node()],
--- a/setup.py	Sun May 11 01:14:34 2014 -0700
+++ b/setup.py	Sun May 11 01:17:02 2014 -0700
@@ -5,10 +5,10 @@
 
 setup(
     name='hg-evolve',
-    version='3.2.0',
+    version='3.3.1',
     author='Pierre-Yves David',
     maintainer='Pierre-Yves David',
-    maintainer_email='pierre-yves.david@logilab.fr',
+    maintainer_email='pierre-yves.david@ens-lyon.org',
     url='https://bitbucket.org/marmoute/mutable-history',
     description='Flexible evolution of Mercurial history.',
     long_description=open('README').read(),
--- a/tests/test-evolve.t	Sun May 11 01:14:34 2014 -0700
+++ b/tests/test-evolve.t	Sun May 11 01:17:02 2014 -0700
@@ -1,6 +1,7 @@
   $ cat >> $HGRCPATH <<EOF
   > [defaults]
   > amend=-d "0 0"
+  > fold=-d "0 0"
   > [web]
   > push_ssl = false
   > allow_push = *
@@ -593,7 +594,7 @@
   2 changesets folded
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ glog
-  @  11:*@default(draft) add 1 (glob)
+  @  11:dd4682c1a481@default(draft) add 1
   |
   o  5:0b9e50c35132@default(draft) add 3
   |
@@ -615,16 +616,20 @@
 
   $ hg up 4
   0 files updated, 0 files merged, 2 files removed, 0 files unresolved
-  $ hg fold --rev 4::11
+  $ hg fold --rev 4::11 --user victor
   3 changesets folded
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ glog
-  @  12:*@default(draft) add 4 (glob)
+  @  12:d26d339c513f@default(draft) add 4
   |
   | o  1:73d38bb17fd7@default(draft) add 1
   |/
   o  0:8685c6d34325@default(draft) add 0
   
+  $ hg log --template '{rev}: {author}\n'
+  12: victor
+  1: test
+  0: test
   $ hg log -r 12 --template '{desc}\n'
   add 4
   
@@ -645,3 +650,28 @@
   4	: add 4 - test
   5	: add 3 - test
   11	: add 1 - test
+
+
+Test evolving renames
+
+  $ hg up null
+  0 files updated, 0 files merged, 4 files removed, 0 files unresolved
+  $ echo a > a
+  $ hg ci -Am a
+  adding a
+  created new head
+  $ echo b > b
+  $ hg ci -Am b
+  adding b
+  $ hg mv a c
+  $ hg ci -m c
+  $ hg kill .^
+  1 changesets pruned
+  1 new unstable changesets
+  $ hg stab --any
+  move:[15] c
+  atop:[13] a
+  $ hg st -C --change=tip
+  A c
+    a
+  R a
--- a/tests/test-obsolete.t	Sun May 11 01:14:34 2014 -0700
+++ b/tests/test-obsolete.t	Sun May 11 01:17:02 2014 -0700
@@ -637,7 +637,7 @@
 #no produced by 2.3
 33d458d86621f3186c40bfccd77652f4a122743e 3734a65252e69ddcced85901647a4f335d40de1e 0 {'date': '* *', 'user': 'test'} (glob)
 
-Check conflict detection
+Check divergence detection
 
   $ hg up 9468a5f5d8b2 #  add obsol_d''
   1 files updated, 0 files merged, 1 files removed, 0 files unresolved
@@ -650,7 +650,7 @@
   update: (2|9|11) new changesets, (3|9|10) branch heads \(merge\) (re)
   bumped: 1 changesets
   $ hg debugobsolete `getid a7a6f2b5d8a5` `getid 50f11e5e3a63`
-  $ hg log -r 'conflicting()'
+  $ hg log -r 'divergent()'
   changeset:   12:6db5e282cb91
   parent:      10:2033b4e49474
   user:        test
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-prev-next.t	Sun May 11 01:17:02 2014 -0700
@@ -0,0 +1,62 @@
+  $ cat >> $HGRCPATH <<EOF
+  > [extensions]
+  > hgext.rebase=
+  > hgext.graphlog=
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext/evolve.py" >> $HGRCPATH
+
+hg prev should move active bookmark
+  $ hg init
+  $ touch a
+  $ hg add a
+  $ hg commit -m 'added a'
+  $ touch b
+  $ hg add b
+  $ hg commit -m 'added b'
+  $ hg bookmark mark
+  $ hg bookmarks
+   * mark                      1:6e742c9127b3
+  $ hg prev
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  [0] added a
+  $ hg bookmarks
+   * mark                      0:a154386e50d1
+
+hg next should move active bookmark
+  $ hg next
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  [1] added b
+  $ hg bookmarks
+   * mark                      1:6e742c9127b3
+
+hg next/prev should not interfere with inactive bookmarks
+  $ touch c
+  $ hg add c
+  $ hg commit -m 'added c'
+  $ hg bookmark -r2 no-move
+  $ hg prev
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  [1] added b
+  $ hg bookmarks
+   * mark                      1:6e742c9127b3
+     no-move                   2:4e26ef31f919
+  $ hg next
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  [2] added c
+  $ hg bookmarks
+   * mark                      2:4e26ef31f919
+     no-move                   2:4e26ef31f919
+  $ hg up 1
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg next
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  [2] added c
+  $ hg bookmarks
+     mark                      2:4e26ef31f919
+     no-move                   2:4e26ef31f919
+  $ hg prev
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  [1] added b
+  $ hg bookmarks
+     mark                      2:4e26ef31f919
+     no-move                   2:4e26ef31f919
--- a/tests/test-prune.t	Sun May 11 01:14:34 2014 -0700
+++ b/tests/test-prune.t	Sun May 11 01:17:02 2014 -0700
@@ -236,6 +236,7 @@
   bookmark 'nostrip' deleted
   abort: nothing to prune
   [255]
+  $ hg tag --remove --local a
   $ hg prune -B todelete
   1 changesets pruned
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -252,6 +253,7 @@
   $ hg prune -B delete
   3 changesets pruned
   bookmark 'delete' deleted
+  $ hg tag --remove --local c
   $ hg id -ir 6:2702dd0c91e7
   abort: unknown revision '2702dd0c91e7'!
   [255]
--- a/tests/test-stabilize-result.t	Sun May 11 01:14:34 2014 -0700
+++ b/tests/test-stabilize-result.t	Sun May 11 01:17:02 2014 -0700
@@ -171,7 +171,7 @@
   o  0:07f494440405@default(public) bk:[] adda
   
 
-Stabilize conflicting changesets with same parent
+Stabilize divergenent changesets with same parent
 =================================================
 
   $ rm a.orig
@@ -291,7 +291,7 @@
   +conflict
   +babar
 
-Check conflicting during conflicting resolution
+Check conflict during divergence resolution
 -------------------------------------------------
 
   $ hg up --hidden 15
--- a/tests/test-tutorial.t	Sun May 11 01:14:34 2014 -0700
+++ b/tests/test-tutorial.t	Sun May 11 01:17:02 2014 -0700
@@ -436,12 +436,13 @@
   
   move changes from parent revision to working directory
   
-      Changes to selected files in parent revision appear again as uncommitted
-      changed in the working directory. A new revision without selected changes
-      is created, becomes the new parent and obsoletes the previous one.
+      Changes to selected files in the checked out revision appear again as
+      uncommitted changed in the working directory. A new revision without the
+      selected changes is created, becomes the checked out revision, and
+      obsoletes the previous one.
   
-      The --include option specify pattern to uncommit The --exclude option
-      specify pattern to keep in the commit
+      The --include option specifies patterns to uncommit. The --exclude option
+      specifies patterns to keep in the commit.
   
       Return 0 if changed files are uncommitted.
   
@@ -469,15 +470,17 @@
   
   Fold multiple revisions into a single one
   
-      Revision from your current working directory to the specified one are fold
-      as a new one replacing the other
+      The revisions from your current working directory to the given one are
+      folded into a single successor revision.
   
-      you can alternatively use --rev to explicitly specify revision to be fold
-      ignoring the current working directory parent.
+      you can alternatively use --rev to explicitly specify revisions to be
+      folded, ignoring the current working directory parent.
   
   options:
   
    -r --rev VALUE [+] explicitly specify the full set of revision to fold
+   -d --date DATE     record the specified date as commit date
+   -u --user USER     record the specified user as committer
   
   [+] marked option can be specified multiple times
   
@@ -826,7 +829,7 @@
 Handling Divergent amend
 ----------------------------------------------
 
-We can detect that multiple diverging/conflicting amendments have been made.
+We can detect that multiple diverging amendments have been made.
 The `evolve` command can solve this situation. But all corner case are not
 handled now.
 
--- a/tests/test-uncommit.t	Sun May 11 01:14:34 2014 -0700
+++ b/tests/test-uncommit.t	Sun May 11 01:17:02 2014 -0700
@@ -316,7 +316,7 @@
 
   $ hg uncommit e
   new changeset is empty
-  (use "hg kill ." to remove it)
+  (use "hg prune ." to remove it)
   $ hg debugobsolete
   5eb72dbe0cb409d094e3b4ae8eaa30071c1b8730 e8db4aa611f6d5706374288e6898e498f5c44098 0 {'date': '* *', 'user': 'test'} (glob)
   5eb72dbe0cb409d094e3b4ae8eaa30071c1b8730 c706fe2c12f83ba5010cb60ea6af3bd1f0c2d6d3 0 {'date': '* *', 'user': 'test'} (glob)