Differences between revisions 48 and 49
Revision 48 as of 2017-01-23 14:59:03
Size: 13496
Comment:
Revision 49 as of 2017-03-13 18:40:02
Size: 13570
Comment:
Deletions are marked like this. Additions are marked like this.
Line 351: Line 351:
 * Cycles: [[CEDCycles|Handling of cycle in the obsolescence markers]]
Line 352: Line 353:

Changesets Evolution - development page.

/!\ This page is intended for developer

{i} For a user perspective see ChangesetEvolution.

1. Contributing

The simplest way to help is to grab one of: list of easy bug

There is also a multiple well defined topic that where idea exist but needs an implementation

  • Rebase could make more use of obsolescence marker:
    • detection that part of the rebase set is already in the destination
    • warning about divergence creation.
  • Obsolescence markers exchange (no really we have idea waiting to be implemented)

  • Prototype for a command bringing changeset back to life.

There is more complicated part that requires attention too.

  • Better storage//loading//cache for markers (depends on marker exchange)

  • Solving the problem of Topic Branch

  • Handling moving changesets around with the "plan" concept,
  • in memory merge (helps a lot of troubles resolution throught evolve)

  • Wide transaction capability
    • Continue/stop/abort for all command including evolve
    • In transaction content non exchangeable.
  • Making evolve capable of solving all troubles that user can encounter
  • Computing UI message about troubles from event who happened during the transaction.

2. Roadmap

See CEDRoadMap

Other concept not directly involved in Changeset Evolution and closely related for technical or user experience reason.

4. In progress Features and discussion

4.1. Using Obsolescence Marker during Rebase

There is two big issues with rebasing a set containing obsolescence changeset:

  • It is easy to create divergence
  • You get a lot of conflict when rebasing an obsolete stack on it's successors version.

To enable the current implementation set the config experimental.rebaseskipobsolete to true.

Current progress:

  • (./) rebase can skip obsolete changeset when rebased on successors,

  • (./) same logic as above, handling prune,

  • (./) same logic as above, handling split,

  • (./) ability to detect divergence creation and bail out,

  • {X} ability to rebase set with obsolescence inside the set (rebasing both precursors and successors) without creating divergence,

  • {X} official config to control these two behavior (either in one or two config)

  • {X} config on by default.

4.2. `hg evolve --list`

This is also tracked in https://bz.mercurial-scm.org/show_bug.cgi?id=4845

Evolution can compute a lot of information out of the obsolescence graph. It already use it to compute troubles and automatically solve them. Yet this information is not easily accessible to the user.

We would like to gain a basic version of hg evolve --list that would provide all available information on current troubles.

4.2.1. Output Proposal

  • CHANGESET
    • - TROUBLE: REASON - TROUBLE: REASON
    CHANGESET
    • - TROUBLE: REASON

More concrete example:

5633576f2df1: unbundle: cleanly abort on unknown ...

  • unstable: parent 485eb2a02a2b is obsolete bumped: precursors ec2662b9629d is public divergent: precursors 4a8e21578e14 have another succcessor 84dcc37b1272 divergent: precursors 4a8e21578e14 have another succcessor 2a3010ba6f52

We want to ensure this is implemented through the 'formatter' API so we gain structured output easily "eg -Tjson"

4.2.2. Command Line API

We probably want

  • --rev to allow select revision to display

  • --unstable/--bumped/divergent to restrict the trouble we display.

4.2.3. Details on Each Trouble Cases

Here is some idea for data we could provide in each cases. This provide an handy list of case in the process.

4.2.3.1. Unstable from Obsolete Parent
  • reason: unstability comes from parent being obsolete
  • Source: What is this obsolete parent,
  • Evolution target: What the evolution will turn the parent into (beware of pruned changeset)
  • We should mention problematic split,

4.2.3.2. Unstable from Unstable Parent
  • reason: unstability comes from parent being unstable
  • Source: What is this unstable parent,
  • parent needs to be evolved before that one.

4.2.3.3. Unstable Merge
  • If both parent have obsolescence/troubles, we must issue two entries

4.2.3.4. Bumped Changeset
  • Point at the public changeset
  • Mention if we need a rebase or not
  • ADVANCE: Is there a commit message change

4.2.3.5. Divergent Changeset
  • Point at the other divergent changeset
  • Point at the "greater common evolution ancestors" of divergence
  • Says if this GCEA is known locally
  • Point "greater locally known common evolution ancestors" in addition
    • otherwise.
  • mention if we need a rebase or not,
  • The "divergent with a split" case…

4.2.3.6. Divergent with the other side public

This is actually one of the most common divergence scenario. We probably need a dedicated name for this.

  • We should mention that the other side is public/immutable.

4.2.3.7. Visible Obsolete Changeset

Should list them with a mention of why they are still visible?

4.3. obsmarker support in `hg strip`

We would like to be able to strip obsolescence marker related to a changeset when stripping it.

We want:

  • (some) way to disable it ("nice way" can come later),
  • the obsmarker to be in the backup bundle,
  • A mode where we strip all markers between the stripped one and first known
    • precursors (default?)
  • A mode where we strip all precursors too (and associated markers) (beware of
    • untargeted descendant of precursors, cf drophack).

The "obsmarker in the backup bundle" will requires some work because there is no other place storing obsmarkers in an on disk bundle. However, all infra should be in place as we already exchange obsmarker over the wire through a bundle.

In the same go, you can consider adding obsmarker support to hg bundle through the "variants" part of the type.

4.4. `hg evolve --continue/--abort/--drop`

Currently evolve implement a super basic state format that does not allow a proper "multi step" behavior.

4.4.1. About `--continue`

Current issues

  • does not remember the currently evolved set (just finish the current one)
  • does not work for --bumped or --divergent

We need to update the format on disk to allow these.

4.4.2. About `--abort`

This does not exists but it would be useful.

  • We need to know the evolved set,
  • We must also record and remove obsmarker we created in the process.

4.4.3. About `--drop`

Currently, user can "abandon" his evolve at any time. leaving half of the thing evolved and the other one still unstable. That is a pretty cool feature we want a way to keep. Adding a flag could be a way. openning the way to similar feature in other multi step command.

Name is not frozen, this is the first time we mention it.

Maybe we just want hg up -C to be that, but it seems a bit too easy to run by mistake.

4.5. Tagging draft changeset

Currently tagging draft a changeset may lead to issues when the tagged changeset is rewritten and its hash change, making the tag invalid.

Here is a small (draftish) list of ideas to handle the question, the first one "rewriting the tag file when we evolve/rewrite the tagging changeset" is probably the way to go.

Mailing list discussion about this: https://www.mercurial-scm.org/pipermail/evolve-testers/2016-May/000178.html

4.5.1. rewriting the tag file when we evolve/rewrite the tagging changeset

When the tagging changeset is evolved (changed from a descendant of the old tagged, to the new version), we could rewrite the content of the tag file.

Pro:

  • Does "the right thing"™
  • Works even if the tagged changeset is pulled -after- the rewrite.

Cons:

  • Only work when the tagging changeset is a descendant of the tagged,
  • Does not handle the local case.

4.5.2. Warn when pushing a draft tag

The idea is that pushing a tagged changeset as draft increase the risk of rewrite, so warning could help having user think about turning them public.

Pro:

  • easy to do,
  • can be reverted when we need something better,
  • prevent the error to pass silently,

Cons:

  • Does not actually solve the problem,
  • Does not handle the local case.

4.5.3. Warn when rewriting a draft tag

Pro:

  • easy to do,
  • can be reverted when we need something better,
  • prevent the error to pass silently,

Cons:

  • Does not actually solve the problem,

4.5.4. Turning the changeset public on tagging

Pro:

  • Prevent any tag rewrite issue,
  • easy to do,
  • handle both local and remote case,

Cons:

  • loose the ability to fix tagging error before publishing,
  • break backward compatibility,
  • hard to revert if we get something better,

4.5.5. Turn the tagged changesets public on push

Pro:

  • Turn changeset public at the time it become more complicated,

Cons:

  • loose the ability to fix tagging error before publishing,
  • break backward compatibility for non-publishing repo,
  • hard to revert if we get something better,
  • do not handle the local case.

4.5.6. refuse to tag draft

Pro:

  • Get rid of the issue (almost) entirely,
  • handle local and remote case,

Cons:

  • massive backward compatibility breakage, sensible user script will break,
  • hard to revert if we get something better

4.6. Obsolescence Marker Discovery

4.7. amend/uncommit/recommit/etc

A recurring discussion is "What should be 'base' for the 'amend' operation" (or other related command).

The complexity of the situation comes from the fact we have 3 states of interest

  1. wc(): The working copy content (on disk file)

  2. p1(): The working copy parent content (commit content, affected by commands)

  3. p1()~1: The working copy parent (commit content).

Various core command already allow to interact with these layers.

* The commit command move content from wc() to p1() (creating a new p1()) in the process), * The commit --amend is just a variation of that moving content from wc() to p1() (reusing the existing one). * The revert command move content from p1() to wc() * The revert --rev command move content from any commit content to wc()

Evolve have various commands in this area too.

* The amend command mimic commit --amend, moving content from wc() to p1() * The uncommit command move content from p1()~1 to p1().

A common question is to change the default of amend to use p1()~1 as base. Picking change from wc() when selected and resetting to p1()~1 for excluded content. "Just changing the default" is not a solution here. We have multiple possibilities (because we have 3 states to select from) and if we change from one to the other, some people will just start asking for the other one instead.CategoryNewFeatures

However, having an easy way to select the mode would be nice, gather all usecase into a single command would be preferable. Building a good UI for that might allow us to remove the dedicated uncommit command and provide a recommit capabilities that people have been asking for.

5. See Also


CategoryNewFeatures CategoryDeveloper CategoryEvolution

ChangesetEvolutionDevel (last edited 2020-05-29 08:03:48 by aayjaychan)