How do tags in Mercurial get propagated to all branches automatically?

226 Views Asked by At

Let's say I have some 50+ feature branches in Mercurial. If I do:

hg tag some-tag

in one of the feature branches, it seems to propagate to all branches. Regardless of which feature branch I am in, hg tags will show all tags. That's all well and good. But if I do hg log, it will tell me that the changeset containing the change to .hgtags occurred in a specific branch:

changeset:   4:ea48c727fbcd
branch:      feat1
tag:         tip
user:        Daniel <[email protected]>
date:        Mon Dec 21 20:15:11 2015 +0100
files:       .hgtags
description:
Added tag feat-1.0 for changeset 3c81a17d4b31

How does Mercurial keep .hgtags in sync across all branches? I've read Mercurial Tag Design, but it doesn't mention any specifics.

The reason I am asking is that we're using Rhodecode for Mercurial at work and this propagation seems to lag significantly when it is under heavy load.

This lag is really annoying since I can see the latest tag in the .hgtags file, but hg tags doesn't list the latest tag. Doing yet another tag sometimes resolves the issue (and maybe it's a bug in Rhodecode), but I would like to know how this works in order to understand the underlying mechanism better.

1

There are 1 best solutions below

0
Mark Tolonen On

Quoting some documentation:

The tags that are in effect at any given time are the tags specified in each head. A difficult case arises, if the same tag specifies two different revisions in two different heads. There is no general "correct" solution to this problem.

If two definitions/changes of tags seem unrelated...the "tipmost" (e.g. the one with the higher numeric revision number) wins.
...
However if a tag was defined in a common ancestor of both heads, but changed in just one head, the changed one wins over the unchanged one.

Also:

If there is just one head only the last line where the tag appears is taken into account. If there are multiple heads, the previous definitions of the tag are used to determine which head holds the most recent tag.... If a tag points to 0000000000000000000000000000000000000000 it is considered to be deleted.

My guess is the lag is when you have multiple tags in multiple branches that need resolution, Mercurial has to look up each changeset to determine its revision to determine "tipmost". Only the changeset hash and tag name are in .hgtags.