[ECOS] Replacing CVS - decision time: part 2

Jonathan Larmour jifl@jifvik.org
Thu Apr 29 15:01:00 GMT 2010

On 29/04/10 14:25, Bjørn Forsman wrote:
> Hi,
> 2010/4/28 Alex Schuilenburg <alexs@ecoscentric.com>:
>> On 2010-04-28 20:26, Bjørn Forsman wrote:
>>> [,,,]
>>> Git may be worse than hg on Windows, but IMHO git has better branching
>>> and tagging.
>> Could you please explain why you think git has better branching and tagging?
> This below is what I *think* is correct, based on my current knowledge. It
> may very well be wrong. If so, maybe someone will enlighten me?
> hg branching (skipping unnamed branches and entire repo forks/clones):
> * either bookmark branches (local branch)
> * or named branches (global branch)
> A hg bookmark is a lightweight branch that can only be used locally. It
> cannot be pushed to another repo. A named branch can be pushed to another
> repo. So when using hg one would have to choose branch type at branch
> creation time. With git you create branches and later choose to push them
> if you want to.

A branch is just a pointer to a revision head. So if you have an hg
lightweight branch (bookmark) and you want to be able to push it, all you
should need to do is set the branch based on the bookmark. You won't have
the advantage of having the earlier changes associated with that bookmark
marked in the metadata as associated with the new branch up to that point,
but having branches in metadata isn't something git gives you at any point
anyway, so hg is still better off than git in this respect.

> You can also push specific branches, not just all at
> once like hg does.

hg push -b <branch>

> You can also rename git branches. Hg named branches are stored as
> metadata in changesets which makes it impossible to rename them.
> Named branches cannot be deleted either, only hidden.

This is for the excellent principle that named branches are first class
revision-controlled objects and history should not be mutable. You should
not be able to easily change history in a version control system. If
you're using named branches, that's presumably because you want to be able
to push them, in which case they should be under version control just as
much as anything else.

That said, it is evidently possible to do so if you jump through some hoops:
but really marking the old branch inactive (the first option) would be the
best option. If you don't want to see inactive branches by default in the
output of 'hg branches' you can add this to ~/.hgrc:

branches = -a

> About tagging:
> hg supports local and global tags. local tags cannot be transferred to
> other repos. global tags can be pushed to other repos and are stored in a
> .hgtags file, versioned as any other file.
> This means:
> * When tagging changesetN, changesetN+1 is the one that has the newly
>   created tag included in .hgtags. A bit confusing?

I agree it seems unexpected, but makes sense once you understand it
(although I admit that that sort of argument is something I've mentioned
many times over as a problem with git). All you have to remember is not to
look at .hgtags to see the tags - use 'hg tags' which is there for exactly
that purpose.

> * hg must scan all versions of .hgtags in all branches to find its tags

Yes - this would take a trivial amount of time surely? I would hope a
well-managed repository will not have many hundreds of active branches
('hg tags' does not look at inactive branches).

> * *all* tags in .hgtags will be transferred to other repos upon push

NB hg has local tags, using 'hg tag -l'. I believe you know that, but I
realise I didn't note that in my first comparison email.

Again the reason tags in .hgtags are transferred is because that's the
distinctive purpose of those sort of tags, rather than local tags. When
people clone the repo, they should get the tags people want to come with
it as well. It is of course trivial to create a first class tag from a
local tag.

> git allows pushing specific tags, I don't have to choose up front whether
> this new tag is to be global or not. I create it and later decide if I want
> to push it. This seems more flexible to me. git supports annotated tags and
> simple tags, but both seems to be able to be selectively pushed to other
> repos.

In hg, you would create local tags, and then can choose to make them
properly version controlled tags in .hgtags.

If you forget until you're pushing, then you can always retag as a
lightweight tag and delete the old tag, before you push so upstream never
sees it in practice (especially if using mercurial queues).

> I found [1] very helpful in understanding more about hg branching. It also
> compares hg branching to git. And [2] is great for comparing hg vs. git
> consepts. It is easy to read.

I've already looked at those, although [1] isn't entirely complete (or is
partially obsolete).

> BTW, about two years ago I was in the process of deciding between git and
> hg myself. It was a very close call, but I choose hg because it had better
> Windows support (at least at that time) and was written in Python. However,
> nearly all projects I worked with after that point was using git, so I
> became a git user. I love the way git completely changed the way I think
> about and work with a SCM system. But I guess hg users feel just the same
> way :-)

I suspect there's a lot in common to any DVCS. As has been said, the
switch to any sort of DVCS will be a huge step forward. Albeit, in either
case, also requiring a step change from eCos users in understanding DVCS
concepts - what's been under debate is how much for hg vs. git; but both
involve some amount of learning curve.

Given hg-git, either way round, no-one will be that disenfranchised.


> [1]: http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/#comparison-to-git
> [2]: http://mercurial.selenic.com/wiki/GitConcepts

--["No sense being pessimistic, it wouldn't work anyway"]-- Opinions==mine

Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

More information about the Ecos-discuss mailing list