Hacker News new | past | comments | ask | show | jobs | submit login
Why I Switched to Git From Mercurial (extracheese.org)
176 points by pilif on May 17, 2010 | hide | past | favorite | 100 comments



I've used Git for three years, at two different companies and various personal and community projects. I sync my home directory between hosts using git, I have administered multi-user git repos using gitosis, and I have been a GitHub user since early 2008.

I started using Mercurial two months ago when I joined the Mozilla corporation, and now use it every day on one of the biggest and best-supported installations in the world. I also started using BitBucket for some of my Mozilla-related personal projects.

It might be that I don't fully "get" Mercurial yet, but I still find myself frequently missing Git. My first impression is that Git has a simple flexible model that supports a complex front-end, while Mercurial has a simple extensible front-end that ends up creating a somewhat more complicated model.

Any time I need to step outside the standard commit-merge-push workflow, I find the higher level of abstraction between Mercurial's user commands and its database makes it harder to understand what I'm doing, and sometimes prevents me from doing what I want. Things like rewriting history (e.g. for rebasing), or combining changes from multiple remote repos with different sets of branches, are still possible in Mercurial - but they usually require plugins to do well, there are more different incompatible ways to do them, and there are more opportunities to mess up your repo.

More concretely, I find that MQ is the best way to do many tasks in Mercurial that I would do in git with plain old branches and commits, and for many of these uses MQ is both more complicated and less flexible than the equivalent git commands. (But there are other uses where MQ is really better than the alternatives.) I also find that it's much more annoying to manage short-lived throwaway or topic branches in Mercurial, so much that I simply avoid using them much of the time.

But perhaps I'm just brainwashed (or brain-damaged) from too many years with Git. :)


Good point about MQ, before people pointed me to it, I was continuously surprised by many things I could not easily do in hg.

The DVCS crowd looks down on centralized VCSses and points out that whenever the answer to a VCS question begins with "well, you should have done X before you did this…", it marks a failure.

Fair enough.

But I would extend that further — when I ask "how do I do X with this VCS", I don't want to be told "well see, you don't really want to be doing X". Yes I do want to, and I want a VCS that let's me do pretty much anything I want. That's git's approach.


For Mozilla development I use a git mirror of the tree. I do all my development on branches in that and only use mercurial to push patches to mozilla-central.


For creating temporary local branches, have you tried the bookmarks and localbranch extensions?

Also, I am be interested to learn more about your workflow and why it is so difficult to do in Mercurial. So far, the only feature I've seen in git that I've wanted in Mercurial is the ability to manage publicly named branches using the bookmarks extension, and by extension, an easy way to track named branches.


I use Mercurial and much much prefer it to Git (personal preference, I'll try not to evangalize)

In part he is dead on.

hg really can't handle large repositories; but to be honest if you're working with GB's of data then you're using the wrong tool :) period.

Point two is a "complaint" I agree with. The repository structure isn't particularly good - it "works" for the most part but sometimes you just want to kick it. And forget hacking around with it..

Silly things like "hg copy [file]" doesn't copy file history but does a remove/add & cp/rm are another ball ache.

Ultimately hg is a good tool; for lightweight, hackerish version control it is great. Beyond that? Yeh, use Git.


But isn't also Git just as good at the stuff you think hg is good at?


Yes.... though it is more complex (and in my experience a lot of that complexity is not needed by most). So hg is a nice portable alternative.


What part do you find complicated about git? The basic commands are: git clone, git add, git commit, git push ... most of these are handled by guis (tortoise, gitx, etc) so all you have to do then is click the right button


Well, exactly. For the vast majority of people those are the only four commands needed. So hg is a great alternative to git.

If you need something more complex or specialist then git is the clear winner.


I think the parent is trying to say that why use a tool that is "hackerish" if they both do the same thing with the same few commands. Then if you need to do something more complex you already have git.

Edit: iPad mistype.


I know this is glib but; it's more "raw" :)

But that's a personal preference. Git is just as good a choice.


hackerish != hackish.


I agree mostly. A large port tree shouldn't be checked into a source code management system,


For sure. But I do think it's just a sign of good design that Git is easily usable in ways that are unexpected and outside its original intended purpose.


personally, I really don't get the complaints about git's UI. OK. I understand the confusion about what checkout does, though on the other hand, once you know that, it won't happen to you.

But a revision control system failing to not corrupt or crash depending on the data you put into it is, frankly, no revision control system.

Just like a database failing to return the same data back that you told it to store and without telling you a problem occurred at store time is no database either (cough mysql cough).


"I really don't get the complaints about git's UI"

I think it's because git's data model is so minimal and elegant, and the UI is anything but.

For me, it's not so much that the UI is quite bad (which it is), but that it could have been brilliant.


Perhaps you could elaborate on a UI design that would be brilliant. Even better, code it, if you can improve do. I'll tell you what, if you even succeed in describing such an interface, I'll build it for you.


Oh, I didn't say that it would have been brilliant if I had built it. But I'll bite anyway. Or at least provide a couple of thoughts.

The index is one of the key components in git, but it doesn't really have a name or label in the UI. Say that it was called "index"; then the current "git diff" would be equivalent to "git diff index", and the current "git diff --cached" to "git diff index..HEAD". Less special cases to remember. IMHO, of course.

The same way "git checkout index foo.c" would fetch foo.c from the index (I don't even remember the magic incantation for doing that now). Etc.

Also, I still think that using the index should be optional: "git diff" should default to "git diff HEAD", "git commit" should default to the current "git commit -a", etc.

"git checkout" tries to do too much. It creates and switches to branches, and copies blobs from the repository to the working tree. The first form is reasonably safe, and bails out without --force if you do something stupid, the second does not. At least for me, the only way to learn the difference is the hard way.

The branch-switching should probably be done by "git branch" instead, and the fetching of blobs by "git reset" (which sometimes already does this, but with very confusing options; I never remember the difference between --soft, --mixed, --hard, --mixed and whatever).

That's only a couple of changes that could have been made a long time ago. Now it is definitely too late. Even if the git UI could be made smaller and more logical (with a huge amount of work), it's not worth pissing off pretty much every git user out there...


I disagree on making `git commit -a` the default behavior for commits in git. It discourages making nice, atomic commits.


I agree that two-stage commits is a great feature to have. But there are downsides to making it the default.

Obviously, it trips beginners up.

And it encourages committing stuff that may never have coexisted in the working tree - and thus have never been tested together.


I can't think of any reason for someone to commit changes that hadn't been tested in the working tree or at least ran through the test suite before doing so.


See bazaar.canonical.com.


a cursory glance at the screenshots there show it similar to git gui / gitx or similar.

I'm talking about fundamental interaction with the version control system, not a pretty gui. git has pretty gui too.


It's not just the GUI - bzr has one of the better-designed command line UIs too. It's very similar to Mercurial's, plus some nice things borrowed from other systems but integrated very consistently. (But I do agree that there's more to a VCS than UI design, and after the initial learning curve there's not a huge difference in command-line usage between the popular systems.)


I disagree. I found bzr to be a mishmash of poorly thought out options and features. A quick example: Compare bzr log's "-r" option to "git rev-list". bzr's "A..B" is stupidly inclusive on both ends making scripting very difficult.

If you want a really nice, consistent UI, check out darcs.


It could still be brilliant. Git's porcelain (the high-level commands you use day to day) has evolved a lot over the last few releases - e.g. "git mergetool". Indeed a couple of years ago ISTR the recommended way for most developers to use git was with a third-party porcelain layer, but the built-in porcelain improved enough to be blessed and the third-party layer was deprecated.


Try SmartGit.


> I really don't get the complaints about git's UI

I would group mine into two main categories:

* Error messages that are confusing.

* Requiring that the user knows a fair number of options to commands. You can get by in svn without knowing many options to pass to commands, but with git, you're going to sink if you don't.


Error messages that are confusing.

Which ones? I have found them helpful, suggesting the right possible commands to use to solve a problem.

Requiring that the user knows a fair number of options to commands.

Which ones? "git add", "git commit", "git push", "git log", "git revert", "git checkout", "git merge", and "git branch" do not require any options unless you want some shortcuts or useful things that SVN cannot do.


The error messages have been undergoing fairly rapid change lately, as in, over the past year. I'd say that anyone complaining about the error messages should double-check that they have a very recent version. If you're just using your distro's version you may be a ways back.

That said, there are still some error messages that are quite good, if you understand git's model, but if you don't are nearly opaque. (Easy to google, though.) Git really is unfriendly to you if you're just trying to hack along without understanding how it works, and I don't see that ever changing. It's a power tool, not a butter knife, and while it can, should, and does have guards in the right place to keep you from really hurting yourself (you basically can't lose data in the repository, thanks to reflog; be careful with checkout, though), it's not ever going to be quite as simple as a casual user would like. If it was, it wouldn't be git anymore.


An example that trips me up frequently is creating a remote branch, then tracking it in a local branch. This is by far my most common workflow, but as far as I've learned so far, involves a couple of commands with some easy to forget options.

Granted, after a few times I just wrote it down, and now mostly remember, but it's not as simple as it potentially could be.

I was also a little shocked to find that I couldn't simply start tracking a remote branch after a local branch had already been created -- requires git 1.7. The workaround was simple (create a new tracking branch and merge the changes over), but to me this is an example of the UI being a little unhelpful.


Coming from Perforce, I'd say that git's model seems overly rigid. In Perforce, workflow looks like this:

- edit files A, B, C, D, E in the default changelist. - put A and B in changelist #1 - put C, D, E in changelist #2 - oops, C is the wrong changelist. Move it to #1. - edit file F (starts out in default changelist) - put F in changelist #1 - send both changelists out for review. - edit file B based on review. Run tests to make sure both CLs work together. - commit one of the CL's

So the basic idea is that I have multiple changelists open simultaneously and the contents of the changelists are fluid. I can keep changing my mind about them until commit.

Of course, since Perforce CL's are file-based, this all breaks down if I want overlapping uncommitted CL's. Git handles that better, which is why I'm using Git now. But I still miss the ease of use of Perforce when working on multiple CL's. Sure, the commits in Git are only local and you can always edit them until you do a push, but it seems like I have to plan ahead more and commit more often, or I end up having to split or merge CL's using commands I'm not very comfortable with.


Not sure if you know about Perforce's shelving feature, but it might be useful for you. Here's how it looks:

1. Hack on files 'foo' and 'bar', but instead of saying `p4 change`, say `p4 shelve`. Write down the changelist number for later; this changelist is stored on the server now. 2. `p4 revert foo bar`. You don't lose any changes; they're all on the server. 3. Hack on files 'bar' and 'baz'. Submit or shelve those changes. 4. `p4 unshelve -c (changelist number from step 1)`. (You'll probably need to resolve here.) Your original changes are back!

Git certainly breaks down if you're working on one massive branch, but it's designed for lots of branching. Go ahead; we're encouraging you to branch for every new feature, every bug fix, everything. Here's the above workflow in git:

1. `git checkout -b first-change`. Hack on files 'foo' and 'bar' and commit. 2. `git checkout old-branch`, where 'old-branch' is the branch that you were on before step 1, probably 'master'. Now `git checkout -b second-change` and edit files 'bar' and 'baz'. Commit again. 3. Checkout the old branch (master, likely) again. `git merge first-change`. `git merge second-change`. Resolve if required. Test. Push changes to the remote server.

Best of all, you don't need to branch before making your changes. You could actually move the `git checkout -b first-change` to after the edits on that branch, and it would still do what you want.


I find local branch really nice, but do you really work on all thoses change at the same time ? I tend to code quite linearly, one functionnality at a time. May be I'm working on too small projects ?


In that case, it doesn't really seem that you would notice much of a difference between Perforce, git, or what have you. Well, maybe between CVS and earlier (which tracked changes per-file) and SVN and later (which track them per repository).


You may want to check out http://porkrind.org/commit-patch/. It doesn't do changelists like you describe but it lets you check in fine grained stuff easier than "git add -i" (IMO). Especially if you are an Emacs user.


Why is git still a collection of bash scripts ? Does nobody care enough to wrap the core into a library (yes, i do know about the glacial libgit2 project) and put a Python/Ruby/Lua interface over it ?

Dulwich exists, but it is not a drop-in replacement.

When will I get a true platform independent Git (none of the msysgit stuff) ?


It is still bash because bash is more universal than Python+Ruby+Lua.

The only place bash doesn't exist is on Windows and installing Cygwin is the least of your worries in that case.


we have selenium testcases that need to be run on IE. We need to have a revision control on windows. Please dont be dismissive of windows just because you can, some of us have to make a living.


I don't think there is a problem with the UI. I don't use git, but by the tone of the comments people seem to be unable to use it, and therefore blame the UI.

I think the real problem is the documentation, both official and unofficial. The best git intro I could find was gittutorial. It's OK, but a bit unfriendly. Everything else rapidly goes from telling you how to do stuff to teaching you how git works.

If somebody came from SVN and told me that hg was unintuitive I'd tell them it's pretty easy, and they just have to get used to a slightly different model. Then I'd tell they to try hginit.com. I'd also point out how they can still work while the network is hosed, and that even if the server dies they still have all the history. Cool, isn't it?

git users tell people to learn graph theory.


The author states three reasons for switching.

1. Problems with storing big files in Mercurial. You can use the bigfiles extension if you really want to manage large files with Mercurial.

2. Inefficient renames. Making renames efficient is a currently recommended GSoC project. I'm sure this will be fixed eventually even if no one picks it up this summer.

3. Destructive commands actually, well, destroying stuff. This point makes me feel like the author knew git first, tried mercurial out, and switched back, making the blog post a little misleading. I don't know how you could expect a delete not to be a delete unless you were familiar with something like git already. If I were to run a delete command in Mercurial, I would read the documentation on the command first to make sure it created a backup for me. Only if it then failed to create this backup would I complain. Also, I think I prefer the bundle approach of Mercurial. You can always rename the bundles to keep track of them. You could even write your own extension in 5 lines that ran a destructive command and immediately unbundled the created bundle to restore your changesets, exactly duplicating git's functionality.

The first two issues he mentions I would consider to be actually valid complaints against Mercurial, the third just a personal preference of the author. I would consider neither of them to be major game-changing issues.


> I don't know how you could expect a delete not to be a delete unless you were familiar with something like git already.

Ability to control and be able to reverse any changes you make to the source code tree is an essential feature of version control system - precisely because you don't know in advance what will work and what won't. The fact that people are not used to that simple idea just shows how broken are most of the other tools out there.

There is no reason not to want an unlimited undo for almost everything, especially today when disk space is so cheap.


Maybe this is not that much relevant for DVCSs but in 'classic' VCSs such as SVN an 'obliterate' command would be quite useful, think about the case when someone accidentally commits something highly sensitive (such as private keys) to version control. People make mistakes all the time, either way.


you can use commands like git filter-branch & git rebase to change your history - http://www-cs-students.stanford.edu/~blynn/gitmagic/ch05.htm...


"git rebase" on its own does not permanently alter history. It creates a new branch that looks like a new history, but you can get back to the original history.

"git gc" will prune the unused old histories for that permanent effect.


even "git gc" will not do it for a while. the old history will still be referenced from the reflog for some time (I think default is 30 days)


Most destructive commands in mercurial do create a backup first. However, some command, for which all we know, could have been written by a third party, didn't. That's why I suggest that you read the docs for a command and test it out on non-important data before applying it to your only copy of a repository. Someone could just as easily create an extension in git that forgets to create a backup as well. What happened to the author is entirely the author's fault.


I don't know about Mercurial, but in your IDE / Editor, don't you like having multi-step undo no matter what command you execute?

Or do you prefer to manually backup the files of your project before doing any operation in your editor that is potentially destroying your files? I'd much rather hit ctrl-z as many times as needed once I noticed my last refactoring has shredded all the files it touched.

Being able to easily undo whatever I do to in whatever application I can think of is a nice feature - even more so if the application is what I entrust all my work to.


When I run sed on a file, I don't expect it to make a backup copy of my file. Similarly, when I run rm, it doesn't create a backup of what I'm deleting. Destructive operations are, well, destructive! I'm amazed at the response I got to my post. Read the docs on a mercurial command. Chances are if it is destructive it creates a backup for you. On the off chance that someone writes an extension that fails to do so, you can create the backup yourself. There's nothing magic about git's operation here. Someone simply took the time to create a backup in git for a command for which the equivalent mercurial command didn't. Big deal.


Git's repository structure, plus the built-in reflog prevents committed data being lost by any command, unless it explicitly erases the repository or reflog.


git stash drop

git gc

oopsie data loss. It is about what he did in hg, except in hg it is one command.


The stash has its own reflog

git gc only prunes nodes unreachable from branches AND the reflog, which I think by default is 30 days long


I explicitly said "committed data" would not be lost, because data only staged in the index certianly can be lost, and I think stashed data is also semi-suceptable to loss as well.

git stash drop does print the sha1 of the stash, and as long as you know that sha1, and it's not been gc'd, you can get a dropped stash back. (git fsck will also show the sha1s of dangling commits left from dropped stashes.) But while a separate reflog records existing stashes, that information is not retained when they're dropped. It's perhaps best to think of git stash as a more convenient form of git diff > patch, and you wouldn't expect that to keep a log of the patch file either.


Yes but the original author in this very thread has said that the data loss was through MQ(Mercurial patch Queue) delete. mercurial queues are an optionally controlled patch queue, so he had some code stashed it in an uncontrolled queue, deleted it and was surprised that it was really gone. This is rather analogous to what I posted for git. It was a bit of bad luck on his part but switching to git doesn't close that hole his code is still vulnerable to the same set of actions.

So his whole reason for switching is I shot myself in the foot. And instead of learning more about his weapon of choice to avoid doing that in the future, he traded in his gun for one that is slightly more complicated.


Kind of like git branch -d, which, as http://www.kernel.org/pub/software/scm/git/docs/git-branch.h... states, deletes the reflog as well? If it doesn't delete the reflog, then it git world, at least, it probably isn't considered to be fully destructive!


git branch -[dD] does not delete reflog entries for commits made to the branch.

A branch may have its own, separate reflog which would be deleted, but that is only a convenience feature as the man page you linked to documents WRT the -l option; the primary reflog still records all operations made on the branch.

You might find it useful to actually test stuff before posting links to man pages that you don't fully understand. I know I do. :P


Destructive commands actually, well, destroying stuff.

Part of the point of using a versioning system is to avoid ever destroying stuff. Therefore, in a versioning system, you'd expect to have to work pretty hard to make a change you couldn't roll back from, wouldn't you?


Yes, and hg and git both make you work hard. I'm not sure what his point is. He used a quite advanced command without understanding its consequences, he paid the price. A non-advanced user would really have no need to use hg strip.


> I don't know how you could expect a delete not to be a delete unless you were familiar with something like git already.

Unless they were also familiar with functional programming and immutable data structures; it's the exact same mental model.


> I don't know how you could expect a delete not to be a delete unless you were familiar with something like git already.

Because it's version control; isn't the whole point that I can change things and return to a previous state?

I don't know anything about hg other than it being distributed, but if it destroys things, well, it's not a VCS as far as I'm concerned. That's crazy!


I'm not aware of any VCS which meets your standard of not allowing destructive commands (I'm sure you realize you can destroy history/data in git as well, right? It may take a --force, and it'll yell at you, but it's definitely doable)


Subversion, the most used VCS in the world, has no totally destructive commands per se.

Once you commit something, it stays in the repository in the commited version forever.

In SVN if you really want to delete a file, you have to stop the service, dump the repository to a text file, edit the dumped file to delete the data (or alternative, do not export the latest revision), restore the repository from the file, and restart the service. SVN has no native way to do that, you have to use some external utility to totally delete something.

Now, it can be argued that this is good or bad design, or that centralized VCSs are bad/distributed are good. But you are making a broad statement about VCSs and ignoring the existence of SVN, and this is misleading to anyone who reads this thread.


It's a lot harder than that, actually. You have to do --force, clear the reflog, and then run the garbage collector. Your data isn't actually removed from disk until the last step.


Yep, and beauty of the system is that anyone who is a sophisticated enough user to do that, would never do it accidentally.

Although, I imagine quite a few users --force a command and, unaware of the afore mentioned facilities, write up a nasty blog post about switching to hg from git because git lost their data :)


Sophisticated users make stupid mistakes all the time. They misread output, get confused about the context in which they're operating, etc. Human beings are not machines. You cannot assume that just because a user is sophisticated, they will not make mistakes that lead to data loss. Even the best drivers still have accidents.


If I git rm something, and then git reset, my file is back. Are we talking about something different, or am I remembering git wrong? I don't actually git rm very often.

And it makes sense that there's a permanent delete feature, but I'd expect it to be outside of the normal workflow.


Yes, hg has a non-destructive rm too. And yes, what he's talking about is outside the normal workflow. Way, way outside.


Okay. Good. I thought it had to be that way.

So why do you speculate he's using the wrong delete?


Yeah, it's not clear what he did, all he references is a twitter posting saying he lost data: http://twitter.com/garybernhardt/status/9368728335 , not how.

I think it's fair to surmise that he must have been messing with commands he didn't fully understand.

The bottom-line is that in either git or hg you have to step past the screaming sirens and big red warning signs to truly lose data.


Because he lost data? hg rm wouldn't ever lose data. He probably used an hg strip (which is an advanced command and must specifically be enabled in .hgrc through the mq extension) but didn't realize what he was doing...


The command that lost data was hg qdel. Strip won't lose data; it dumps bundles (although they're a pain in the ass to restore from). Like I said, I used Mercurial for three years. And not "I play with it sometimes at night" kind of used, but rather "it was my main version controls system all day, every day" kind of used. I was using MQ for most of that time.

The fact that so many people consider "hg strip" an advanced command is part of the problem. Modifying history should not be considered advanced. Being able to recover from ANY command, including destructive ones, should not be considered optional.


> The command that lost data was hg qdel

Yes, so that deletes a patch. Anything in patches is basically in flux, and I wouldn't call losing a patch "data loss". If you call hg qdel "data loss", you'd call any sort of modification to a patch "data loss", since patches aren't versioned. If you want versioning with patches, use pbranches.

> Modifying history should not be considered advanced.

Maybe, but the only way I modify history in practice is through rebasing. I've never ever felt the need to modify history any other way. What use case do you have for modifying history in potentially destructive ways?


Git gives me everything I needed MQ for, but with the complete safety of the reflog. There is no such thing as a change I can't undo. The fact that patch management is "special" in Mercurial is the problem!

With respect to history modification:

First, I rebase a couple dozen times per day. I'm on a team that doesn't use merges unless we have a reason to (this makes it easier to bisect and think about history). I also create, destroy, and rebase many of my own branches every day.

Second, I amend commits a lot. I'll often spike some little piece of code I don't understand, then start amending the commit as I rewrite it with TDD, until the commit no longer contains any traces of the original spiked version. For more complex spikes and TDD rewrites, I'll do it over many commits, rebasing the spike over the rewritten version until the spike commit is empty and gets skipped by the rebase. Doing that in Mercurial would be... arduous. I can easily do multiple history rewrites per minute while doing this.

Third, I amend commit messages a lot, usually with "git rebase -i". Maybe I forgot the ticket number, or maybe the meaning of the commit changed (see the next point).

Fourth, I sometimes do drastic commit rearranging. This is harder to explain, but it usually involves splitting commits (in the simple case) or moving sets of related changes from one commit to another (in the complex case). These are sometimes at the file level, sometimes at the hunk level, and sometimes within a hunk. This is rarer than the others; I probably do it once or twice per week.

Fifth, I "git reset <ref>" a lot. It took me longer to start doing this, but it's useful in a lot of situations. For example, "oops, I accidentally created a merge bubble."


the patches directory that mq uses can be put under hg control.

i don't know about git reset, but everything you mentioned before can be done with mercurial (mq, histedit, ...)


Yep – and I did it all, using those tools, for a couple of years. :) Now, when I go back to Mercurial (which I know better than Git, mind you), I get frustrated. Those tools are much more blunt than their Git equivalents.


so i tried it for a couple of days, and the speed was the thing that impressed me the most actually. the rest is not that dissimilar, but i didn't dislike it as much as i thought i would :) - our workflow assumes mq already so a git add is a qnew, or qref, a git diff --cache is a qdiff, a git diff is an hg diff ... so on. most commits i make are usually a qfinish, which is comparable to a git commit (no -a).

how do you manage patch queues in git? we need them because we are constantly backporting to different versions of our app. branches will mean n merges for n versions. stacked git? or is there a git native way to manage the same?

what about something like tortoisehg? gitk is pretty crude in comparison.

i assume one can glue a diff/merge tool like meld. is the experience similar when resolving conflicts?

thanks for any feedback.


Also, MQ's "qdel" command is the one that led to the data loss mentioned in the original blog post. So it doesn't really answer my concerns. :)


This is always relevant: http://keithp.com/blogs/Repository_Formats_Matter/

"I would like to argue that none of the user-interface and high-level functional details are nearly as important as the fundamental repository structure. When evaluating source code management systems, I primarily researched the repository structures and essentially ignored the user interface details. We can fix the user interface over time and even add features. We cannot, however, fix a broken repository structure without all of the pain inherent in changing systems."

Keith makes a good point. While Git's interface is lacking in some areas, those things can be fixed in the higher level porcelain. Picking a system with a nicer interface whose plumbing is uglier will lead to problems further down the road.


With respect to his claim hg lost data for him, he was using mq without really understanding it or using a versioned queue. mq is disabled for a reason, and he enabled it without fully understanding the risks and ways of mitigating those risks. I've discussed this with him at times, but the message never seems to connect.


Augie, I understand what you're saying, and I don't buy it. Git, when taken as a full DVCS capable of rewriting history, is safer than Mercurial, when taken as a full DVCS capable of rewriting history.

A DVCS that is incapable of rewriting history is, for me, a nonstarter, so I'm not interested in talking about "well, if you turn off the interesting parts of Mercurial, it's perfectly safe!"

You can either use Mercurial in a mode where it's not at all equivalent to Git, but safe (extensions off), or you can use it in a mode where it's somewhat equivalent to Git, but might lose your data.

With Git, I can mutate history without the slightest bit of fear, often just to see what will happen. Does this giant branch I discarded two months ago rebase cleanly over master? Try it. If the rebase completes but I don't like it, I "git reset mybranch@{1}" and everything is good. And that safety net is always there.

In Mercurial, I have to stop and think every time. Even if the command does dump a bundle, restoring from it is a special case, and I'm going to have to go dig up the bundle file, and in some cases it might not be there and I'll be screwed. In Git, there are no special cases, I always know exactly how to recover, and the recovery mechanism is always there.

Once more, to be clear: In Git, it is always there. Always there!


I still think you need to be much clearer here. _Nothing_ about Mercurial is unsafe - mq has dangerous edges, and we're aware of that. I'm trying to design something that's more flexible and safer than mq, but these things take time.

Let me state it to be clear: mq is your problem, not Mercurial. Mercurial is perfectly safe.


i guess i will have to try git to be sure, but i really don't see a difference here. usually if i'm going to try something drastic, i try it on a clone that i know i can throw away.


I often do it multiple times per minute. That wouldn't fly if each required a clone. :) (See another post I made in this thread for what I'm doing that involves so much history mutation.)


"It's just an interface, though, and this is a tool you are going to use every day..."

This summarized, for me, why I use hg. It is a tool I am going to use everyday and it's not ok for this tool to have a crappy interface. My hard drive space, that I don't care about.


Did you read the end? ;)

""" I'm sorry for recommending software with a confusing interface. But you'll be spending a lot of time with it; it's worth getting over the initial hurdle of confusion. """

Note that I call it the "initial hurdle". I know both systems very well, and Mercurial gets in my way far, far more than Git.


git's interface isn't terribly intuitive, but it isn't that bad. Once you get the hang of it, it makes sense.


I really don't follow this argument. git's interface is a giant turd. I've been using it for months, and it still hasn't stuck, no matter what tutorials I read. The normal workflow needs far too many commands and special options, local vs. remote branching seems to do weird things, and the error messages are completely obtuse.


not all guis are made equal, depends which is being used to how good or bad it is. I use gitx on osx (http://gitx.frim.nl/), other than the lack of a 'push' button its spot on, simple to use and powerful.


Yeah, I too thought the logic of that statement was completely back asswords.


I thought Git handled huge files poorly too. What I'd read was that most algos in git assume that the whole file in revision control can be held in memory at once to do things like diff.

Has this changed, or was I always mistaken, or this guy talking about the sum of file sizes being a few gig?


It still handles them poorly by default. You can do things like edit .gitattributes to say that e.g. a *.binary file should be treated specially, but Git's still not a good system for e.g. archiving HD video.

Some of this can be fixed, but a lot of it is probably not going to change. When you git-add something it has to checksum the old data + new data. That's going to be a pretty expensive operation when you have 50TB of data.

There's no DVCS that I'm aware of that handles large binary files as well as say Perforce or Subversion.

Check out this project for more info on tuning Git for big files: http://caca.zoy.org/wiki/git-bigfiles


I cant find the resource, but sometime back someone compared DVCS for large binary files (game assets) and saw they were absolutely inefficient .. and in several case incapable of handling large files


Thanks for this good article. I took a 15 minute tour of both HG and Git and felt that hg was overall a better experience, but felt if the community is moving towards Git there has to be some good reason. I'm always a fan of the underdog, so I've been asking everyone why Git (besides Github of course).

This is the first article that gives real pitfalls of one vs the other. I enjoyed the read and would love to hear more as well as counter arguments.


... but felt if the community is moving towards Git there has to be some good reason...

Must there? What if most people are switching based on the same vague feeling that there must be some reason behind the shape of the swarm?

(I'm a fan of both systems here, fwiw.)


Hg is going to usually be something you pick up slightly faster. It is between much and very on the intuitive scale. On the same note, once you get to competency (between 2 weeks and 4 months of use, depending on the person), git is more easy to manipulate and do the sort of things you often have to do when working with people on a project.

While somewhat unintuitive in some of the commands or the default arguments you may need, git is perfectly decipherable and memorable once you do get through the initial period.

Additionally, as git is often handled on the command line (even by people who'd usually use GUI programs), it LOOKS more intimidating, but it seems a few weeks in, people are getting by with Hg (As they don't have to get what's going on) however can do pretty complicated stuff in git (as you have to get what's happening or you will be lost).


although a bit biased, http://whygitisbetterthanx.com/ gives you the highlights of what git is good at.. for me its the simple branching coupled with easy stashing


Being biased is OK, but that site is just flat out wrong on some of its points. Mercurial has cheap local branching. There are good hosting services for hosting Mercurial repositories.


What makes you think Git is the underdog?


I think he's implying that Mercurial is the underdog


Yeah, that's the way I read it also.




Consider applying for YC's W25 batch! Applications are open till Nov 12.

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

Search: