/!\ This page is primarily intended for Mercurial developers

There are a number of things that have to be discussed about how the Evolve UI works.

Glossary

Which language should we use for Evolve? Remember that once this goes into core, this language gets frozen forever.

1. Command names

/!\ This sub-section need rework/splitting/movement/unicorn before being useful

2. Concepts

/!\ This section need rework/splitting/movement/unicorn before being useful

3. Terminology Opinions

/!\ This section need rework/splitting/movement/unicorn before being useful

Ideally we're searching for a grammar where everything is related. If we have words that are closely associated in the English language, users will associate them with related version control tasks. It reduces the potential for confusion and increases the probability for knowledge recall. With that in mind, I'm not sure words like "evolve" and "troubled" go together well. You wouldn't think "this thing is troubled, therefore I'm going to evolve it." I would think "stablize" or "solve" would be much better verbs to complement "troubled." "This thing is troubled, therefore I'm going to stablize it" makes more sense, IMO. But I think there's still room for improvement in the grammar. --indygreg

Commands

/!\ This section wants to be:

hg fold

/!\ This sub-section need rework/splitting/movement/unicorn before being useful

Currently fold can work in two modes: folding between a target revision and ".", or given an explicit set of revisions, fold this set into a single revision. The current UI for this is weird: for the first mode you specify revisions without --rev and the second mode you specify them with --rev. This UI is inconsistent with the rest of Mercurial. We have several examples of commands that take revisions with or without a --rev argument, and in all these cases, the behaviour is the same, and the --rev specifier is just optional:

Jordi has proposed patch to address this that treats revisions with and without --rev the same way and obtains both kinds of behaviours depending on whether a single or multiple revisions are specified. However, this has other problems. With certain revsets, it may not be easy to know in advance how many revisions are actually in the revset, so it would be surprising to get different behaviour depending on the number of revisions.

How to solve this?

Behavior

Automatic "hg evolve" call

/!\ This sub section need rework/splitting/movement/unicorn before being useful

/!\ no decision are will be made on this any time soon, concider using your brain power elsewhere.

Many evolve commands produce unstable changesets. Should they immediately call hg evolve by default?

1. pros

2. cons

Perhaps ui.autoevolve option? On by default? Off by default?

I think auto evolve makes sense in some cases. For example, say you amend a commit with descendants and only change the commit message. Why wouldn't you want auto evolve in that scenario? -- indygreg

I think the "there are now troubled commits message" should be actionable. Currently it just prints the count of troubled commits. I'd really like to see a "run hg evolve to stablize" message. If we don't auto evolve, at least we can tell the user what they should probably be doing next. -- indygreg

Use Cases

1. Undoing an amend

Users will often accidentally amend a commit. We need a good story to undo them.

This mean changing the commit content, but not touching the working directory. The hg uncommit command is already responsible for this action.

Growing a was to easily call uncommit on the precursor intead of the parent would fit that need:

(Git have a git reset HEAD@{1} notation for this. However, introducing a git-reset like command in Mercurial is a non-goal)

Pain Points

1. Evolve can "stabilise" to unstable destination

1.1. Situation

Start with a linear graph:

and amend 1 and 3 to create aa' and bb'. This gives us this graph:

The red changesets are marked as obsolete, and the orange changesets are thus troubled. Starting from bb, getting this repo back into an untroubled state takes 6 calls to 'hg evolve', the last 4 of which need --any.

1.2. Explanation of the current behavior

This happens because evolve first started to rebase c and cc on B. After that it asked to --any to start evolving B, BB' and C' and CC' over aa'.

1.3. Possible improvement

The shortest path to stabilization would have been to take care of B and BB' first then directly evolve C and C on the result.

The fact that hg evolve think evolve B is unrelated to BB' (then requires --any) sounds wrong too.

Both point can be fixed if we make evolving ancestors "relevant to the context" (not requires any).

(This case is not a valid case in favor of hg evolve --all)

2. The obsolete history is not very usable

/!\ This section need some clarification /!\ consider using a 1. Example 2. explanation 3. possible actions format

In order for evolve to achieve its full potential the hidden history that that evolve creates must be not only useful for enabling amending shared revisions but also _usable_ by the user to get back to old versions of a given revision (e.g. in case that the user is not happy with a later version of that revision).

Currently the obsolete history created by evolve is not very usable because the number of hidden, obsolete revisions created by evolve is greater than it should. In particular:

- Each history modification step creates its own set of obsolete revisions. There is no way to perform several history editing operations and combining those into a single operation.

/!\ Why do you say evolve creates more obsolete changeset that it could. Do you have a concrete example of situation where it does? (beside the extra temporary commit thing)

An alternative to this would be for evolve to provide tools to filter or show the obsolete history somehow.

/!\ This second point is very interresting, there is multiple direction where we could improve that. Can you elaborate on your filtering idea?

F.A.Q.

1. Why do we have a temporary commit after amend?

It is an implementation details that will eventually be removed