merge with the rest of stable stable
authorPierre-Yves David <pierre-yves.david@fb.com>
Sun, 03 Jan 2016 15:51:36 +0100
branchstable
changeset 1578 ec4fae88831d
parent 1577 0e9821f54ef2 (current diff)
parent 1574 dcfe3afe548b (diff)
child 1579 4f83b2d2d20d
child 1584 190e4e526c66
merge with the rest of stable
--- a/README	Wed Dec 30 03:48:11 2015 +0530
+++ b/README	Sun Jan 03 15:51:36 2016 +0100
@@ -42,10 +42,15 @@
 for guidelines on the patch description.
 
 Please don't forget to update and run the tests when you fix a bug or
-add a feature. To run the tests:
+add a feature. To run the tests, you need a working copy of Mercurial,
+say in $HGSRC:
 
     cd tests
-    python run-tests.py --with-hg=/path/to/hg
+    python $HGSRC/tests/run-tests.py --with-hg=$HGSRC/hg
+
+(evolve's stable and default branches correspond to Mercurial's stable
+and default branches. So to test evolve from default, you need
+Mercurial on default.)
 
 
 Changelog
@@ -55,6 +60,11 @@
 
 - split: add a new command to split changesets
 
+5.2.2 --
+
+- no longer lock the repository for `hg parents` (issue4895)
+- updated help for the `evolve` command
+
 5.2.1 -- 2015-11-02
 
 - add compatibility with Mercurial 3.6
--- a/hgext/evolve.py	Wed Dec 30 03:48:11 2015 +0530
+++ b/hgext/evolve.py	Sun Jan 03 15:51:36 2016 +0100
@@ -147,8 +147,8 @@
 class exthelper(object):
     """Helper for modular extension setup
 
-    A single helper should be instanciated for each extension. Helper
-    methods are then used as decorator for various purpose.
+    A single helper should be instantiated for each extension. Helper
+    methods are then used as decorators for various purpose.
 
     All decorators return the original function and may be chained.
     """
@@ -678,16 +678,19 @@
 
 # This section take care of issue warning to the user when troubles appear
 
+
+def _warnobsoletewc(ui, repo):
+    if repo['.'].obsolete():
+        ui.warn(_('working directory parent is obsolete!\n'))
+        if (not ui.quiet) and obsolete.isenabled(repo, commandopt):
+            ui.warn(_('(use "hg evolve" to update to its successor)\n'))
+
 @eh.wrapcommand("update")
-@eh.wrapcommand("parents")
 @eh.wrapcommand("pull")
 def wrapmayobsoletewc(origfn, ui, repo, *args, **opts):
     """Warn that the working directory parent is an obsolete changeset"""
     def warnobsolete():
-        if repo['.'].obsolete():
-            ui.warn(_('working directory parent is obsolete!\n'))
-            if (not ui.quiet) and obsolete.isenabled(repo, commandopt):
-                ui.warn(_('(use "hg evolve" to update to its successor)\n'))
+        _warnobsoletewc(ui, repo)
     wlock = None
     try:
         wlock = repo.wlock()
@@ -697,6 +700,12 @@
         lockmod.release(wlock)
     return res
 
+@eh.wrapcommand("parents")
+def wrapparents(origfn, ui, repo, *args, **opts):
+    res = origfn(ui, repo, *args, **opts)
+    _warnobsoletewc(ui, repo)
+    return res
+
 # XXX this could wrap transaction code
 # XXX (but this is a bit a layer violation)
 @eh.wrapcommand("commit")
@@ -786,7 +795,7 @@
         if histedit:
             extensions.wrapcommand(histedit.cmdtable, 'histedit', warnobserrors)
     except KeyError:
-        pass  # rebase not found
+        pass  # histedit not found
 
 #####################################################################
 ### Old Evolve extension content                                  ###
@@ -1119,11 +1128,12 @@
 
 @command('debugrecordpruneparents', [], '')
 def cmddebugrecordpruneparents(ui, repo):
-    """add parents data to prune markers when possible
-
-    This commands search the repo for prune markers without parent information.
-    If the pruned node is locally known, a new markers with parent data is
-    created."""
+    """add parent data to prune markers when possible
+
+    This command searches the repo for prune markers without parent information.
+    If the pruned node is locally known, it creates a new marker with parent
+    data.
+    """
     pgop = 'reading markers'
 
     # lock from the beginning to prevent race
@@ -1155,6 +1165,7 @@
 
 @command('debugobsstorestat', [], '')
 def cmddebugobsstorestat(ui, repo):
+    """print statistics about obsolescence markers in the repo"""
     def _updateclustermap(nodes, mark, clustersmap):
         c = (set(nodes), set([mark]))
         toproceed = set(nodes)
@@ -1172,7 +1183,6 @@
                 c = other
             clustersmap[n] = c
 
-    """print statistic about obsolescence markers in the repo"""
     store = repo.obsstore
     unfi = repo.unfiltered()
     nm = unfi.changelog.nodemap
@@ -1384,7 +1394,7 @@
         ui.status(_('working directory is now at %s\n') % repo['.'])
 
 class MultipleSuccessorsError(RuntimeError):
-    """Exception raised by _singlesuccessor when multiple sucessors sets exists
+    """Exception raised by _singlesuccessor when multiple successor sets exists
 
     The object contains the list of successorssets in its 'successorssets'
     attribute to call to easily recover.
@@ -1487,14 +1497,14 @@
 def _orderrevs(repo, revs):
     """Compute an ordering to solve instability for the given revs
 
-    - Takes revs a list of instable revisions
-
-    - Returns the same revisions ordered to solve their instability from the
+    revs is a list of unstable revisions.
+
+    Returns the same revisions ordered to solve their instability from the
     bottom to the top of the stack that the stabilization process will produce
     eventually.
 
-    This ensure the minimal number of stabilization as we can stabilize each
-    revision on its final, stabilized, destination.
+    This ensures the minimal number of stabilizations, as we can stabilize each
+    revision on its final stabilized destination.
     """
     # Step 1: Build the dependency graph
     dependencies, rdependencies = builddependencies(repo, revs)
@@ -1535,38 +1545,66 @@
     ] + mergetoolopts,
     _('[OPTIONS]...'))
 def evolve(ui, repo, **opts):
-    """solve troubles in your repository
-
-    - rebase unstable changesets to make them stable again,
-    - create proper diffs from bumped changesets,
-    - fuse divergent changesets back together,
-    - update to a successor if the working directory parent is
-      obsolete
-
-    If no argument are passed and the current working copy parent is obsolete,
-    :hg:`evolve` will update the working copy to the successors of this working
-    copy parent. If the working copy parent is not obsolete (and still no
-    argument passed) each invocation of :hg:`evolve` will evolve a single
-    unstable changeset, It will only select a changeset to be evolved if it
-    will result in a new children for the current working copy parent or its
-    descendants. The working copy will be updated on the result
-    (this last behavior will most likely to change in the future).
-    You can evolve all the unstable changesets that will be evolved on the
-    parent of the working copy and all its descendants recursively by using
-    :hg:`evolve` --all.
-
-    You can decide to evolve other categories of trouble using the --divergent
-    and --bumped flags. If no other option are specified, this will try to
-    solve the specified troubles for the working copy parent.
-
-    You can also evolve changesets affected by troubles of the selected
-    category using the --rev options. You can pick the next one anywhere in the
-    repo using --any.
-
-    You can evolve all the changesets affected by troubles of the selected
-    category using --all --any.
-
-    The working directory is updated to the newly created revision.
+    """solve troubled changesets in your repository
+
+    Modifying history can lead to various types of troubled changesets: unstable,
+    bumped, or divergent. The evolve command resolves your troubles by executing one
+    of the following actions:
+
+    - update working copy to a successor
+    - rebase an unstable changeset
+    - extract the desired changes from a bumped changeset
+    - fuse divergent changesets back together
+
+    If you pass no arguments, evolve works in automatic mode: it will execute a
+    single action to reduce instability related to your working copy. There are two
+    cases for this action. First, if the parent of your working copy is obsolete,
+    evolve updates to the parent's successor. Second, if the working copy parent is
+    not obsolete but has obsolete predecessors, then evolve determines if there is an
+    unstable changeset that can be rebased onto the working copy parent in order to
+    reduce instability. If so, evolve rebases that changeset. If not, evolve refuses
+    to guess your intention, and gives a hint about what you might want to do next.
+
+    Any time evolve creates a changeset, it updates the working copy to the new
+    changeset. (Currently, every successful evolve operation involves an update as
+    well; this may change in future.)
+
+    Automatic mode only handles common use cases. For example, it avoids taking
+    action in the case of ambiguity, and it ignores unstable changesets that are not
+    related to your working copy. It also refuses to solve bumped or divergent
+    changesets unless you explicity request such behavior (see below).
+
+    Eliminating all instability around your working copy may require multiple
+    invocations of :hg:`evolve`. Alternately, use ``--all`` to recursively select and
+    evolve all unstable changesets that can be rebased onto the working copy parent.
+    This is more powerful than successive invocations, since ``--all`` handles
+    ambiguous cases (e.g. unstable changesets with multiple children) by evolving all
+    branches.
+
+    When your repository cannot be handled by automatic mode, you might need to use
+    ``--rev`` to specify a changeset to evolve. For example, if you have an unstable
+    changeset that is not related to the working copy parent, you could use ``--rev``
+    to evolve it. Or, if some changeset has multiple unstable children, evolve in
+    automatic mode refuses to guess which one to evolve; you have to use ``--rev``
+    in that case.
+
+    Alternately, ``--any`` makes evolve search for the next evolvable changeset
+    regardless of whether it is related to the working copy parent.
+
+    You can supply multiple revisions to evolve multiple troubled changesets in a
+    single invocation. In revset terms, ``--any`` is equivalent to ``--rev
+    first(unstable())``. ``--rev`` and ``--all`` are mutually exclusive, as are
+    ``--rev`` and ``--any``.
+
+    ``hg evolve --any --all`` is useful for cleaning up instability across all
+    branches, letting evolve figure out the appropriate order and destination.
+
+    When you have troubled changesets that are not unstable, :hg:`evolve` refuses to
+    consider them unless you specify the category of trouble you wish to resolve,
+    with ``--bumped`` or ``--divergent``. These options are currently mutually
+    exclusive with each other and with ``--unstable`` (the default). You can combine
+    ``--bumped`` or ``--divergent`` with ``--rev``, ``--all``, or ``--any``.
+
     """
 
     # Options
@@ -1710,7 +1748,7 @@
 
 def _solveunstable(ui, repo, orig, dryrun=False, confirm=False,
                    progresscb=None):
-    """Stabilize a unstable changeset"""
+    """Stabilize an unstable changeset"""
     obs = orig.parents()[0]
     if not obs.obsolete() and len(orig.parents()) == 2:
         obs = orig.parents()[1] # second parent is obsolete ?
@@ -2017,7 +2055,9 @@
           ('n', 'dry-run', False, _('do not perform actions, just print what would be done'))],
          '[OPTION]...')
 def cmdprevious(ui, repo, **opts):
-    """update to parent and display summary lines"""
+    """update to parent revision
+
+    Displays the summary line of the destination for clarity."""
     wkctx = repo[None]
     wparents = wkctx.parents()
     dryrunopt = opts['dry_run']
@@ -2068,11 +2108,12 @@
           ('n', 'dry-run', False, _('do not perform actions, just print what would be done'))],
          '[OPTION]...')
 def cmdnext(ui, repo, **opts):
-    """update to next child
-
-    You can use the --evolve flag to get unstable children evolved on demand.
-
-    The summary line of the destination is displayed for clarity"""
+    """update to next child revision
+
+    Use the ``--evolve`` flag to evolve unstable children on demand.
+
+    Displays the summary line of the destination for clarity.
+    """
     wkctx = repo[None]
     wparents = wkctx.parents()
     dryrunopt = opts['dry_run']
@@ -2211,25 +2252,26 @@
 def cmdprune(ui, repo, *revs, **opts):
     """hide changesets by marking them obsolete
 
-    Obsolete changesets becomes invisible to all commands.
-
-    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 parent.
-
-    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 absorbed automatically).
-
-    If you specify multiple revisions in --succ, you are recording a "split"
-    and have to acknowledge it by usng --split. The same logic apply when you
-    prune multiple changesets with a single successors, this will record a
-    "fold" requires a --fold flag.
+    Pruned changesets are obsolete with no successors. If they also have no
+    descendants, they are hidden (invisible to all commands).
+
+    Non-obsolete descendants of pruned changesets become "unstable". Use :hg:`evolve`
+    to handle this situation.
+
+    When you prune the parent of your working copy, Mercurial updates the working
+    copy to a non-obsolete parent.
+
+    You can use ``--succ`` to tell Mercurial that a newer version (successor) of the
+    pruned changeset exists. Mercurial records successor revisions in obsolescence
+    markers.
+
+    You can use the ``--biject`` option to specify a 1-1 mapping (bijection) between
+    revisions to pruned (precursor) and successor changesets. This option may be
+    removed in a future release (with the functionality provided automatically).
+
+    If you specify multiple revisions in ``--succ``, you are recording a "split" and
+    must acknowledge it by passing ``--split``. Similarly, when you prune multiple
+    changesets with a single successor, you must pass the ``--fold`` option.
     """
     revs = scmutil.revrange(repo, list(revs) + opts.get('rev'))
     succs = opts['new'] + opts['succ']
@@ -2624,12 +2666,12 @@
     ] + commitopts + commitopts2,
     _('hg split [OPTION]... [-r] REV'))
 def cmdsplit(ui, repo, *revs, **opts):
-    """Split the current commit using interactive selection (EXPERIMENTAL)
-
-    By default, split the current revision by prompting for all its hunk to be
+    """split a changeset into smaller changesets (EXPERIMENTAL)
+
+    By default, split the current revision by prompting for all its hunks to be
     redistributed into new changesets.
 
-    Use --rev for splitting a given changeset instead.
+    Use --rev to split a given changeset instead.
     """
     tr = wlock = lock = None
     newcommits = []