Differences between revisions 21 and 25 (spanning 4 versions)
Revision 21 as of 2015-06-04 23:08:30
Size: 8992
Editor: AugieFackler
Comment:
Revision 25 as of 2015-10-23 16:21:51
Size: 6650
Comment: added data about behavior regarding branch name.
Deletions are marked like this. Additions are marked like this.
Line 19: Line 19:
=== Goals === == Current Target ==
Line 21: Line 21:
The main challenges to get such a feature right are: This describe the target semantic and behavior for topics.
Line 23: Line 23:
- '''Life cycle''':
  Grouping changes and naming the topic branch is usually only relevant while working to get the feature done. We need a natural/efficient way for the topic to fade away when feature are complete. [augie notes that it might be interesting/useful to be able to query the topic name after the topic is done]
=== General semantics ===
Line 26: Line 25:
- '''Distributed''':
  A good solution for topic branch should work well in a distributed environment, where users may be pulling from each other in arbitrary ways. Topic information must be exchanged at the same time as the commits they reference.
TL;DR; topic are an extra "light-branch" data relevant to draft changesets.
Line 29: Line 27:
- '''Clearly defined set of changes''':
  A topic is usually composed of multiple changesets. Being able to easily define what is in the set is important for commands that handle topics as a whole (eg histedit and email.) Having a good mechanism for this will probably help produce a better UI in evolution as well. Having a defined set of changesets is also needed when only part of the topic is pushed or pulled. A topic for a change can't be derived from its topological branch and a bookmark because sometimes topics share a root, and sometimes exploration leads to multiple heads on a topic. [TODO(marmoute: work with augie to explain this sentence) It can also be confusing when a topic is rebased.]
 * Topic is a ''name'' explicitly attached to changesets,
Line 32: Line 29:
- '''Anonymous branching''':
  Anonymous branches is a useful feature of Mercurial that adds flexibility and improves productivity. We should keep this strength available within each topic.
 * This Topic data is primarily meant to categorize ''draft changeset'' and fade out when things become public,
Line 35: Line 31:
- '''name conflict handling''':
  Fixing a bad name (or people fighting over a name) should not result in a very complicated situation (particularly around divergence.)
 * Changeset have both a ''topic'' and a 'branch'. The ''topic'' allow to gather related in progress work, while the ''branch'' data refer to the long terms line of development.
Line 38: Line 33:
=== Goals Under Debate ===  * Behaviors focus on ensuring any ''name'' have a single head.
Line 40: Line 35:
- '''Tracking/Target''':
  People typically make changes with the goal of getting them integrated into a specific line of development (default, stable, version 4.2, staging, etc). This "target" should be the default destination for merge, rebase, update, etc. This aspect can probably use (or maybe need) integration with the life cycle.
 * Behaviors related to named branches behave mostly as if the draft-with topic are not on the branch (yet).
Line 43: Line 37:
    ''augie notes that he doesn't like the conceptual complexity this introduces''  * Behaviors within a topic are similar (with minor sensible difference) to named branches one within the topic.
Line 45: Line 39:
=== General effect on named branch ===
Line 46: Line 41:
=== Current shortcomings of bookmarks === Changeset with topic are ''only aspiring'' to be part of the named branch, but not fully in that branch yet. when you have branch `foo` name `foo` is resolved to the heads of `foo` with no topic.
Line 48: Line 43:
This plan is not meant as "bookmarks are doomed, lets do something else." The idea here is more driven by "we have some long standing issues with bookmarks, lets think again from scratch and see what emerges." We'll reconcile topics with bookmarks at a later date, once we know what we want. It's entirely possible that bookmarks can grow bits of new functionality and become topics. Three is a couple of examples:
Line 50: Line 45:
There is currently an experimentation around the idea of "remote bookmarks" [TODO(augie): link to a remote bookmarks wiki page] and wider workflow changes, it will be "evaluated" independently. (it's a wiki, please feel free to update the content of this section) {{{#!dot
digraph {
  rankdir=LR
  node [shape=box,style=filled]
  A -> B -> C;
  B -> X -> Y;
  A [label="A\n(b: foo)"];
  B [label="B\n(b: foo)"];
  C [label="C\n(b: foo)"];
  X [label="X\n(b: foo)\n(t: bar)",fillcolor="lightblue"];
  Y [label="Y\n(b: foo)\n(t: bar)",fillcolor="lightblue"];
}
}}}
Line 52: Line 59:
||requirements || in-core || remote ||
||Life cycle || poor || poor ||
||distributed || okay || bad ||
||defined set || poor || poor ||
||partial exch || bad || okay ||
||branching || bad || bad ||
||conflict || okay || okay ||
||tracking || bad || good ||
Multiple heads are not longer ambiguous,
Line 61: Line 61:
The lifecycle of bookmarks is problematic because we still have not figured out a good way to handle deletion and renaming. Once in the wild, it is very hard to get rid of a feature related bookmark. [augie and marmoute are not sure if remote-bookmarks improves that.]  * The name `foo` resolve to C,
 * The name `bar` resolve to Y,
Line 63: Line 64:
Bookmark behavior in the '''distributed''' area is okay-ish for the in-core bookmark. The current behavior on pull works in a distributed way: it will exchange any bookmark along with the matching changeset. Behavior on push is problematic as the local bookmark may not be pushed (Mercurial may warn about it, but this is not reliable.) ----
Line 65: Line 66:
[TODO(marmoute): work with augie to clarify this sentence] The 'remote-boomarks' change is more problematic in this aspect as remote name are not propagated so changesets can get exchanged without there topic information. {{{#!dot
digraph {
  rankdir=LR
  node [shape=box,style=filled]
  A -> B;
  B -> X -> Y;
  A [label="A\n(b: foo)"];
  B [label="B\n(b: foo)"];
  X [label="X\n(b: foo)\n(t: bar)",fillcolor="lightblue"];
  Y [label="Y\n(b: foo)\n(t: bar)",fillcolor="lightblue"];
}
}}}
Line 67: Line 79:
'''tracking''' is not covered at all by current core version. It is introduced with 'remote-bookmark' but only covers rebase. Additionally, the UI to configure and observe tracking is unclear to [marmoute] yet. Partial data does not have radical change on the definition,
Line 69: Line 81:
A bookmark can implicitly '''define a set of revisions''' since everything 'only' under that bookmark it can be considered in the topic. This has issues:  * The name `foo` resolve to B,
 * The name `var` resolve to Y,
Line 71: Line 84:
 * Requires the use of bookmarks for the main branches
 * Misbehaves if a some part of the topic is shared with another bookmark
 * No way of handling of extra anonymous heads on the same topic
----
Line 75: Line 86:
Because they refer to a single changeset at the top of the stack, bookmark are bad at '''partial exchange'''. It is often practical to push or to pull only a part of the topic because the rest is not ready yet. Because the bookmark have no "start" the shared changesets are pulled anonymously in this case. {{{#!dot
digraph {
  rankdir=LR
  node [shape=box,style=filled]
  A -> X -> B;
  A [label="A\n(b: foo)"];
  X [label="X\n(b: foo)\n(t: bar)",fillcolor="lightblue"];
  B [label="B\n(b: foo)"];
}
}}}
Line 77: Line 97:
For the same reason (referring to a single revision), bookmarks do not allow for experimental branches within a topic label. Usual traversal rules apply:
Line 79: Line 99:
Divergent bookmarks provide a solution for '''conflict'''. However it does not handle rewinding a bookmark or deletion/recreation cycles.  * The name `foo` resolve to B,
 * The name `var` resolve to X,

=== Behavior for update ===

This implies change in hg update behavior (but are not super relevant)

=== Behavior for merge ===

This assume `hg rebase` and `hg merge` to be identical

=== Behavior for push to publishing (default repo) ===

=== Behavior for push to non-publisehd repo ===

=== Stacked diffs workflow ===

=== User Transition ===

== Pro and Cons ==

== Other questions ==
Line 83: Line 124:
This is a list of idea that emerged while brainstorming. This is a list of idea that emerged while brainstorming. This served as base for the current things.
Line 113: Line 154:
Code is available at [[http://hg.durin42.com/hg-topic-experiment/]].
Line 126: Line 169:
== See also ==

 * FeatureBranchesStruggle

Note:

This page is primarily intended for developers of Mercurial.

Topic Plan

A (speculative) plan for topic branching that would work more seamlessly with common Mercurial workflows. Still very early prototype stage. Everything is subject to change.

1. Problem Statement

The Mercurial community has been struggling for years to define a nice way to handle 'topic' branches (sometimes also called 'feature' branches), especially when it comes to sharing them with other people (mainly for code review or other collaboration.)

Bookmarks are a clone of git's refs, which seems to work more poorly in Mercurial than they do in Git, in part because the synchronization parts of bookmarks aren't really done. Adding the remaining bits of git's refs to Mercurial has been controversial, and may represent enough of a behavior change that it's infeasible.

Named branches are visible forever in the revision history, which makes them unsuitable for feature branch work as the feature branch names rapidly pollute the output of things like hg branches.

2. Current Target

This describe the target semantic and behavior for topics.

2.1. General semantics

TL;DR; topic are an extra "light-branch" data relevant to draft changesets.

  • Topic is a name explicitly attached to changesets,

  • This Topic data is primarily meant to categorize draft changeset and fade out when things become public,

  • Changeset have both a topic and a 'branch'. The topic allow to gather related in progress work, while the branch data refer to the long terms line of development.

  • Behaviors focus on ensuring any name have a single head.

  • Behaviors related to named branches behave mostly as if the draft-with topic are not on the branch (yet).
  • Behaviors within a topic are similar (with minor sensible difference) to named branches one within the topic.

2.2. General effect on named branch

Changeset with topic are only aspiring to be part of the named branch, but not fully in that branch yet. when you have branch foo name foo is resolved to the heads of foo with no topic.

Three is a couple of examples:

Multiple heads are not longer ambiguous,

  • The name foo resolve to C,

  • The name bar resolve to Y,


Partial data does not have radical change on the definition,

  • The name foo resolve to B,

  • The name var resolve to Y,


Usual traversal rules apply:

  • The name foo resolve to B,

  • The name var resolve to X,

2.3. Behavior for update

This implies change in hg update behavior (but are not super relevant)

2.4. Behavior for merge

This assume hg rebase and hg merge to be identical

2.5. Behavior for push to publishing (default repo)

2.6. Behavior for push to non-publisehd repo

2.7. Stacked diffs workflow

2.8. User Transition

3. Pro and Cons

4. Other questions

5. Open ideas

This is a list of idea that emerged while brainstorming. This served as base for the current things.

  • Topic could be a property attached to each changeset (grouping them by similar topic)
  • Topic could fade away when changesets become public (either archived or plain dropped)
    • A benefit of archiving them is that users can query for topics, eg you could say hg log -r topic(issue123) which would help

  • Tracking could be achieved through the naming scheme. eg:
    • 'default//feature-foo' would be a topic 'feature-foo' tracking the 'default' branch.
    • 'stable//issue4700' would be a topic 'issue4700' tracking branch stable.
    • '@//feature-bar' would be a topic 'feature-bar' tracking bookmark '@' ?
    • 'stable//issue4689//issue4700' would be a topic 'issue4700' tracking the topic 'stable//issue4689'. When topic 'issue4686' face away (because published), the tracking fallback to 'stable'.
  • Topics could be non contiguous (mpm idea) feature-foo -> fix-bar -> feature-foo. Allowing a streamlined work that is automatically split apart after that.

  • Topics could be hierarchical 'issue4700.test' 'issue4700.preparation', activation//reference could be done at any level 'issue4700' or 'issue4700' (this could help handle branching/different approach)
  • pushing a new head on a new topic to a non-publishing server would be allowed.

    • that is, it'd be legal to have one head per topic on a non-publishing server.
  • A changeset could maybe have multiple topic.
    • Augie doesn't feel great about this option just because of UI complexity.
  • Users can name patches (in a sense) without mq
    • One of the major complaints about evolve from veteran mq users is that their patches no longer have explicit names. Topics provide a potential way to name patches again.

6. Current Implementation

Assign topics to non-public changesets. A topic is like a named branch, in that it is a label stored in a changeset's extra, but that topics just disappear when the change moves to public phase (the data still exists, it's just not shown.)

Code is available at http://hg.durin42.com/hg-topic-experiment/.

6.0.1. Non-Goals

  • Topics are not suitable for long term branches. We have named branches for that (and possibly also bookmarks, depending on workflow.)
  • Topics are not suitable for tracking a moving point in public history. This seems to be a perfect fit for bookmarks.

6.1. Open Questions

  • Right now we use changeset extra for storing the topic. That might lead to bonus divergence problems. They might be easily fixed, but should we avoid that?
  • Should changesets be allowed multiple topics?
  • How permissive should we be on topic names?

7. See also


CategoryDeveloper and CategoryNewFeatures

TopicPlan (last edited 2021-10-08 14:11:59 by GeorgesRacinet)