Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Ask HN: Google/FB engineers, Do you like Mercurial?
45 points by gitdude on May 7, 2015 | hide | past | favorite | 58 comments
All the Google and Facebook engineers who are currently using Mercurial, I want to hear from them how they feel about Mercurial over Git. If they leave GooG or FB, will they still use Mercurial?


The problem with this question is that there are so many _different ways_ to use Mercurial. hg's core is fairly minimal and everyone I know who uses it rely heavily on core- and third party extensions to get any productive work done.

Mercurial does a good job at facilitating everyone's favourite, yet obscure, workflow. There are people who prefer using things like mq (patchset queues), which until recently also was Mozilla's recommended workflow. Queues are a novel way to organise your work in progress, but is quite different from what people are used to coming from svn or git.

More recently bookmarks were added (also as an extension you have to opt-in to), which are reminiscent of git branches. They make it possible to have a HEAD-based workflow where you rebase frequently, much like you would with git, only that the defaults of `hg log` and various other commands don't interop very well, which means you have to memorise a lot of flags and arguments.

There are also many strange defaults in hg that you simply have to get used to, for example that `hg push` by default pushes everything. I have a hook in place on the remote end which prevents me from doing that.

By far the most frustrating experience with hg is that you cannot expect the default installation to come with sensible defaults. The argument is that keeping "advanced" functionality out of core prevents new users from accidentally using it.

An unintended consequence is that it sometimes makes it difficult for other people to help when you're stuck because more often than not their environment won't match yours.

One frequently lauded aspect of hg is that the user interface is easier to understand. Whilst I appreciate difference in taste, my experience is the opposite. If you follow the HEAD-based bookmark-style workflow, I find many cognitive dissonances in how the bookmark feature interacts with other commands.

At Mozilla we use hg for the canonical repositories and we have many Mozilla related extensions, but whereas I use hg every day now and it's a fine experience as long as I stay within the marked lines, I would return to git in a heartbeat if I had the chance.


"The problem with this question is that there are so many _different ways_ to use Mercurial. hg's core is fairly minimal and everyone I know who uses it rely heavily on core- and third party extensions to get any productive work done. Mercurial does a good job at facilitating everyone's favourite, yet obscure, workflow. There are people who prefer using things like mq (patchset queues), which until recently also was Mozilla's recommended workflow. Queues are a novel way to organise your work in progress, but is quite different from what people are used to coming from svn or git."

Up to this point your comment was true, objective, and very helpful (though I would remove the word "obscure"). Then it starts to sound like maybe you learned git first and got used to it's defaults and now mercurial tastes a little funny to you. I'm guessing this because I got good with mercurial first and then when I tried git it left a funny taste in my mouth. I thought, what is this "fast-forward merge" that doesn't actually merge anything? Why do people talk about deleting a branch when it doesn't actually delete the branch of commits in the DAG of commits, just a pointer? Why does pull do a pull (fetch) and merge (mercurial's pull just pulls, or fetches, I guess)? Stuff like that.


There's definitely a lot of baby duck syndrome on both sides of this git-vs-hg thing:

https://en.wikipedia.org/wiki/Imprinting_%28psychology%29#Ba...

Habituation is the best user interface.


> More recently bookmarks were added (also as an extension you have to opt-in to)

Bookmarks were added to the core in mercurial version 1.8 in 2011. No configuration is needed to enable them.


Do you realise that "HEAD-based" doesn't mean anything? In git you are always at HEAD, by definition. It refers to the commit currently checked out, wherever it may be in history. The only way to not be at HEAD is to have a bare repo without a working directory. Mercurial calls this commit "the parent of the working directory" and uses the notation "." to refer to it.

It's a very widespread common misconception that "HEAD" means "latest", probably because this is what it means in svn.

And this brings up some very interesting usability research from Google: the vast majority of people who use any VCS don't really understand it:

http://static.googleusercontent.com/media/research.google.co...

I realise you are trying to say that you like to rebase and linearise your hg history. This is just `hg pull --rebase`, just like `git pull --rebase`.

> only that the defaults of `hg log` and various other commands don't interop very well, which means you have to memorise a lot of flags and arguments.

I assume you want something like git where "log" by default starts from the currently checked out commit and hides the rest?

You can have that, and if you don't like memorising the incantations to do that, you can save them as aliases in your ~/.hgrc


It's worth noting with bookmarks that the workflow you describe doesn't even need to use bookmarks at all (and I wouldn't call when they were put into core to be "recent"). All a bookmark does is give a development line a tag that can move.


Why only Google and Facebook engineers?

I use both Mercurial and Git, and honestly, they aren't that different. Unless you're doing something very specific I don't see why you would choose one over the other.


I've never used mercurial outside of TortoiseHg. In fact, the only time I've used mercurial is when I was attempting to build Firefox from source before I realized that they do a git mirror thing so you don't have to touch mercurial at all.

I don't know much about mercurial. I use git because somebody said it is easier to rewrite history in git.


I don't believe the ability to rewrite history is a good idea. One of the reasons I like Fossil-SCM is that you can't rewrite history.


Do you ever write code, test it, and then edit that code some more? If so you just "rewrote" history. The history in the VCS is whatever you decide it to be when you actually commit. You can carefully shape what the history looks like with any VCS by being careful about what you commit. Git and mercurial simply allow you to shape the history after committing as well.


> Subversion uses a centralized revision control model. Ben Collins-Sussman, one of the designers of Subversion, believes a centralised model would help prevent "insecure programmers" from hiding their work from other team members.

source: http://en.wikipedia.org/wiki/Apache_Subversion#Limitations_a...

Sounds like you should be using Subversion then.

Do you understand how history rewriting works in git? do you understand why it's there? do you understand why people use it?

Personal beliefs don't advance computing, hard facts do.


Note that Ben (a personal friend) has been an enthusiastic user of Mercurial for several (4? 5?) years, and is pretty happy with it. He was even using hgsubversion for a while I think.

Note that there's a lot of social problems around DVCS, and the thing Ben worried about is still a _real problem_. I get potential contributors showing up with months of work, and it's an enormous pain in the ass (both for them to rewrite and for me to beg them to work with me) when they did something architecturally unacceptable early in the process that a simple 2 minute review could have caught.


But would the insecure people have done that work at all if they knew they would be forced to commit it publicly? Maybe so, but would it all be one huge commit to svn instead of maybe a string of more concise commits to git or mercurial?

I just envision someone insecure (like I feel at times) saying, well, I'll just clone this and play around on my own machine. Then after making some commits and building up courage, saying, OK, I'll try and go public with this. With centralized VCS that seems less likely to me. The insecure programmer just won't even try. I don't know, it's probably different for different people.


>Do you understand how history rewriting works in git? do you understand why it's there? do you understand why people use it?

I do not. Could you please explain?

At work I learned to use mercurial and never felt the need to pick up git since I can use the hg-git plugin.


First of all, the history re-writing of both git and mercurial do not throw any history away[1], let's be clear on that. The history re-writing allows you to commit willy-nilly as often as you want, and then allows you to clean up those commits to make them readable, useful, and presentable to your team by combining commits, reordering commits, deleting commits, etc. The freedom to commit (and have an undo-point to go back to) at any time is very liberating and anxiety reducing :-)

Using VCS's other than git and mercurial people still end up doing essentially the same thing, they are simply required to do all the cleanup outside of the VCS before they commit. Almost nobody commits every sloppy, intermediate, untested edit of their files to svn or perforce. Users of those VCS's "rewrite" and "throw away" history just the same.

Footnote:

1. They both keep the original commits around after they are replaced by "rewritten" or "edited" commits. git does eventually delete the old history with its garbage collection, but it takes a number of weeks for that to happen. Mercurial saves backup bundle files (or obsolete changesets if using the evlove plugin) indefinitely. You have to manually delete them.


Why would you rewrite history? Don't be ashamed.


For me, I tend to commit frequently, sort of like my obsession with constantly hitting CTRL-S while working in an IDE. Before I push my changes I like to squash the commits into more cohesive commits. If anything, I think it makes it easier on my colleagues for code review.


I do the same in hg. I do `hg amend` all the time to keep adding changes to my commit. At the end I may selectively undo some changes with `hg uncommit --interactive` or `hg uncommit --all` and redo the whole thing piecemeal with `hg commit --interactive` in order to slowly split up my work into several commits. Evolve makes it really easy to keep (and ignore!) a meta-history of all of my editions, with a clear lineage of which new commit replaced which prior commit.

I may also rebase my work onto the latest head at the end (not to be confused with git HEAD).

And all of this with a very nice interface. It's always --interactive, not sometimes --patch and sometimes --interactive.


Thanks, that is useful to know.

Mercurial was my first DCVS and I loved using it, but I only touched on the basic features. I stopped using it when I switched jobs and to become proficient with git. I'll have to give it another try with one of my side projects.


Thats not the same kind of rewriting history because its local to you and hasn't yet been pushed out to others.

Git allows you to push commits to other people and then rewrite history, which is different


Ah, gotcha. Thanks for the clarification.

I knew that pushing a rewritten history was possible, but I can't think of any situation where I would ever want to do that.



No it's not, it rewrites and destroys history. The problem it solves is "keeping the history clean", when actually it's not what you want. You don't see your history, you see logs and diffs. So you want to keep your logs and diffs clean. There should be an other solution to this other than simply removing/merging commits and eventually removing information with it.


We had the same discussion in my office. If I am developing a feature (in a separate branch) - why shouldn't I rebase to make a single commit out of this feature ?

Is this really interesting for you that it took me 10 commits to do sO ? Even if one of the commits was just a "I have to switch an fix a bug and want to commit before switching to another branch" - commit ?

I think there is nothing wrong with rebasing and to merge commits before pusing them.


I don't think it's wrong when using git. However I think it shouldn't be designed like this though. Git rebase should add metadata not remove them. Essentially you rebase because you want to hide certain details because they are not important. Rebase could do one or more actual merges instead and mark certain commits not important so they wouldn't show up in logs by default.

AFAIK rebase is the only operation that happily destroys your history without any --force or --hard option. It always disturbed me.

There is a legitimate usage of rebase though: you really want something removed from history. Like you accidentally committed a secret, inappropriate message or you just want to fix a typo in the last commit.


The way I understand it, I should only rebase (for squashing, not in the case of a spilled secret or inappropriate message) if I haven't pushed it to a shared remote branch. Is that correct?


That's how I am using rebase all the time. I'd say yes - that's the most common use for it and I think it works fine for this.


if you read my post, "history" on local branches is irrelevant. They do not exist and "destroy" here is totally fine. It's not like it's meant to be a grand book detailing all the work done by you, in every point in time, as a database record. What you want here instead is just a clean patch coming off your topic branch -- which this does perfectly.

This is SUPREMELY valuable for OSS patch workflow and I absolutely love git for having it.


Some of the arguments against merging made in this article seem a little strange, for example saying "If folks on topic branches rebase, there will not be any conflicts on merge" after previously stating "It’s also a great idea to rebase periodically - several times a day", as there would also be no merge conflicts if the branch was merged in periodically as well. If merge commits are so abhorrent, just alias git log to git log --no-merges


Rebase is not just a history win, but also a patch review win.


I don't know about Google, but I believe Facebook keeps all of its code in one gigantic Mercurial repository.


Not exactly "all", but certainly the mother load.


Mother lode, the central, most valuable vein of buried gold.


Oh, thanks! I'll let my original spelling stand as a testament to my ignorance. :-)


heavy mercurial user. all my open source projects are on it. first at Google code (rip) and now on bitbucket.

though i have to use git at work daily. github to add insult...

my finger memory is now on git. and that's where git "wins". the chance that you will be forced to use it and learn the awful laundry list of steps to properly use it (hint, if you ever type "pull" you are doing it wrong) you get your finger memory and then curse when you have to use the simple and more intuitive solutions. damn dumb fingers.


> hint, if you ever type "pull" you are doing it wrong

Genuine question: what's wrong with executing 'git pull' on a branch you haven't changed locally?


It could be rebased upstream. While it's a really bad practice, it could happen.


Ah ok, I think I understand the concern. So 'git fetch' and 'git merge' explicitly will stop an upstream rebase from making destructive changes to the history of your local branch(?)

As you say it's bad practice and shouldn't happen. I use gitlab and GitHub where branches can be protected to only allow merges via their web interfaces.


GitLab CEO here, in GitLab you can protect branches to not be rebased at all (web or command line), see https://about.gitlab.com/2014/11/26/keeping-your-code-protec...

I'm not aware that GitHub offers the same functionality.


On the page where the ssh finger print is listed, can you list the RSA finger print too?

I am not well versed in working with git over ssh, but after following the instructions on GitLab to generate a key, then git would keep showing me the RSA finger print which doesn't match the one provided on the website. After looking around a bit, it looks like the one listed is ECDSA.

tl;dr: It was late. Finger prints didn't match. Only logical assumption was NSA. :P (Not really, obviously, but the finger prints could be more clear.)




but you still damage your local copy and it's a pain to clean up, specially if you had local changes/commits


The idea is not to have upstream rebases so you can't pull them by accident.


I don't think git pull would ever destroy your history (AFAIK it's exactly the same as a fetch+merge), at worst you end up in a merge conflict, but it's easily revertable. However after a git fetch and a git log you can see beforehand if there is anything nasty going on.


Nothing unless you're rebasing upstream, but I think the point he was trying to make was that you should always run `git fetch` and then `merge` from there (again, there are some situations where the pull is fine IMHO).


git pull just runs git fetch then git merge.

At least that is what the docs say: http://git-scm.com/docs/git-pull

What am I missing?


but it tries to be smart about how to merge. and usually it's not what you want. i consider it the clippy of linus.

if you run merge/rebase/etc on its own, it will tell and ask you about anything out of the ordinary and then there's no surprise.

again, it's all about avoiding errors on the rare cases because you developed dangerous finger memory.


Beat me to it.


Why?


nothing. but tomorrow, when you are used to type git pull, you will run it on a branch with changes and you have no idea if it will rebase, merge, fast forward... and /then/ you will see the problem. (and open yet another stackoverflow question on how to undo the last merge :)


the question about mercurial by "gitdude" is very umm.. leading.


You can be a fanboy about something and still want to understand why people prefer the alternative.


Honest question: could someone summarize why would one use mercurial vs git? Both seems really close in features. What would be a use case where one would outshine the other?


I promise I'll turn this FAQ you just posed into a wiki page... in the meantime,

https://news.ycombinator.com/item?id=9467096


Google is working on integrating Mercurial into their workflows, but hasn't quite achieved this goal yet. They are growing their hg team with hopes of replicating what Facebook has done, but they aren't there yet. Check out their contributions:

http://selenic.com/hg/log?rev=google.com&revcount=80

Facebook is almost entirely hg by this point, though.


Mercurial is almost unknown at Google.


I did some work on Hg and I liked, but now EVERYBODY is using Git. Very similar systems by the way. I work on iOs apps.




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

Search: