Hacker News new | past | comments | ask | show | jobs | submit login
I'm going to slowly move on from Mercurial (mercurial-scm.org)
480 points by jordigh on Jan 25, 2016 | hide | past | favorite | 162 comments



10+ years is a long time to steward a project. Most projects don't even live that long!

Transitioning away after 10+ years is a sign of several positive things:

* Creating a successful project that lasts 10+ years

* Having the perseverance, patience, and willpower to guide that project for its lifetime

* Creating a healthy community whom you are able to transition day-to-day responsibility of that project to

Matt has accomplished something that most of us never will. I'm envious of what he has accomplished and that he is able to walk away from a healthy and successful project. Truly a remarkable accomplishment.


Matt has done a great job and I wish hg had taken off more than it did, though it would be disingenuous to suggest it hasn't been successful.

I used hg before moving to git and always preferred the clean, single language implementation vs the scripts and general hackish nature that git offered as an alternative. As a result, it was a nice perk for a long time that hg worked much better than git on Windows.


Also the revsets, while they're relatively recent in the grand scheme of things (hg 1.6 circa 2010) I so miss these when I have to use (or even read the man page of) the garbage fire that is `git log` (templates also help)


I've actually converted a git repo to hg just to use revsets.


How much of the hg revset functionality could be implemented for git, without writing any C? Is the revset feature basically a DSL for specifying queries, and are the queries thus-specified ones that have direct analogs in git and can be done in git using git's API?


> Is the revset feature basically a DSL for specifying queries

Yes, it's a way to select sets of revisions by filtering and merging existing sets.

> and are the queries thus-specified ones that have direct analogs in git and can be done in git using git's API?

I don't think so, not all of the filter operations are available, but more importantly I don't think git supports arbitrary sets of revisions, only fairly basic relatively continuous ranges (that's the idea I get from gitrevisions(7) anyway)


What is it about these revsets that can't be achieved with a "git log --graph --decorate --all"?


Those would be accomplished with hg templates, not revsets. Revsets are kind of like gitrevisions(7), but much more powerful.

Docs:

https://selenic.com/hg/help/revsets

A complete example, which appears to have some popularity in Mozilla:

http://jordi.inversethought.com/blog/customising-mercurial-l...

edit: Sorry, the --decorate part would be with template, the --all is kind of like a revset, and the --graph part is well, --graph.


> Those would be accomplished with hg templates

Except for the --graph part which would be accomplished with --graph of course

> Revsets are kind of like gitrevisions(7), but much more powerful.

And easier to read and write too.


Usage without a PhD in git-manpage-generator, primarily.


love to have someone with a PhD in git show how to do the `hg wip` from jordigh above.


I'm worried I might have to move off of hg eventually. But just can't get over all those points .. and also TortoiseHg, for which there doesn't seem to be even remotely as good an equivalent in the git ecosystem. It's kind of frustrating. I end up cloning git projects using hg-git plugin just so I can use it to search the repo history.


This is a gutsy thing to do with a piece of software that has been part of your life for over a decade. Mad props to mpm.

Up until Blekko I had pretty much been a perforce user (both at NetApp and at Google) and git was "that weird system you had to use to check in kernel changes". Blekko used Mercurial and I had no opinion as I had no experience. But over the years using hg at work and then starting up a github account to learn git, I saw the writing on the wall. Hg was the betamax of source code management systems. Clean, elegant, reliable, and not mainstream.


For context here, and for people like me who don't follow the development of Mercurial closely enough to realize, mpm is not just some random contributor to Mercurial, but is in fact Matt Mackall, the original author of Mercurial.


Lest we forget, Mercurial was offered as the other solution to the Bitkeeper problem, as mpm was a kernel hacker at the time. It got a usable UI at version 0.1, two weeks after the git announcement. Some git users relied on cogito for another year or so, as simple things like `git-commit` still had to be manually handcrafted out of `git-commit-tree`.

I wasn't there to witness this, but I repeat it because it's actually kind of hard to dig up this history. I don't know of a single place that neatly chronicles the whole transition from bitkeeper -> git/mercurial.


> Lest we forget, Mercurial was offered as the other solution to the Bitkeeper problem, as mpm was a kernel hacker at the time. It got a usable UI at version 0.1, two weeks after the git announcement.

I remember using Mercurial very early on in its lifetime, during my first internship at IBM, because Xen used it.

Mercurial also ran on Windows far, far earlier than Git did. A few projects (notably Mozilla) selected Mercurial for that reason, because they had developers on Windows.

Unfortunately, Mercurial took longer to develop some of its infrastructure, such as a repository structure optimized for performance, fast branches without making a separate working directory for each, and history editing capabilities. Today, as far as I know, Mercurial does have all of those things (some through plugins).

> Some git users relied on cogito for another year or so, as simple things like `git-commit` still had to be manually handcrafted out of `git-commit-tree`.

Many people (myself included) also used cogito as a crutch for a while longer, until really internalizing the value of the git index, because cogito defaulted to bypassing the index. I originally saw the index as an obstacle to the commit model I'd gotten used to from subversion. Today, I find it a critical part of git's culture of making small commits with one logical change each.


A couple of technical notes:

> such as a repository structure optimized for performance

Actually, repository structure hasn't fundamentally changed (unless you count the RevlogNG change in 0.9). There have been changes so that data on disk compresses better (the generaldelta change) and there's more underway to support new features (such as narrow clones), but they generally aren't performance-related.

I note that this is a good thing: Mercurial's repository structure allows it to do things that aren't easy for Git, especially efficient random access to history (Git's structures are generally optimized for access close to HEAD and the root of the directory tree), at the expense of requiring more disk space.

The performance improvements you've seen most likely come from more/better caching or reimplementation of time-critical code.

> fast branches without making a separate working directory for each

That was always possible. Documentation (such as the Mercurial book) suggested a clone-based workflow for reasons of convenience and because that's what people were used to at the time, not because you had to do it this way.


Thank you for correcting. There is so much misinformation about mercurial out there.


> I originally saw the index as an obstacle to the commit model I'd gotten used to from subversion. Today, I find it a critical part of git's culture of making small commits with one logical change each.

How is this different from mercurial ? I know that the latter doesn't have the index, but is there any practical difference from the point of view of the user ? In Mercurial you can easily commit a subset of the files, or even a part of a file if you use the record extension.


> if you use the record extension.

It's now part of core with `hg commit -i`, although it's still experimental.


Have you used both?

You can commit a subset of changed files in most version control systems, but it isn't smart because you didn't test that state and it's relatively easy to garble files.

Not having the index is a very practical difference for users, because it means that you do not get any editable "staging" commits, only commits that will be on the permanent record.


> You can commit a subset of changed files in most version control systems, but it isn't smart because you didn't test that state and it's relatively easy to garble files.

The clean solution here is to stash/shelve the changes you don't want, then commit the ones you wanted. This works pretty much the same way in either VCS.

> Not having the index is a very practical difference for users, because it means that you do not get any editable "staging" commits, only commits that will be on the permanent record.

Use hg commit [-i], hg commit --amend [-i], and hg uncommit (with evolve) to modify the most recent commit as needed. Or, frankly, just use hg shelve [-i] to do the reverse as described above.

The Git index doesn't improve upon the situation, since you still can't test the partial commit without stashing the remaining changes first. At which point you could have just done that first.

In any event, the closest equivalent of Git's index in Mercurial is MQ, not hg commit -i and friends. The difference is that in Mercurial it's opt-in rather than opt-out.


Thanks for clarifying, my experience with Git is much more limited than with Mercurial, so it wasn't clear to me that the index is a sort of editable (or partial?) commit (of course now it looks quite obvious).

I understand the appeal of that, in fact Mercurial acquired similar capabilities during it's evolution, thanks to a number of extensions (for example histedit [1])

[1] https://www.mercurial-scm.org/wiki/HisteditExtension


But nothing in git (or any dvcs, really) is "permanent record" until you share it with others. git users are very proud of git's history editing capabilities, in fact. So no need for an index, just commit, and edit that commit if needed.


"I find [the index] a critical part of git's culture of making small commits with one logical change each."

I've never understood why the index has to be forced on everyone for every commit. Apparently it's due to a belief that everyone always just munges a bunch of changes together in their working copy in a mad coding frenzy and then later realize they need to filter and separate those changes into separate commits? That happens to me from time to time, but it's not the common case. When it does happen (since I use mercurial) I can use use tools such as commit --amend, or commit <list of filenames>, or record or crecord to filter and separate the changes in my working copy into separate commits. I believe even git has some of those same options.


> "I find [the index] a critical part of git's culture of making small commits with one logical change each."

> I've never understood why the index has to be forced on everyone for every commit.

You can generally bypass it if making a simple commit; I use "git commit -a" all the time. But every time you use tools like "git add" on individual files, or "git add -p" on parts of files, you rely on the index.

Understanding the index also helps greatly when you need to do a merge, cherry-pick, or other similar operation; you need a staging area to work in, separate from the work tree.


"Understanding the index also helps greatly when you need to do a merge, cherry-pick, or other similar operation; you need a staging area to work in, separate from the work tree."

Actually, with mercurial I don't need a staging area to work in separate from the working copy to perform merge, cherry-pick, or other similar operations. The index appears to be needless complication.


Having used both git and mercurial extensively I can guarantee you the index is not a needless complication, it is a feature sorely missed in hg.


With `hg commit --interactive` and `hg amend --interactive`, I really don't see what's the difference between a temporary commit that you keep adding stuff to and a staging area. It's all just diffs and hunks. Whether it's finalised or not is just a matter of perspective. Mercurial encodes this perspective by distinguishing draft from published commits.


In recent versions the "record" extension has been replaced by "hg commit -i". Many other commands support interactive hunk selection as well.


The index being so visible by default (as opposed to being a behind the scenes thing in most other VCS system) definitely adds some complexity. I need to sit down someday and figure out exactly how the git index fits into everything, because that is the sticking point on the one thing I used to do automatically in Mercurial that I have not figured out how to do in git other than manually.

I had this hook in Mercurial on OS X:

pre-commit = mdfind -0 -onlyin . "kMDItemContentTypeTree = 'com.apple.package'" | xargs -0 hg addremove

For those not familiar with Mercurial, "hg addremove dir ..." adds any files from the specified directory that are not already in the repository, and removes from the repository any files that were from the repository that have been deleted from the specified directory.

For those not familiar with OS X, that mdfind command is finding directories in or under the current directory that have the kMDItemContentTypeTree list in the metadata includes com.apple.package. These are directories that are logically treated as if they are single files.

Suppose I am keeping a TODO list named "TODO" with my project, and I'm using OmniOutliner to organize it. The TODO list will be in a directory named "TODO.oo3". OmniOutliner will keep an XML file in that directory that has most of my TODO list. If all my TODO list consists of is formatted text, that will be all that is in there, and everything is simple. As far as any DVCS goes, I can just treat that XML file as my entire TODO list. It will be no different than a code file, except that I edit it with OmniOutliner instead of vim or TextMate.

Now suppose I add more than just simple formatted text to my TODO. OmniOutliner allows adding files as attachments. They get copied into the TODO.oo3 tree. It also allows recording audio notes, which get stored as files in TODO.oo3. Deleting an attachment in OmniOutliner will delete the file from TODO.oo3.

So what my Mercurial pre-commit hook is doing is finding any files that have been added or removed in directories like my TODO.oo3, and adds any newly added files and removes any deleted files. Files that have just had contents changed will be taken care of by the normal operation of Mercurial.

With git, I'm not sure how to handle this. There are two main issues.

1. Where to handle this. I think the adding and removing of files from the magic directories need to occur on commands that modify the index. In particular, on "add -u". However, I don't see any hook for this. Git's pre-commit hook is, unsurprisingly, for commits, which is too late.

2. Dealing with fancy things like stashes. In general going over ever git command that affect the index and making sure that magic directories are being handled right.

It would be ugly, but I'm starting to suspect it might require putting a wrapper around the git command itself, which is kind of ugly.

Another possibility is a pre-commit hook that just checks to see if any magic directories have added or removed files, and if so aborts the commit and alerts the user that they need to "git add" or "git rm" those files or add --no-verify if they want to commit anyway. It wouldn't be as clean as it was in Mercurial, but it would at least be an improvement over relying on noticing in the "git status" I almost always do before committing that I've got some add/removes in a magic directory that need to be taken care of first.


I don't understand why you need this as a hook. In recent versions of git, "git add" on a directory updates the index to match the entire directory, with modifications, additions, and deletions.


Suppose the project looks like this when clean:

  README.txt
  src/
  include/
  doc/
  TODO.oo3
In the midst of development, I may end up with files in some of these directories that are not supposed to go into the repository. There may be output files from test runs that I'm keeping around temporarily while I debug, notes (that will be incorporated into commit messages which is why the notes files do not belong in the repository), short-lived alternative versions of some of the source or include files, and so on.

I don't want to "git add" on the project directory, or any of the subdirectories other than TODO.oo3 because I don't want to pick up those files. For everywhere except TODO.oo3, "git add -u" is what I (think I) want. It's only with TODO.oo3 that I want "git add" instead of (or in addition to) "git add -u".


That's what the .gitignore file is for, or if you don't want/need to change that between other users of the repositor, the .git/info/excludes file.


Deletions feel a bit odd.

I mostly use "git add -p" and it misses new files, which doesn't feel right either :\


> Mercurial also ran on Windows far, far earlier than Git did. A few projects (notably Mozilla) selected Mercurial for that reason, because they had developers on Windows.

Ouch, yet another way in which running on Windows can lead to poor technical decisions.

In my own case, I really preferred hg's command congruence to SVN; git's deceptive similarity took a long time to get over.

> I originally saw the index as an obstacle to the commit model I'd gotten used to from subversion. Today, I find it a critical part of git's culture of making small commits with one logical change each.

Same here, on both counts. I'd never go back, now, but it did take time to understand the benefits.


> Ouch, yet another way in which running on Windows can lead to poor technical decisions.

Are you implying that choosing hg was a poor technical decision?

Or are you just making the general observation that if you include non-technical requirements when choosing a tool (and if we accept that running on a specific set of platforms is not a technical requirement...) then you might not end up with the choice that would have been best if all the requirements were purely technical?

If the former, then you should elaborate. As far as I was able to determine when I evaluated both hg and git is that they are essentially equivalent technically. Git's default interface makes some things visible that hg keeps behind the scenes, but these are all a quick hg extension installation away for those who want them.


> As far as I was able to determine when I evaluated both hg and git is that they are essentially equivalent technically.

Today, yes. Significant work went into getting Mercurial's internals up to parity with Git's, and conversely into getting Git's UI up to parity with Mercurial's.


Respectfully, Git still has a long way to go before it achieves parity with Mercurial, or even its state of the art from, say, 2010.

Don't discount the effect that familiarity with a tool or process can have on your perception of it. The most succinct explanation of this effect that I know comes from the title of a post on the Light Table blog called, "Pain We Forgot".

Coming from a Mozilla-influenced, pre-GitHub-explosion background, I'm one of those people always favored Mercurial but used both out of necessity. Mostly that meant using hg for my own stuff that is most likely never to see the light of day and git for almost everything else. But I also ended up calling it quits on Mercurial and pulled the trigger on git-for-everything last week.

So, having just written (what should be a completely unnecessary) tool to dump out stats about files' line ending conventions, again, I'll say that Git has a long way to go.

(And before you ask, yes the problem manifests itself using the latest version of Git, and there's nothing exotic or wacky to my workflow, nor am I witnessing the effect of interplay with other tools of dubious quality. This is an outright case of Git's tendency to drop the ball and then gesture in the vague direction of a poorly documented non-fix that cuts orthogonally to the problem it's supposed to be solving.)


Mercurial has some warts of it own. Common case of working on something, then wanting to update the repository in the midst of it to get something from a co-worker isn't handled exactly stellar.

So you can shelve. When you have enabled the extension.

If I'm not mistaken, even CVS handled this better.


> hg clone . ../CloneForCoworkerInvestigation

This is way, way better than CVS. Some people complain about how this doesn't work in place, like git or shelve, but I prefer I don't have to change anything in my main repo, like regenerate IDE files, dependency caches etc.

In any event, I've always like how this worked.


Can you explain what's the relation between git or mercurial and files' line ending convention and what problem there is? I have used both and never met this kind of problem


It's not Mercurial and Git line ending conventions, it's that Windows uses CRLF and Unix uses LF, and Git's approach to addressing this is pretty far short of good.

(Another pre-emptive response: yes I'm aware of both core.autocrlf and "text eol", but those are exactly the sort of sideways-cutting non-fixes that I'm talking about.)


What's the behavior you expect, compared to the behavior that you get with git's configuration options?


I've tried to write and rewrite this comment, but it oozes disdain every time. So here's my best:

I expect that if a file uses CRLF everywhere, `git merge` will not leave it in a state with mixed line endings after inserting conflict resolution markers that end in LF instead of CRLF.

This shouldn't require a configuration option, but if it does, fine. However, Git doesn't even seem to have this.

What it does have are 'autocrlf' and 'eol' and 'text' options/attributes. For anyone who mentions those, I'm going to ask that you be familiar with not just what those actually control, but also how they're documented in the git man pages and in the book from git-scm.org—the entire premise was a discussion about Git's user-facing parts. By either source, those options control line normalization (i.e., implicit automatic conversion), which is not what I'm talking about. And the documentation for those is sick enough that even if they were the things to look to in order to configure this, then the idea that Git's UI is on par with Mercurial nowadays would still be wrong.

EDIT: To clarify, the desired approach for this is, "Use whatever line endings the file is already using". Git's approach to this is, "Standardize on either LF or CRLF, and at your discretion enable what amounts to some glorified git hooks to ensure that policy is followed, through the use of some obtusely documented configuration options. Make sure to work around any problems with that (e.g., when it's corrupting files that should have never been normalized) by applying another liberal layer."


"Don't standardise on line endings" is not a good idea. The whole CRLF thing is already completely stupid. Why are you trying to justify a dumb design decision, and claim that trying to standardise the way source code line endings are stored is a bad thing.

Not to mention that you can't send CRLF in emails. So how are you going to email patches.


It's worth pointing out that part of the reason that Mozilla selected Mercurial over Git was that the Mercurial developers were more willing to help fix issues that Mozilla had identified than Git was, with Windows support being the most important point.

In a way, actually, that still seems to be the case. The Mercurial community seems to be working hard on making enormous monolithic repositories much more performant and realiable, whereas a lot of Git community seems to prefer to merely respond "YOU'RE USING IT WRONG" to these issues (although I suspect the developers themselves are also working on some of the issues; it's just that I see the community at large as much more visible).

So there's definitely a sense to me that Mercurial is the better VCS because it will quietly support whatever development model you want to use, whereas Git tries to force you to use the One True Model™--and I'm firmly in the camp that development tools should support developers' habits, not force them.


> So there's definitely a sense to me that Mercurial is the better VCS because it will quietly support whatever development model you want to use, whereas Git tries to force you to use the One True Model™

Considering the number of tools based on the Git data model to do completely unrelated things (I'm thinking about e.g. bup or git-annex). I wouldn't say that's Git imposes you a One True Model. Also, Git doesn't restrict you to an arbitrary number of parents on a commit ;).

BTW,

> The Mercurial community seems to be working hard on making enormous monolithic repositories much more performant and realiable

The irony is that to do so, Mercurial had to bend its data model, adding (backwards incompatible) support for per-directory manifests (which sound a lot like trees in Git, except the part where manifests have history attached to them, where Git only has history attached to commits).


> So there's definitely a sense to me that Mercurial is the better VCS because it will quietly support whatever development model you want to use, whereas Git tries to force you to use the One True Model™

Wow, I can't disagree with that notion more. I've been on many projects that use git and practically every one used git in different ways. I've never felt that git was trying to force a particular workflow on me. Git's greatest strength, to me, has always been its toolbox nature—you can make it do whatever you like (want to comb through your entire repo and change someone's email address, or backdate an entire branch? No problem!).


Hg worked on Windows from the beginning because it was written in Python. Python best practices make it pretty easy to avoid Windows-specific quirks (use os.path.join for directory munging, and don't use hard links). Git was a bit of C at first, which got wrapped in successive levels of bash and Perl, neither of which were particularly well supported on Windows 16 years ago.


> Git was a bit of C at first, which got wrapped in successive levels of bash and Perl, neither of which were particularly well supported on Windows 16 years ago.

Not that this has changed much, the CLI git has been renamed to "git on windows" but fundamentally you're still installing msys (2) to run git.

That issue is greatly mitigated by the existence of libgit2 though, it builds natively on windows (and just about everything else) so windows git (GUI) clients need not depend on CLI git.


> but fundamentally you're still installing msys (2) to run git.

You're installing msys to run git because (I guess) it was considered the git CLI would be useless without a decent shell. Would you see yourself use Git or Mercurial in cmd?

Git itself in Git for Windows, afaik, is not actually an msys program, and uses native win32 APIs.


Ever heard of a thing called powershell?


Is that like Bash for Kids?


Maybe that's a poor description of a tool with full access to the entire class hierarchy of the .NET Framework. You could write a GUI program in it with WPF, although most people would take it as a kindness if you didn't.


> Ouch, yet another way in which running on Windows can lead to poor technical decisions.

I didn't see any indication in the parent comment (or in general, really) that Windows support was the cause of Mercurial's difficulty in implementing those features.


He means that Mozilla devs running Windows led them to adopt Mercurial (which was, in his opinion, a "poor technical decision"). Not that Mercurial made poor technical decisions as a result of supporting Windows.


> Ouch, yet another way in which running on Windows can lead to poor technical decisions.

I've never heard from anyone that choosing/using Mercurial was a poor decision. Are you biased?


Well arguably the long-term result for Mozilla is that we have ended up having to support two version control systems for everything because there has been less resistance to that than trying to force people to use mercurial for everything (for the projects that were already in mercurial people wrote git bridges, and for new projects people tended to start them on GitHub). I strongly doubt that there would have been the same problem if we had used git from the start. I suspect this is a net negative, even if you believe the rhetoric that mercurial (or future-mercurial) has technical advantages in some areas.

Edit: to be clear, the kind of "everything" I have in mind is the code review system which now has to support two version control tools. Indeed if we'd used git from the start there might well have been an off-the-shelf code review tool we could have used without putting multiple man years of effort into customisations.


> I've never heard from anyone that choosing/using Mercurial was a poor decision.

I liked hg too, but as the passage of time has indicated choosing it for one's project would have been a mistake, as git has effectively won.


You haven't mentioned why you think Git won. If by "won", you mean "is more popular", then yes, it won. But that criteria alone doesn't make a decision bad. When changing gives you no clear advantage, why change to something more popular?


Isn't that akin to arguing that choosing to distribute your movies only on Betamax is not a bad decision?


won what?


It has won GitHub, that's mostly it.

Separately, GitHub has won the "place where you share you project code" prize that used to belong to sourceforge.


I do the same thing with mercurial's "hg commit -i" interactive interface. There's also a very nice curses interface for interactive hunk selection which is currently behind an experimental config flag but is shipped with the core application.


> Ouch, yet another way in which running on Windows can lead to poor technical decisions.

That's quite dismissive of Windows...


There was no version control on the transition? :)


Why is context needed when the first sentence is "Here it is 2016 and it's been almost 11 years since I started Mercurial." ?


I don't know the GP intention, but for people who first look through comments here, before investing time in reading the piece this is a crucial information. I wouldn't read the article if not for this post.


I thought the same thing. Then I thought about some of the subthreads on the Sun2 bootloader article. Then I recalibrated my cynicism.


Thanks for the clarification. Initially, I was thinking mpm was another package manager.


I'm really surprised by the "git won" mentality that manifests in any discussion of mercurial as of late. It makes no sense. We don't decare "winners" with other tools we use. Do we?

Why are we all playing with new programming languages when C won? Or maybe C++ won? Or Java? Did emacs or vim win? Speaking of text, did ASCII win? Which code review tool won? How about continuous integration tools? or build tools? I mean, make won, right?

None of us just pick the most widely used tool or programming language and say, "there can only be one" and then stop trying new things. Why are we doing this with version control?


Code collaboration tools have a strong network effect due to them being ultimately social tools, and we expect categories affected by the network effect to have winner/losers mechanics. Of course, they don't actually have to, but it's a common expectation and a common outcome.

For equivalents to "code collaboration tools", instead of "programming languages", "text editors" and "build tools", try "social networks" (Facebook won, MySpace lost), "network protocols" (HTTP won, FTP and Gopher lost) or "spoken languages" (English won)


It seems to me that programming languages have far stronger network effects than any other example you or I are throwing out. If one project uses git and another mercurial and they want to work together, there are ways (hg-git, plain old patches). Try incorporating some java code in a ruby project, however. No possible way that is going to fly. Yet, we (at least the hacker news crowd) haven't declared any language as "winner". I really hope version control does not stagnate at git.


>Try incorporating some java code in a ruby project, however. No possible way that is going to fly.

I don't think this example is convincing. There are too many languages to expect arbitrary pairings to combine well. (Not to mention the fact that googling "java ruby" returns JRuby, which apparently lets you do just what you describe.)

I do agree with your last point: Even when we look at similar languages, like Python and Ruby, we don't declare one a winner, generally.


> English won

English did not won.

It might be widely spoken in the 21st century, but so were Greek, Egyptian, Latin, French, Portuguese and Spanish once upon a time.

I might be writing this in English now, but saying it won implies no change in common language will ever happen again.

Given the history of mankind and some of the countries I had the pleasure to visit on my life so far, I doubt it.

Specially since most of the people I know, do happen to speak three foreign languages on average.


> English did not won.

Apparently not.


Well, yes. Everything else I've mentioned is also dependant on cultural contexts that may vary dramatically over time. I surely hope Facebook hasn't won forever.

For what it's worth, I'm not a native English speaker.


While emacs and vim are still duking it out people are CONSTANTLY defaulting to or arguing the case for this or that because "the right tool for the job" 90% of the time means "the tool the community supports for my problem"


It's the old diversity vs. centralization/standardization argument.

Too many programming languages leads to too much fragmentation, not enough programmers well-versed in the languages, etc. Most times, we pick a language today based not on how optimized the language is for the problem, but on the availability of programmers who know how to use it. Haskell might be great, but if you're a business trying to build something, you'll have a much easier time hiring experienced C++ programmers. However, different languages have different strengths and weaknesses and applicability to certain problems, so you don't want to just standardize on one either. You probably wouldn't use Haskell on a project that is a good fit for C and needs low-level access to hardware.

It's not much different with version control, except that fundamentally all such systems aim to solve the exact same problem: managing and keeping track of source-code changes in a project. They go about it differently (distributed vs. non-distributed is a big factor), and offer different features, but they all want to do the exact same thing. And here again, programmer familiarity is an important factor. Working with git is not even remotely like working with ClearCase, for example. So people tend to gravitate towards popular choices, which was SVN before, and now has become git. So if you pick Hg for your project, you're going to probably have to spend more time getting contributors up to speed on it than if you picked something more popular like git.

One big factor in these debates is: how easy is it to change from one to another? Another is: how easy is it for individuals to pick their favorite and use that regardless of what others use? For programming languages and version control, you can't easily change between them, and everyone needs to be using the same one on a particular project (unless you do something where one part is written in one language and linked to another part in a different language through bindings, but this doesn't apply to version control). For editors, this isn't the case usually: any programmer can use whatever they want for the most part, and it has no effect on what others use.

As for your other examples, build tools are the same as version control: everyone has to use the same one on a project. You can't have one person build with make/autotools and another with scons and another with CMake. This doesn't mean you can't change it later if there's a compelling reason, but there's inertia to overcome once a project is built a certain way. ASCII did win, that should be obvious. Even Unicode is largely based on ASCII with utf-8.


> but on the availability of programmers who know how to use it

The sheer prevalence of git "tutorials" would suggest that most programmers don't actually know how to use it.

Relevant xkcd: https://xkcd.com/1597/


This comic is shockingly spot on for me and my group. We all know the basics, but only at a "type this to get this result" level. The moment something ridiculous needs to be done like a rebase, I get called, and without fail need to have a few stack overflow tabs open to figure it out.

Git's a phenomenal system, but sometimes part of me thinks it does require a PhD to fully grok.


I think that comic also accurately describes the problem leading to that as well: it dismisses any explanation of Git's underlying mechanics and repository structure as ignorable rambling prefacing the command to do what you want.

It took me a while to learn git, and the explanations I went through involved the underlying structure of the repository. They seemed excessively complicated at the time, compared to memorizing commands for cvs and svn. However, now that I understand that underlying structure, every new git tool or function just provides additional means of transforming the repository structure I have into the repository structure I want.

You don't stop learning programming once you've memorized a rote sequence of steps to run a half-dozen algorithms on a hash table. And you don't stop learning git once you've memorized a rote sequence of steps to run a half-dozen algorithms on a git repository structure.

I don't mean that to suggest that git has no room to improve in its UI; far from it. But that particular comic seems to excuse a self-perpetuating problem of not wanting to learn something useful, and instead relying on people who did learn that useful thing while simultaneously belittling them for knowing it.


One of my problems with git is that I don't want to have to understand anything and source code control. It isn't something I am interested in. All I want to do is merge from upstream and commit my changes. Mercurial lets me do this without needing to understand much, whereas git makes me understand all sorts of stuff just to get this basic job done. Why should I have to understand the structure of the repository to merge something? Seems like a classic case of the UI exposing the implementation details. I get that if you are managing a large project you might want all of Git's features, but since that's not me, I just do what the XKCD comic suggests.


Learning git internals can be useful but I'm really sad that its also required. If git's UI weren't so leaky a beginner would be able to go very far with just the "graph theory model" as guidance, which is much simpler to understand.


That's the problem with git. It's extremely powerful, but requires a lot of knowledge to use well. It's a lot like a F1 racing car: the performance of such a car is phenomenal compared to a regular car, but the driver has to really know what he's doing to operate the thing at all. Just google for "F1 steering wheel" to see the controls they have to operate.

Honestly I think it's an accident of history that git became so popular for software development outside of Linux kernel development.

It doesn't help that git is really a good example of evolution, as seen in the UI. It would have been better if it had been architected more thoroughly before releasing for general use.


> The moment something ridiculous needs to be done like a rebase

Rebase, "ridiculous"? Uh oh. It's a very valuable tool and it's a quite simple concept. I agree that the user interface could be less confusing, though.

Git is just a malleable graph made out of patches. The concept is really simple (even simpler than hg). The UI could be better but the manpages are rather good at explaining how it works.


Just because something is conceptually simple does not make it simple to use. Similarly pointers are simple. They are things (usually variables) used to point to other things in memory by storing the memory address of the target. They are simple. And yet their usage is very complex.


Ridiculous, as in, a case where we actually need it is rare enough that by the time the need arises, everyone's forgotten how it works.

We're not in a shop where one-off merge commits are a thing anyone really cares about, so rebases usually mean things like "Somebody used the wrong committer name" or "Somebody did a branch merge incorrectly and now the history makes no sense".

The git manpages suffer from the same problem as the sudo manpage(1). I want to know how to do "X" and why it works that way, and perhaps see examples explained.

(1): The, IMO, canonical example for awful documentation design - why does a user credential switching program open with a primer to EBNF when it's hardly necessary?


> The git manpages suffer from the same problem as the sudo manpage(1). I want to know how to do "X" and why it works that way, and perhaps see examples explained.

Perhaps that's might apply to some git manpages, but man git-rebase in particular is really good. It has exactly what you want, example situations, the command lines to achieve them, complete with pretty ascii art diagrams.

It could still be improved, though. There might be some "oops I screwed up, what next" situations too. I think `git rebase --abort` works most of the time these days but it wasn't always so.


That's actually quite interesting - I remember similar comments (Phd required, or Phds aren't able to understand it) cropping up in discussions of the GNU autotools toolchain. (With a fair bit if justification, in my own experience, although I understand the results tended to be better for those who were shell script gurus...)


Autotools is actually quite simple to understand.

If your install needs autotools, your install is broken. :)

The number of projects that need autotools in this day and age is vanishingly small. A small script (bash/python/perl/ruby) that checks exactly what you need and then runs make instead of copying 15 years of cargo cult m4 is far superior to autotools.


It gets much worse once you step out of the open source software and start up communities.


This is exactly what keeps me on Mercurial.

I can teach Mercurial to CEO's, artists, students, etc. and some of them will be better than me on it with a week or two. All of them "get it" and it's "low friction"--they can commit and forget about it. People who need it can handle merging and the rest can ignore it. People who need branches can use it and the rest can ignore it. etc.

git doesn't allow this. git is all or nothing. Either you inload the whole mental model, or you WILL wedge your repository somehow when you execute a command that doesn't quite do what you think it does. At that point, you will spend 4 hours combing Stack Overflow for the answer. Or you will just pull up the filesystem copy of the git repo you made before executing any command other than "git pull" or "git clone".


I was a Mercurial crew member for a few years (2008 to I don't know) and was very happy to be able to learn from Matt in his role as BDFL. His principled stance against layering violations and his policy to require really small commits still influence my coding every day. I hope he finds something new to give him satisfaction/joy!


+1, working with Matt was also extremely formative, I learned a lot of best practices during those years.


What do you mean by "layering violations"?


I loved Mercurial, but just like with Wirth languages, I seem be on the wrong side of the mainstream flow.

Thanks for Mercurial!


I did a project on integrating Mercurial with Mongo before, and I have to say being a Python developer I didn't have too much difficulty in figuring the right API, although the documentation is not so great. The code itself uses a lot of abbreviations which you have to really be patient to get familiar. The Mercurial model [1] is a pleasant read for a couple train ride (read it a few times I encourage). Others have done amazing things with hg too, like making hg available in Javascript (now an abandon project).

Mercurial is actually very easy to use. However, it didn't have the exact lightweight concept of git branch until they implemented bookmark a few years ago. I don't remember the limitation of bookmarks now it has been a few years since I used Mercurial...

I too thank Matt and core developers working on Mercurial. One thing I feel Matt and developers need to address is hosting hg on PyPI infrastructure instead of redirecting to their own server. From time to time the server wouldn't deliver anything and it was frustrating to see our builds fail (of course some say you should have cached the build and not hitting Mercurial server every day).

[1]: https://www.mercurial-scm.org/wiki/Presentations?action=Atta...


We've been uploading to PyPI as part of our release process for quite some time, and our own server is hosted on public infra now instead of on a privately managed machine. :)


Thanks for all your contributions over these years.


Thanks for starting Mercurial.


hg could be 20% better than git. For the sake of the arugment, let's say it is.

git's network effects mean hg needs to be 1000% better than git to replace it (much like git replaced svn, svn replaced cvs, and cvs replaced rcs).


TBH, I prefer Hg regardless. I only use git when forced to to interact with a project on GitHub. As for replacement, I don't think anyone wants that. Two widely used open source DVCSes is a great thing.


Have you ever tried out hg-git? It lets you interact with github repos using mercurial.


I've tried it during the transition from Google Code. It works well enough but it didn't handle orphaned branches (as used by Github pages) well and I had to provide credentials twice for every push for some reason.


i've never tried. but i usually refrain from putting more technology than needed to reach my end goals.

less is more, in this case. :P


On the other hand, I find git's command line interface very confusing so less trips to the man pages is also more :P


I have. TBH it was more trouble than it was worth, and I had some trouble with the initial setup. It was a couple years ago now though, so it's possibly gotten better.


There are tons of companies using mercurial including some of the biggest ones. It's not really accurate to imply that Git won and Mercurial is dead.


I consider the CPython switch from Mercurial to git the final declaration of victory.

I still have to understand how CPython could miss the symbolic meaning of this decision.


"I consider the CPython switch from Mercurial to git the final declaration of victory."

Really I think it was bitbucket's total sidelining of hg in favour of git. hg features break regularly on bitbucket and today if you visit bitbucket's home page you're greeted with "Bitbucket is the Git solution for professional teams"


More Guido and a couple of vocal people than CPython. I truly hope the switch wasn't the reason for Mackall to quit.


Nope. mpm has been wanting to move on for a while, it's only recently that he's published plans more publicly.


I'm not sure. I have the impression some larger organizations that are moving or using monolithic repos are now aligning more strongly towards hg, because it's easier to extend and optimize than Git.

If you look at the outside contributions that both projects get, this is pretty obvious. Hg is getting big changes from Facebook, Google, Mozilla, ...

Maybe the answer to the argument that a paradigm change is needed to unsettle git is simply "monolithic repos".


imho for CPython, the decision was more of the network effect that Github have rather than picking any particular tool or language. I Know Gitlab was also taken into account, and RhodeCode as well which supported Mercurial and itself is also written in Python. I think in there days for large OS projects it's more important to have more potentials contributors rather than sticking to only Python projects. Just my 2c.


It's probably more accurate to say they switched to github, but yes.


Yes, For instance, Java.


Facebook is another example :)


Winning and 'being dead' are two things that mean different things to different people.

Git has at least an order of magnitude more people use it, and there is a significant and growing ecosystem around it that mercurial does not have.

Mercurial is not going to 'die' until the developers abandon it; you can still use and install it. Hell, even cvs isn't 'dead', and the last stable release was in 2008.

Mercurial will also continue to 'not be dead' for the foreseeable future, and people will use it for years to come.

...but it is already niche, and will increasingly become so.

Only time will tell, but I'd be shocked if you don't see more big name migrations away from hg over the next year or two.

People are important.

When your project forces them to use tools that don't like or don't know, they go else where. The impetus to change gathers more slowly in companies; but when you see announcements like this, like google code, like atlassian marginalizing hg, like cpython... it's crazy to suggest that it doesn't affect the way people think about mercurial.


There are tons of companies using Lotus Notes. git won.


What does "won" mean, concretely? I mean, if 75% of people use git and 25% use mercurial, what does it matter?

Also it's not true that a lot of forward-thinking, progressive, thought leader tech companies are using Lotus Notes. That is true of mercurial.


I think "won" means that when you are making an argument to introduce a piece of software into your workplace there is a technology that is more widely used. It doesn't necessarily mean that one is better, but there is usually a reason a technology is widely adopted. If you don't fully understand the advantages and disadvantages of similar products then widespread adoption can help with the decision.


Yeah by "git's network effects" you mean github. If github had decided to be hghub instead, hg would probably have won.


Or if Github had added Mercurial support at the same time Bitbucket added Git support (circa 2011?), I do believe that the playing field would be a lot more even today than it actually is.


Mercurial's storage format was broken from birth; it dealt with the concepts of individual files and history on them. Git's storage format was much more basic but more flexible, with the result that it was possible to implement the Git storage engine in different languages (cgit, jgit, libgit) as well as a minimal transfer protocol.

http://alblue.bandlem.com/2011/03/mercurial-and-git-technica...


It seems github and bitbucket were released in the same year.


Yes, it's likely that github had more (or better connected) users at first and then Metcalfe's Law took over.


github catered to some of the big open-source names early.

Of course, now that they've "won". They're basically letting the open-source stuff rot. See the recent complaint by quite a few projects about github and lack of support.

This is the problem with anointing a "winner".

Now we'll have to wait for github's replacement just like we had to wait for SourceForge's replacement.


You don't take into account tooling. There're more options for tools which work with git than for hg. Also, git support is usually more stable and better tested.


Except unlike your examples, hg was contemporaneous with git.

Git may have won the network effect benefit but 10 years ago it was not at all clear how it would shake out. Mercurial did gain enough users (and large users) to remain relevant, unlike some of the other options at the time.


Well yes, that's the point! It would have never been the replacement for git because it's the same paradigm.

rcs: revision control

cvs: concurrent check outs

svn: atomic versioning (edit: originally said renames that don't suck - thanks Danny for correcting this)

git: decentralised version control

To replace git, you need a new paradigm. I don't know what it is, and I think few people here would.

Edit: to reiterate, none of this has anything to do with whether git or hg is technically better.


Except its not the DCS paradigm that led to git's network effect. In fact, for the vast majority of users they are using it as a de-facto centralized system (on github).

DCS was around before git and did not sweep the tech industry. Just like concurrent check outs weren't the reason cvs took off.


>To replace git, you need a new paradigm. I don't know what it is, and I think few people here would

um.... how about a good command-line UI that doesn't require remembering all sorts of crazy command line switches?


Most would agree that Git's command line leaves a lot of room for improvement (although the manpages are quite good at explaining). But the internal concept is sound.

I find it a bit odd that no-one has come up with a decent GUI or an improved command line tool for Git yet. There's plenty of attempts to supplement Git with extra commands but that's hardly an improvement. There are several implementations of the Git plumbing parts (e.g. libgit2), so making an UI on top of it wouldn't be that much work.


"svn: renames that aren't awful and keep history "

No, it was "atomic commits and single revision number for a change"

Remember CVS had non-atomic commits (part of the commit could succeed, part could fail), and per-file version numbers.

Disclaimer: I worked a lot on SVN :)


I stand corrected. Will edit my post and credit you.


Git was far from the first DVCS though, or even the first open source DVCS. Darcs, Arch, Monotone at least came before. So this does not explain why Git is the most popular DVCS, or why Git is more popular than Mercurial.


   Well yes, that's the point! It would have never been the replacement for git because it's the same paradigm.
No, it really isn't the point. How can hg "replace" git, when they were be developed at roughly the same time for roughly the same purpose (replace bitkeeper, provide a DCS for open source work), with roughly the same model.

Git didn't come up with the paradigm, and neither did hg.

git and hg were direct competitors, not different generations of revision control like the list given.


I think the big big points for git initially actually were: 1) performance - everything comparable but open was way slower back then 2) a usable and relatively small per-checkout history

In the cvs & svn days I used a fair amount of hacks to get those two, and pretty much always failed. For svn svk was a partial solution. For cvs there was rsync, but also something else I can't even remember. Bad memories fade.


svn eventually got a fairly hacky answer to merging edits to a renamed file. For a long time it didn't even try, and git was a godsend compared to straightening out messes like that.


How about "git, but actually usable".


Thats mercurial :(


If people would judge a tool on its technical merits, that may be true. However, a lot of people that adopted git hardly needed/used git's improvements (in their one man projects).


hg-git[1] lets hg interoperate with git repositories, which helps a bit with the network effect problem. I'm currently using hg-git for my projects and I am loving it because I much prefer the hg UI (both the command line and tortoiseHg) to git's UI.

[1] https://bitbucket.org/durin42/hg-git


I use this constantly --- I've been migrating all my projects to github. hg-git Just Works (almost; there are a few places where the git model doesn't match up with the hg model).

If you like hg, but want to exploit git's network effects, I strongly suggest checking it out.


hg came before git, you have your network effect backwards.

The reason git ended up overtaking mercurial is because git is more flexible. Programmers for closed-source enterprise projects worldwide flocked to git because git can be massaged into any existing development process almost painlessly.

Mercurial, in contrast, is "opinionated".

(Before you mention github -- the timeline here is also backwards, github became the de-facto standard riding on the coattails of git's success.)


I'm curious what makes you say that. From my point of view the exact opposite is true. Mercurial allows many different workflows (bookmarks, anonymous heads, named branches, topics), but with git you're pretty much stuck with the "standard feature branching" workflow.


>I'm curious what makes you say that.

The experience of migrating to DVCS's. (Anecdotal, I know, but still...)

>...but with git you're pretty much stuck with the "standard feature branching" workflow.

Git is a loose collection of file manipulation utilities, it can be cobbled together to support even the most insane workflows.


> Mercurial allows many different workflows (bookmarks, anonymous heads, named branches, topics), but with git you're pretty much stuck with the "standard feature branching" workflow.

Mercurial is internally more complex than Git, as shown by the concepts you mention (bookmarks, named branches, etc) and all the various extensions. By contrast, Git is just a malleable graph of patches and tools to manipulate it. This is very well explained in the first commit(!) of git, which explains the concepts and the internal database layout.

In Git, there might be a "default workflow" that the tools are geared towards but you can use rebase and cherry-pick and all the other tools to enable just about any workflow you can imagine. Of course, this allows you to turn it into a big mess and there are some weak spots (like tracking a lot of bugfix commits backported to several release branches) but the concept is simple and sound.


This. Absolutely this.

It's ironic how many people claim that Mercurial is simpler, when actually git is much simpler and more elegant. You don't need named branches, bookmarks, extensions, and all that stuff. Just a graph of commits. The core of git is beautifully simple.

I don't know what's more frustrating-- people who think DVCSes need to be really really complicated, or people who endlessly complain over what color the command-line bikeshed is painted.


> hg came before git, you have your network effect backwards.

Can you explain? Not sure how hg being released earlier changes how many users they have. See https://en.wikipedia.org/wiki/Network_effect


Time line isn't the same thing as network effect.

GitHub and Linux gave git the network effect.


I talked with an engineer from a fortune 500 tech company and they chose git over other vcs because they could have permission control; they have sensitive sub project who needs only a small set of engineers with permission to access it, but that subproject/module is part of a bigger project that everyone has access to.

I personally prefer HG over git and use it for my own personal projects, hosted on my own redmine server. I tried bitbucket, and github; the latter have s superior interface to bitbucket. which I believe why people picked github over bitbucket


You find yourself in a realm where hackers don't branch and use svn with no experience of distributed source control.

hg is so much your friend here. They will actually probably get over the switch hump and use it. git that hump is much bigger and more arduous. Git is great, I like it. When you want to drag the team with you who aren't already sold, just go straight to hg every time. You're hacker, you can use either effectively and both are excellent tools.


I believe that Mercurial's greatest flaw is that it is too damn easy to use. Since you don't have to wrap your head around it so damn much to use it, it seems weak, like if it was only slightly better than subversion.

The truth is different and Mercurial is roughly as capable as git but it's easy to miss Mercurial's power where as Git rubs your face in it (less so these days but early on, it was a brain f* to my CVS trained brain.)


If you ever see this, Thank you Matt. It helped me a lot to get away from subversion by working with hg at the same time.


I've only contributed a few patches to Mercurial but meeting Matt and learning from him (mostly on the HG mailing lists) has taught me a lot. He's influenced how I think about and work with code at a really basic level. I wish him the best in whatever he decides to do.


Thank you, Matt. hg is still my choice in source control. It's the only one I really use.


I've used Mercurial on Bitbucket in the past and loved it. Very thank you for your hard workd, Matt. Too bad that git is on everywhere now.


I think hg was/is important, to provide competition to git.

But I don't really understand all the people arguing that hg is so much easier to use, and so much cleaner. Sure, in the first few years that was true, and there's architecturally better choices (not a mess of scripts, embeddable as library). But from a day to day usage, hg seems worse to me. And that includes the documentation, something that really surprised me after I had to restart using hg a year or so back.

The whole thing how hard it is to actually get rid of branches (no, I do not want to merge that branch. Yes, I don't want any central record anymore. No, I don't want to ssh into the remote box. Uh....), really bugged me. So does the need, slowly abating, to activate a lot of random plugins to get functionality that git had for years (pagers, incremental add, staging area, ...).

But I very well, and I actually mean that, might just be mind warped by having used git so long and so continually that I just don't see the problems anymore and it just seems easier. I do remember some initial difficulties understanding it, but that was in the quite early days...


Mercurial has to be one of the best examples of incredibly high quality Software Engineering out there. It is very well-designed, reliable, fast, easy to use, well-documented and has a great community behind it. Matt deserves huge kudos for his enormous effort and commitment over the years. And like a true gentleman, he is leaving in style to ensure the transition is smooth.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: