Clone wiki

hgext-branchident / BranchIdentityPlan

Separating branch name from branch identity

Problem

The existing branch naming infrastructure (Mercurial 1.4) has some shortcomings.

For example, assume you have a project A with a branch named "release-1.2". Then assume you have a follow-up project B that wants to reuse the code base of A. In the scope of project B, branch names like "release-1.2" at best pollute the branch namespace of B. Sure, with current Mercurial, you can close the branch "release-1.2" but project B might want to have a "release-1.2" as well, but those two are not the same then. The closed "old variant" of "release-1.2" still pollutes the branch namespace of project B.

In contrast, a follow-up project B of a project A can remove meaningless tags like "release-1.2.7". Such a tag is only relevant in the scope of project A, but not in the scope of a follow-up project B. So it is a feature to be able to delete the tags in .hgtags.

  • The current branches can not be renamed, since the branch name is directly "burned" into history forever. The current branch name establishes the identity.
  • You cannot remove a branch name.
  • Current branch names cannot handle branch name conflicts.

Solution draft

Add a '''branchid''' extra field (!= changeset id), and allow later revisions (revisions with higher revision numbers) to override the branch name of earlier ones.

Example:

o  rev 3, branchid:7d3dab845c956436e2eacdb468dfbd62455600d3, branch:red
|
o  rev 2, branchid:7d3dab845c956436e2eacdb468dfbd62455600d3, branch:blue
|
o  rev 1, branchid:7d3dab845c956436e2eacdb468dfbd62455600d3, branch:blue
|
o  rev 0

Revisions 1 and 2 have the branch name "blue". In revision 3, the same branch (7d3dab845c956436e2eacdb468dfbd62455600d3) was renamed to "red". The branch name of rev 3 overrides previous names of the same branch, so revision 3 renames the branch "blue" to "red".

A branch name may be removed by overriding it with the empty branch name (or the 'default' branch name).

Questions and possible answers

Q: Should this be implemented in core Mercurial or as an extension?
A: Probably as an extension (if possible)

Q: How should branch id's be picked?
A: Calculate the sha-1 hash from the concatenation of for example, node id's of parent revisions, username, date, and branch name. This branch-id would then propagate onto child csets like the current branch name.

Q: How do these new branch names interact with the existing branch names?
A: Current, "direct" branch names can coexist with the new branch names. The distinction is made with the additional extra field 'branchid'.

Advantages

Branches can be renamed.

Branches could be unnamed, having only a branch-id.

Branch names can be removed (of course, the branch by itself cannot be removed because the branch-id's on the changesets they were applied to cannot be removed without altering history).

Branch name conflicts can be resolved: Consider Alice's repository has named branch 'for-joe', and Bob has also a 'for-joe' branch, but which has nothing in common with Alice's branch with the same name. What happens if both are pulled (or pushed) to Joe's repository? The conflict can be resolved by renaming one branch.

Updated