Git and Mercurial branching
lucumr.pocoo.org
lucumr.pocoo.org
A repository can have more than root. For instance, I have a repository that was formed from merging two separate repositories. From a code history point of view, the two repositories are unrelated, so in the merged repository each has its own root.
I've also used it to greenfield some ideas in the same project. Its a bit of a hack to create one, though:
git symbolic-ref HEAD refs/heads/newbranch
rm .git/index
git clean -fdx
<do work>
git add your files
git commit -m 'Initial commit'
(From http://book.git-scm.com/5_creating_new_empty_branches.html)Modern versions of git let you do this instead:
git checkout --orphan new-branchIt's not likely to change though. And here's the dice:
If you want something that "just works" and is awesome from the command line Mercurial is your best friend. If you may be facing borderline case that will wrap you in tape, Git is a better option.
With whatever git-hg bridges are available you can probably still use hg if you really like it. Could be wrong on that but iirc they exist.
There are some reasonable means of local git sharing, by the by: the old gitjour project was fun and more recently there's gitosis and gitolite. You could also leverage Dropbox or similar, or actually work with individual repositories.
I could be wrong.
Ya, I'm a little bruised over the flames that ensued during the transition but I think we're better off after having bitten the bullet. The biggest problem was always close-minded people, it was never the technology.
* the HEAD^2~3 syntax is so obscure that I can't believe anyone actually uses it; I always give up and get a commit name from the log instead
* it will cheerfully give you a branch named refs/heads/R/B having no relationship with refs/remotes/R/B with no warnings (I have even seen peers create and push refs/heads/refs/heads/R/B by mistake)
* the index should be a hidden implementation detail, with partial commits done instead via "git stash" so it's at least possible to test them (the index is also what caused "git checkout" and "git reset" to become bizarre grab bags of mutually exclusive actions)
Well, hg is doing the same.
The pager and editor are configurable, of course. I have it set up to use emacsclient on Windows.
And I think any tool's user interface is fair game for criticism. (Though other than the infamous "How do you delete a remote branch?" issue, I like git's user interface just fine.)
The only thing I'm aware of that Git can do that Mercurial can't, branching-wise, is pushing deletes, which messes up everyone else's pulls anyway.
There's also the whole index/staging area thing that I use everyday in git. That said, I think they're both alright. I think schacon summed it up pretty well in his talk at pycon:
I'm quite happy using the hg-git plugin (by the GitHub folks) which allows you to use Mercurial to interact with GitHub: http://hg-git.github.com/
hg also requires extensions to do many things that git does out of the box (like the equivalent of git stash, which I also use often). I saw very little reason to prefer hg for the brief time I experimented with it.
The tip thing mentioned by Armin is a big UI wart when using "intree" branches, by which I mean any branching scheme not based on cloning. It is also pretty difficult to name branches in the various commands - as far as I know, you cannot easily diff between two names branches, for example.
Nevertheless, I miss index much more than git's branching when using hg at work.
The branch model doesn't compete because branches are ingrained, as this article discusses; the changeset always carries the branch name with it. Branches are also ingrained as "long-lived branches" and instead of the mere application of a label to divergent changesets, these branches appear tightly coupled and are meant to be merged and/or closed in the way hg expects. You can only get git-like flexibility such as cherry-picking by making another clone or by installing a variety of extensions.
See http://mercurial.selenic.com/wiki/GitConcepts#Branch_model , which explains that git-like branches don't have a direct equivalent in Mercurial unless you use the BookmarkExtension to apply names to a changeset; otherwise, you must use hg heads, which doesn't work in quite the same way, at least during my brief experience.
On top of this, git is usually faster and usually has much smaller repositories (see https://git.wiki.kernel.org/index.php/GitBenchmarks), so I don't see much reason to prefer hg. git integrates fine with Windows if one installs msysgit, which includes a minimalist cygwinish environment and is not at all unreasonable.
Mercurial ships with a bunch of features ("extensions") turned off by default so that beginner users aren't confused with stuff before they're ready. Turning the bookmark extension on is as easy as putting "bookmarks=" in your ~/.hgrc file. So the bookmark branching model, which is equivalent to the git branching model and something I use every day, is a built-in part of mercurial. You just have to enable it to work that way.
The "transplant" extension (similar to cherry picking in git) also comes with mercurial and is just a one liner in a config file to enable.