Bookmarks in core?

Didly Bom didlybom at
Mon Dec 6 05:44:17 CST 2010

On Thu, Dec 2, 2010 at 12:44 AM, Matt Mackall <mpm at> wrote:

> On Wed, 2010-12-01 at 23:45 +0100, Martin Geisler wrote:
> > Matt Mackall <mpm at> writes:
> >
> > > On Wed, 2010-12-01 at 09:13 +0100, Martin Geisler wrote:
> > >
> > >> If one could mark a bookmark as fixed, then it would behave like a
> > >> tag,
> > >
> > > Ugh, no, not this again.
> > >
> > >
> > > Look, here are the basic properties of any sensible implementation of
> > > tags:
> > >
> > > a) in history (auditable, signable, etc.)
> >
> > There is nothing that prevents you from including a committer name and a
> > signature in a bookmark.
> That's not anything like being auditable.
> > > b) mutable
> > > c) can be applied after the commit they refer to
> > >
> > > You -really- want ALL these properties for tags on a real project, but
> > > most critically, you want (a). If you decide to use bookmarks instead
> > > of tags, and someone accidentally nukes one (or even just moves it),
> > > you'll have no record of that happening and no way to get it back.
> >
> > I think you're being too pessimistic here.
> Ok, let's say you freshly clone the Mercurial repo onto your laptop and
> discover it has no 0.5 tag. How do you figure out how that happened?
> Answer: you can't without reference to other repositories, which may or
> may not still exist, you may or may not know about, and you may or may
> not have access to. And the longer the tag was missing without anyone
> noticing, the more likely it's going to be impossible to figure out
> where it went and what went wrong.
> This is so obviously screamingly horribly wrong to me that I'm amazed I
> even need to argue against it. Replace 'tag' with 'file' above and bang
> head on desk until you're enlightened, please.
> If you want a thing that's like a bookmark but isn't, fine. But don't
> pitch it as a tag replacement if you want me to not object violently to
> it.
> > You must acknowledge that a lot of people are unhappy with the current
> > design of tags in Mercurial.
> Sure. That's because a lot of people haven't thoroughly weighed the
> alternatives. Or have forgotten the numerous discussions we've had about
> those alternatives (*cough*Martin*cough*).
> I've spent a few hours summarizing that here to save myself future
> rehashing:

Hi Matt,

thank you for the excellent write up. I think that it is a very clear
summary of the reasons behind the design of the tag feature in mercurial.
Clearly you have given a lot of thought to this subject.

While reading the wiki, I was a little surprised that I agree with most of
its contents; despite the fact that the way tags work is probably the only
part of mercurial that I don't agree a 100% with. Thus, for the past few
days I've tried to understand why that is and I've come to the following
conclusions. I hope you don't mind me commenting them here with you. My
intention is giving you the perspective of a user so that perhaps you can
see why some are not fully satisfied with the current solution. This email
will be long! :-)

The first thing that I noticed is that when you discuss the "Basic desirable
tag properties" you set as a requirement that tags must be "In history". I
think that here you are in fact mixing two different requirements, one of
which is certainly essential while the other one is not. In particular, I
think that tags must “_have_ history". The version control system _must_
keep track of changes on the tags and you _must_ be able to go back in time
to a previous tag "state" and see who changed a tag and when. However I do
not think that having the tag history mixed with the source history is a
"Basic desirable tag property". I think that it is a UI decision that has
its own set of drawbacks (which I'll discuss later) but it is not an
essential feature of a good tag system.

In section five you "Explore the alternate solution space". In there you
have the section "What if we had separate revlogs for tags that weren't part
of normal history?" where you say that:

"This would also be significantly more baroque and confusing from the user
perspective ("There's a whole separate normally-invisible history of

I think that this statement is not backed up by facts and in fact the
opposite may be true! Where you _imagine_ a question such as "There's a
whole separate normally-invisible history of tags?" I _get_ (on a day to day
basis!) questions such as "Why does creating a tag create a new commit??",
"Why does the "tag commit" appear as a child of the current revision?" and
so on! So I believe that at most the fact that tags are "in history" is a
User Interface decision. While your document addresses most of the key
issues behind the design of mercurial tags it does not really address the UI
issues that may be leading to the slight dissatisfaction that some users (me
included) have with the way tags work.

The second thing that I noticed is that section 6, "Examining the
downsides", does not address the main downside that I personally see on the
current design, which is "tag and source history get mixed". I think that
you do not address it because you believe that it is one of the requirements
of a good tag system (after all you stated that tags must be "in history").
However as I said earlier I do not agree with that.

I think that mixing both histories has several important downsides:

- It makes the source code history look more complicated than needed. You
get a bunch of extra commits _in addition_ to your tags. For many users it
is very surprising that when they apply a tag to their tip their tip is no
longer the tip! They are often surprised when they apply a tag to an old
revision and a new commit appears somewhere else in the history (i.e. as a
child of their current revision).

- In order for it to work mercurial must treat the .hgtags file as a "magic
file" with special properties. This is hard to understand, _very hard_ to
explain and leads to a lot of questions such as "Why is this tag set if I
don't see it on the .hgtags file?" and "Mercurial looks at all the .hgtag
file on all the heads to tell which tags are active??"? In my opinion these
questions are much harder to explain than "There's a whole separate
normally-invisible history of tags?" would ever be.

- It makes it hard to "navigate" the tag history. How do you go back in time
and see the old state of tags at a certain time in the past? You cannot
simply update to an old revision, because mercurial still looks for the
state of the .hgtags file in all the heads (since this is what you normally
want). As far as I can tell the only way is to clone the repository to an
old revision.

- It has the side effect of making tag conflicts a little too common and a
little harder to resolve (since tags are always added at the end of the tag

Personally I think that these are problems that can be lived with. Yet, for
a tool as elegant and polished as mercurial they feel a little out of place.

If I could design a different tag system for mercurial (which I can't do but
hey, one can always dream! :-) ) I would put the tag information into a sort
of "subrepository". The “tag subrepo” would contain a file per tag and its
contents could be the SHA1 of the revision it points to. Adding a tag would
imply adding a new file to the tag repo and removing it would be removing
the corresponding file. Moving a tag would imply changing the contents of
the corresponding tag file. Tag conflicts would be resolved with the regular
mercurial merge machinery but conflicts would only happen when two users
changed the same tag (which makes sense) and they would never happen if two
users added a new tag, for instance (as it happens today). Mercurial would
make sure to keep this "tag subrepository" in line with the main repository
(for example if revisions where stripped it would take care to remove any
corresponding tag revisions). Finally changes to the repository revision
would not result in new visible commits on the main mercurial repository.

I think that this would solve most of the drawbacks I mentioned above while
keeping most of the features on the current implementation (I had to relax
the "in history" requirement and make it "have history" but I personally
think that is a good thing!). For example it would be easy to navigate back
in tag history (since the tag history would be just another mercurial repo
and all mercurial commands would work with it!).

I don’t claim that this solution would be perfect and I know that this
design would have its own set of issues that would need to be addressed
(e.g. how to treat branchy tag history?, etc). What I say is that there may
be alternatives to the current design which cover the basic requirements of
a good tag system.

Perhaps on a more realistic note, there may be solutions that would not
require a full redesign of the tag system as I just described. Probably
there could be some changes to the UI of the tag system that would go a long
way into improving the tag feature (e.g. “filter” the tag commits from the
graph log by default) or alternatively history could be added to the
bookmarks and then we'd get something that may work better for some users.

Anyway, please understand that my goal with this email is not to tell you
how tags should work (it is your version control system not mine!) but to
show you that some users see (perhaps mistakenly) more downsides than the
ones you mention on the wiki page. I really like mercurial, I am a big
proponent of it and I have the uttermost respect for your work so I would
hate it if you saw this as anything other than constructive criticism.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the Mercurial-devel mailing list