Why a small team chose Mercurial. (ninthdivision.com)
After using git and then using Mercurial, it was clear that Mercurial was a better fit for our company, how we develop. For educated people on git/hg, these might be a surprise. But the people still considering git or hg its a good look.
31 comments
[ 3.4 ms ] story [ 65.2 ms ] threadso yes, cheerleader piece you are right on that. not much cheerleading for hg these days.
Joel Spolsky seems to like it: http://hginit.com/
I don't really get the big issue with branches in svn though. Branches and tags are "cheap" operations in svn, and making personal branches, etc. was something I used to do. Merging back into trunk was never a huge issue either. Maybe I've been lucky; also our team was not very big and different people weren't often working on the same source files at the same time.
"In Mercurial you can’t change previous committed code. In git you can change the past commits in the repo. I am sure there are cases where the linux kernel needs to do this (I can’t think of any), but this is some we don’t even want to have the option to do."
Yes, you certainly can change commits in hg. The tools to do it in git are a bit more refined, but there's no fundamental difference here.
I don't want every failed, unbuildable, safety-net commit making it into my project history. I want it to be possible for people to understand change.
For example, here are the last few commits from my primary work project: http://pastebin.com/BiNpP08s
In a week from now, will you need to see the four different attempts it took to get that last change right? If so, you can always follow the code review link and see the discussion that went on there and how it shaped into that file change, but anyone who makes actual good use of their project history will get frustrated pretty quickly at thought-free changes.
The question is: Why would you commit (to a stable branch) when your code doesn't build or pass tests? Why would you want to eliminate a state where you made something that worked? I don't see the appeal in modifying history.
If you just need to save some partially working state, etc. you can use patch queues- They make much more sense here.
1) sometimes you commit by accident. This happens to me a few times a year, from hitting the up arrow the wrong number of times and pressing enter.
2) sometimes you say something in a commit message that turns out not to be true, or is just a typo, and especially if you're using commit messages to tie commits to tickets in your bug tracker, this can make code show up on the wrong ticket, or not at all, which is quite confusing for a later maintainer.
I use it all the time to fix typos, add a file I forgot to add, or whatever. Once you push, it is more difficult, but I try not to push my code until it works. I also commit only tested chunks of code, so that is the "unit of work" I aim for.
The equivalent in git is something stupid, I have to look it up every time: git reset --soft HEAD^
That's intuitive!
And if you really forget it often, add this to your ~/.gitconfig:
Now you can run `git rollback`The fact that I have to make aliases for commonly used tasks is not a point in git's favor to me.
The point is that you can make just about any workflow with git. The ones that git users less commonly use may not be have easy toplevel commands. People already complain about how many toplevel commands there are with git.
Because:
a) It's not a stable branch. It's my dev branch on my local box that nobody else can see.
b) I feel like it and there's no penalty. I can go back if something is wrong.
c) The next thing I'm going to do is risky. I should save where I am just in case I'm wrong.
> Why would you want to eliminate a state where you made something that worked?
Because it may not be meaningful and it may not work. In the above case, what value do you gain from the three revisions of that change that were incorrect? When it hit code review, there were problems with it. We fixed them. Why would you publish code that is known to be incorrect (since we figured that out during code review)?
> I don't see the appeal in modifying history.
I don't see the appeal in a history full of "Oops, I forgot to add this file to the last commit," and "build fix" and "The author wrote this on Solaris, but I need a small change in the Makefile for Linux."
If there's one logical change, having several commits where you just didn't get it right only adds confusion.
> If you just need to save some partially working state, etc. you can use patch queues- They make much more sense here.
Are you saying that because that's the tool you were offered or because you actually believe it's the best way to do things?
I used mercurial very extensively before I started using git (which I have also used very extensively). Most of my time was spent in mq capturing state of work in progress. That really sucked.
Now, I just commit whenever I feel like it, and then before I publish code, I update the commit messages, squash distinct changes that represent a single logical change that shouldn't be broken up, break up commits that represent more than one logical change that shouldn't be lumped together and just generally tidy things up so the reviewers and future developers tracking back bugs can make sense of things.
Then I test it: http://dustin.github.com/2010/03/28/git-test-sequence.html
a and b are not really reasons /to/ commit a broken state. On c: If the next thing you're going to do is dangerous, I'd say it's a separate "thing" and either 1) commit the stuff you have in a working state or 2) shelve/stash/qimport it if it's not done and you need to do the dangerous work first, which is why I mentioned patch queues.
Thus, purposeful broken commits are eliminated.
> I don't see the appeal in a history full of "Oops, I forgot to add this file to the last commit," and "build fix" and "The author wrote this on Solaris, but I need a small change in the Makefile for Linux."
hg rollback/backout are intended for "oops, I forgot to add this file to the last commit." There's no need to leave those commits in, unless the problem isn't discovered for a while, which is when modifying history makes sense.
Patch queues are most definitely not just "the tool I was offered." They are a rather powerful way to deal with commits as a stack, and I've never been bogged down "capturing state of work in progress."
---
There's nothing really wrong with git's workflow, but there's nothing wrong with mercurial's either. That's all I'm saying - "it is a difference in philosophy and interface that discourages modifying history" that I happen to prefer.
What about general edits in your editor? If it's important enough to have been typed so undo in my editor works, it's important enough to be part of the project history so someone else can see my typos when they're (as I've heard used as an argument for why you should never squash commits) tracking down a bug they can figure out the train of thought that led to that work?
EDIT: I am not making a value judgment here. It's harder to learn to fly a plane than drive a car, but that hardly makes the car better than the plane or vice-versa. It's just a recognition that their learning curves aren't identical.
i also use bitbucket and since having been bought by atlassian, was able to get lots of free private repositories. i think some people mentioned that they accidentally left cookie secrets in their code on a public github project.
i'm still too early in development to get into the perceived branching woes that others are talking about, but i'll let you know when i get there.
Say you have a repository, fix a few bugs on it, and now you want to work on a crazy feature. What you need is a short lived local branch, because you don't know if crazy feature even makes sense. Unfortunately, there is no built in way to do this in hg. [1] Deleting a branch is not a fundamental concept in hg, and so the advice is to create a new local "clone" of the entire repo. [2] Great, now you have to change the config files for your dev environment to point to a new folder just so you can test out crazy feature. Also, by default all your branches get pushed (although hg will complain about creating remote branches).
In practice, all this turned "branching" into an expensive concept in my mind. That's bad, very bad.
I still prefer the hg elegance and ui to git -- even the output of "hg st" vs "git status" tells a great deal about the philosophy behind both. However, I think hg got branching wrong and that is a fundamental flaw that no amount of elegance at the UI level can compensate for.
I remember when I was making my first choice between hg and git and the advice was "they're pretty much the same, pick one." I think that advice is incorrect based on what I've said above.
[1] http://mercurial.selenic.com/wiki/LocalbranchExtension [2] http://mercurial.selenic.com/wiki/PruningDeadBranches
If these short-lived branch will be merged back shortly. Bookmark is another alternatives.
[1] http://mercurial.selenic.com/wiki/MqExtension [2] http://mercurial.selenic.com/wiki/BookmarksExtension
As the result, in hg, you have to decide in advance "what kind of branch" it will be -- or you have to get in the habit of using mq's for everything -- and this just not a natural experience especially for a DVCS where branching is just fundamental.
git stash is another thing I really like about git. There are hg alternatives but they are not as easy to use (and if you go the mq route things become so complicated you might as well just use git).