evolve extension#

extends Mercurial feature related to Changeset Evolution

This extension:

  • provides several commands to mutate history and deal with resulting issues,

  • enable the changeset-evolution feature for Mercurial,

  • improves some aspect of the early implementation in Mercurial core,

While many feature related to changeset evolution are directly handled by core this extensions contains significant additions recommended to any user of changeset evolution.

With the extension various evolution events will display warning (new unstable changesets, obsolete working copy parent, improved error when accessing hidden revision, etc).

In addition, the extension contains better discovery protocol for obsolescence markers. This means less obs-markers will have to be pushed and pulled around, speeding up such operation.

Some improvement and bug fixes available in newer version of Mercurial are also backported to older version of Mercurial by this extension. Some older experimental protocols are also supported for a longer time in the extension to help people transitioning. (The extension is currently compatible down to Mercurial version 6.7).

New Config:

[experimental]
# Set to control the behavior when pushing draft changesets to a publishing
# repository. Possible value:
# * ignore: current core behavior (default)
# * warn: proceed with the push, but issue a warning
# * abort: abort the push
auto-publish = ignore

# For some large repositories with few markers, the current method for
# obsolescence marker discovery can get in the way. You can disable it by
# setting the following configuration option to "no". Then all pushes and
# pulls will re-exchange all markers every time.
evolution.obsdiscovery = yes

Obsolescence Markers Discovery#

The evolve extension containts an experimental new protocol to discover common markers between local and remote repositories.

"Large" repositories (hundreds of thousands) will take some time to warm the necessary cache. Some key algorithm has a naive implementation that can result in large memory or CPU Load.

The following config controls the new protocol:

[experimental]

# enable new discovery protocol
# default to "yes"
obshashrange = yes

# control cache warming at the end of transaction
#   yes:  warm all caches at the end of each transaction
#         (recommended for server),
#   off:  warm no caches at the end of transaction,
#         (no cache overhead during transaction,
#          but cache will be warm from scratch on usage)
#   auto: warm cache at the end of server side transaction(ie: push)
#         (default).
obshashrange.warm-cache = 'auto'

When you switch to using this protocol, we recommand that you explicitly warm cache for your server side repositories.:

$ hg debugupdatecache

It is recommended to enable the blackbox extension. It gathers useful data about the experiment. It is shipped with Mercurial so no extra install is needed:

[extensions]
blackbox =

Finally one more option is available to help tame the experimental implementation of some of the algorithms:

[experimental]
# automatically disable obshashrange related computation and capabilities
# if the repository has more than N revisions.  This is meant to help large
# server deployment to enable the feature on smaller repositories while
# ensuring no large repository will get affected.
obshashrange.max-revs = 100000 # default is None

For very large repositories, it might be useful to disable obsmarkers discovery (make sure you follow release announcements to know when you might want to turn it back on):

[experimental]
evolution.obsdiscovery = no

Effect Flag Experiment#

Evolve also records what changed between two evolutions of a changeset. For example, having this information is helpful to understand what changed between an obsolete changeset and its tipmost successors.

Evolve currently records:

  • Meta changes, user, date

  • Tree movement, branch and parent, did the changeset moved?

  • Description, was the commit description edited

  • Diff, was there apart from potential diff change due to rebase a change in the diff?

These flags are lightweight and can be combined, so it's easy to see if 4 evolutions of the same changeset has just updated the description or if the content changed and you need to review again the diff.

The effect flag recording is enabled by default in Evolve 6.4.0 so you have nothing to do to enjoy it. Now every new evolution that you create will have the effect flag attached.

The following config control the effect flag recording:

[experimental]
# uncomment to deactivate the registration of effect flags in obs markers
# evolution.effect-flags = false

You can display the effect flags with the command obslog, so if you have a changeset and you update only the message, you will see:

 $ hg commit -m "WIP
 $ hg commit -m "A better commit message!"
 $ hg obslog .
@  8e9045855628 (3133) A better commit message!
|
x  7863a5bb5763 (3132) WIP
     rewritten(description) by Boris Feld <boris.feld@octobus.net> (Fri Jun 02 12:00:24 2017 +0200) as 8e9045855628

Servers does not need to activate the effect flag recording. Effect flags that you create will not cause interference with other clients or servers without the effect flag recording.

In-memory Evolve Experiment#

The `hg evolve` command normally creates new changesets by writing the files to the working copy and then committing them from there. You can tell it to create the changesets without touching the working copy by setting this config:

[experimental]
evolution.in-memory = yes

It will still update the working copy in case of conflicts.

Template keywords#

Evolve provides one template keyword that helps explore obsolescence history:

  • obsorigin, for each changeset display a line summarizing what changed between the changeset and its predecessors. Depending on the verbosity level (-q and -v) it displays the users that created the obsmarkers and the date range of these operations.

Evolve used to provide these template keywords, which since have been included in core Mercurial (see `hg help templates -v`):

  • obsolete

  • obsfate (including obsfatedata, see also obsfate* template functions)

For compatibility, this extension also provides the following aliases to template keywords from core Mercurial:

  • precursors (deprecated, use predecessors instead)

  • successors (deprecated, use successorssets instead)

  • troubles (deprecated, use instabilities instead)

Revset predicates#

Evolve provides several revset predicates:

  • unstable

  • troubled (deprecated, use unstable instead)

  • suspended

  • predecessors

  • precursors (deprecated, use predecessors instead)

  • allpredecessors

  • allprecursors (deprecated, use allpredecessors instead)

  • successors

  • allsuccessors

Note that successors revset in evolve is not the same as successors revset in core Mercurial 4.3+. In evolve this revset returns only immediate successors, as opposed to all successors. Use "allsuccessors(set)" to obtain all successors.

See `hg help revsets -v` for more information.

Commands

  • amend: combine a changeset with updates and replace it with a new one

  • evolve: solve troubled changesets in your repository

  • fixup: add working directory changes to an arbitrary revision

  • fold: fold multiple revisions into a single one

  • gdown: gdown have been deprecated in favor of previous

  • gup: gup have been deprecated in favor of next

  • metaedit: edit commit information

  • next: update to next child revision

  • obslog: show the obsolescence history of the specified revisions

  • pdiff: show diff combining committed and uncommitted changes

  • pick: move a commit onto the working directory parent and update to it.

  • previous: update to parent revision

  • prune: mark changesets as obsolete or succeeded by another changeset

  • pstatus: show status combining committed and uncommitted changes

  • rewind: rewind a stack of changesets to a previous state

  • split: split a changeset into smaller changesets

  • touch: create successors identical to their predecessors but the changeset ID

  • uncommit: move changes from parent revision to working directory