Would any of this transfer to understanding how git works as well? Alternatively, is there a similar introduction to git? I'm in the camp of someone who has used CVS and Subversion a lot and have had "learn Git" or some other distributed VCS on my to do list for a while now.
Cheap local branching: mercurial has had this since day one, and for a long time has had most of the capabilities mentioned in this section for a while. Unfortunately, it hasn't had good named branching support, so most mercurial users preferred to branch through cloning, but that was never necessary. Right now you can use bookmarks for temporary named branches but there's no built-in support for sharing them. You have to write your own extensions to copy bookmarks files around automatically or just do it manually. Mercurial really needs to deal with this, I think. It's the only feature I've seen in git that I wish mercurial had.
Staging area: mercurial has mq, which is far more powerful than a staging area. In all honesty, I only use mq as a staging area and ignore it's other features most of the time, and using mq only as a staging area is just as easy as using git's staging area. Also, not having a staging area forced on the user by default makes mercurial much easier to pick up than git initially, and later on if a user wants the same functionality he or she can get it.
github: Mercurial has bitbucket. Github is far more popular, but not necessarily technically superior as far as I know.
That puts mercurial almost entirely on par with git in terms of this web site's criteria.
edit: reading more carefully, http://whygitisbetterthanx.com/ doesn't actually claim mercurial doesn't have the features mentioned above. It does just claim that git does things better. They say their local branching is better(it is) and github's social atmosphere is better than competing products(it is). However, with mq and the record extension you can do the same things as with the staging area.
Since we're discussing this, is there any equivalent to git rebase --interactive?
Coming from darcs to git (I add -p more or less exclusively), I didn't think I'd use rebase much but commit reordering/squashing has turned out to be very useful the few times I've wanted it. I know it's doable with mq, but you have to know to mq everything before the fact rather than after.
A lot will transfer over; some won't. Git does branching differently, has a kind of commit staging area called the index, and has a radically different UI than Mercurial, but the underlying concepts are all the same.
The bigger question is: if you follow this tutorial and like Mercurial, why then use Git instead?
Now that's what I call organic SEO effort for their product Klin. I think patio11 will approve! :)
EDIT: The above comment may seem negative but that's not the intention. As much as this site will help their SEO effort, I think the guide itself is awesome. I am a git user and when I was learning git, I went through similar 'examples' to understand git. I think this is the best way to learn git or hg!
EDIT: I wanted to mimic the guide for git at gitinit.com and someone has already registered it!
I have this funny feeling that Joel Spolsky probably does not need to read my blog for advice on effective software marketing. But yes, I approve. Do stuff like this. It works, it is inexpensive, it lasts forever, and your customers will love you for it.
(Though if you're doing it for narrow SEO reasons, I might consider not breaking it into its own domain. Links pointing at it won't help the product rank if the product is on a domain different than the linkbait.)
If this is advertising, I want more of it. As an SVN curmudgeon, the first part of this tutorial finally persuaded me that I really, really need to give distributed version control a fair trial. Joel pretty much nailed all my objections/complaints/whines about switching. But I also know the pain of merging all too well - a benefit that I hadn't really seen explained as persuasively before.
" But I also know the pain of merging all too well - a benefit that I hadn't really seen explained as persuasively before."
FWIW, try to give a few DVCS tools a shot before settling on one.
I was a big hg fan, and really didn't care to switch when my coworkers ganged up on me and decided that git was a better tool, but I think they were right.
The git command line leaves much t be desired; hg was far more intuitive. But I would occasionally have merging issues with hg that were just too annoying (lost or missing file changes, for example) that I haven't had with git.
But that's anecdotal, and I'm sure (if you follow enough dvcs flame/troll threads :)) you'll hear other stories about other tools. The upshot is to try a few to see which works best for your particular needs.
There are scenarios where Git reverts some changes unexpectedly and almost silently, if you don't take care. In contrast, Mercurial's strict "every merge is an explicit commit" principle saved me from a lot of problems.
Regarding the command line interface: Darcs has still the best one. Well, Darcs has some performance issues, but its interactive dialog-based command line interface is outstanding. It is years old, but neither Mecurial nor Git come even close to it.
So if you have a small project or a fast computer, you should definitely have a look at Darcs in addition to Mercurial and Git.
This I don't get. The branching/merging thing seems to be overblown to me.
The reason I'm switching is because I like the tools better, and you can be up and running with a repo in about 5 seconds. I think that's argument enough. There's less pain.
But what is so different about merging in hg/git that merging a complex change from a branch is somehow made magically trivial? I mean, the tools for handling changes might be better because they are more modern, but the whole "changeset" thing seems to be hyperbole -- all (well, any good one) VCS's track changesets, that's what those revision numbers (or collectison of rev numbers) mean. :-)
I understand where you are coming from. I used to think the same way. But once you have used git or Mercurial with their powerful branching/merging capabilities, you will never go back to anything else. Also, it's not that the tools aren't better, it's that git and Mercurial have different architecture which makes branching/merging easy and powerful. I would sincerely request you to not dismiss this 'branch/merge' phenomena. Once you understand their power, you would wonder why you ever managed to live with Subversion (or other centralized VCS).
Searching on Google, I came across this example which will show you how powerful Git really is. [warning: PDF link]
Oh the branching and merging can be big problems for some of us :-)
The difference is that hg preserves the local commits as part of the upstream commit-set. That gives it a lot of information when making decisions about merging. SVN only has two versions of the file: what's in the server and yours. There's just less information to merge intelligently.
Joel hits on this on the first page (Subversion Re-education). My understanding, as a DVCS virgin, is that you commit far more often (to your local repository) than with Subversion, and so Hg can more intelligently merge things.
My guess is that there is some intelligence that can tell that "foo missing there, and foo added here" is actually just "foo moved from there to here", unlike SVN, which attempts no such heuristics. I hope someone can correct me if I'm wrong here :)
The difference is that SVN is dumb on a profound level when it comes to diffing. It knows how to diff one file vs. another, and that works great for incremental changes all in one branch, but it doesn't keep track of revision and merge history the way more modern tools like perforce, TFS, and especially git and mercurial do.
The end result is that when you have two branches that have become even a little out of sync with each other when you try to merge them together SVN doesn't know what to do because all it can do is diff one version against the other. Imagine how this looks if you've spent a bunch of time refactoring in one branch, moving code around, deleting code, adding new code, etc. The end result is that you basically have to hand-edit each file into the final merge state you need it to be in, entirely defeating the very reason you use source control tooling in the first place. You might as well just print out all the code from each branch and get a committee to merge it all together using scissors and craft glue, it wouldn't take any longer or be any more onerous than it would be using SVN.
In contrast, more sophisticated VCSes, including hg, keep track of changesets, and they are capable of tracking those changesets as they move through different branches. When you merge in Mercurial it's able to trace through the revision history of a file in the source and target branches, find the common revision, then separately apply the diffs from the source and target branches, automatically check for conflicts (e.g. changes from both sides that touch the same blocks of code) and create a sanely merged final result which will only be flagged as a merge conflict requiring manual intervention when there's a high probability that there actually is a merge conflict. More so, the merge conflict will be presented in such a way that it's actually sensible, showing the actual conflicting changes and the resulting conflicting final versions of the file, making it fairly straightforward to resolve even in that case.
Casting this in the form of a real world example, consider a "main" branch with two dev. teams each working in their own child branches. For the most part each dev. team works on their own code within their own set of files, separate from the other team's, but there is some common code which both teams have a tendency to contribute to or change. Team A spends a bunch of time making changes in their own branch (branch A), committing as they go, then merges these changes up to main. Later team B merges their changes to main as well. Instead of running into a merge conflict nightmare that requires huge amounts of developer time be expended in sorting out the state of each and every file, the version control system sees that team B hasn't made any changes to most of the files in the repository, and most of the changes team B has made are to files that haven't been changed by anyone else, and there are only a tiny number of changes to files that had also been changed by team A's recent commits, which hadn't been merged to team B's branch before team A pushed their code up to main. However, most of those edits are to distinctly different parts of the shared files, and are automatically merged without human intervention, only a tiny handful of merges require manual intervention, a process that takes only a tiny number of people a few minutes to sort out. Some of those automated merges may, in theory, not be safe, but that is what testing is for, and the devs can still review and sanity check the merged files before committing if they like.
The ability to turn a show-stopping ordeal into a routine task can be utterly transformative to the development process. There are many big dev. shops that are reliant on dozens or perhaps hundreds of big merges (in multi-thousand file code bases) shuffling around code between various branches every day.
When you merge in Mercurial it's able to trace through the revision history of a file in the source and target branches, find the common revision, then separately apply the diffs from the source and target branches...
Originally subversion couldn't do this, but it has had merge tracking since version 1.5 (a couple of years already). You can now merge one branch into another multiple times without specifying explicitly which revisions to compare.
I have seen a number of people saying that the merge tracking in subversion still isn't as good as what's in git or mercurial, but I haven't found an explanation of the difference. Can someone elaborate, or point me to some good reading?
lallysingh and nollidge point out that in a DVCS model you tend to make more frequent commits, because committing and publishing are no longer the same action, and that having finer-grained commits makes automatic merging more likely to succeed. This seems quite plausible to me, but it's orthogonal to the problem of merge tracking (isn't it?).
Proof that Joel still has something to offer developers besides "if you were any good you'd be on StackOverflow right now". <g>
As it happens I started moving to Mercurial yesterday, how is that for luck. I think the Hg site documentation is fine, but I have to say, Joel's is more fun right out the gate. May much Google juice flow his way.
If you're intent on building from source, make sure you're running "sudo python setup.py install; sudo make install-doc". Installing with the makefile directly will place packages in /usr/local, where Python doesn't normally live under OS X.
Or if you're serious about installing Python packages, you already have a .pydistutils.cfg file specifying where you want things to install. Learning a few options to put in that file is a lifesaver.
I remember having to symlink /usr/local/lib/python2.6 to /Library/Python/2.6 so that site-packages are automatically included in $PYTHONPATH. You should also see what echo $PYTHONPATH says, and make sure site-packages is in there.
I always enjoy reading Joel's writing, regardless of whether I happen to agree with whatever he's saying. He can take on a subject as dry as comparing two version control systems, and make it enjoyable to read. Especially when he's working without an editor (his inc. stuff reads like it has been edited out of all recognizable shape.)
Compare it to the normal dry, unreadable technical writing on similar subjects and it's just night and day.
Note that the only reason Spolsky is doing this is because he bet on Mercurial a few years ago for his project http://www.fogcreek.com/Kiln/ which is Mercurial only. Unfortunately for him, git got more popular than hg so now he's promoting hg as much as possible.
I don't use windows much but msysgit is good. I was pleasantly surprised with it. The GUI is a bit fractured in terms of what it can do but the command line is competent.
For a commercial product that needs to be integrated in the windows world like kiln I would have made the same decision that Joel did. (Though I prefer git overall)
There was a recent article by Martin Fowler (http://news.ycombinator.org/item?id=1131664) suggesting that the "view now is that msysgit is good enough to make comparison with Mercurial a non-issue for Windows."
If only Windows users were hardcore UNIX users...everything would be so much easier. No GUI code, no leaking GDI objects, no Java Swing, no WxWidgets, no cross-browser bugs (curl would be the only browser), no DPI scaling issues, no DLL hell, and no IE. Just text. Beautiful, green text. And it would all be BSD licensed.
While msysgit runs okay on Windows as of fairly recently, for a very long time, Git had very bad performance on Windows, and required Cygwin. Saying that it ran fine for years is pretty bad hyperbole--especially since both Git and Mercurial are only about two years old at this point.
Yeah, except that Git is 5 years old and that the Cygwin requirement was just a dll that came _with_ the installer and was _automatically_ installed with Git. Nobody would notice except people that had an agenda against git (hg supporters, svn etc).
Edit: about performance, while Git was slower on windows than on linux, it was still faster than both SVN and Mercurial.
Interesting, I'm getting downvoted for telling the truth. Maybe I should just go with the HN flow so here it goes:
Git still doesn't work well on windows and it's damn slow and only 2 years old, also running it with cygwin was a pain because you had to install it manually and stuff. High 5 y'all!
/me disappointed by HN, expected better than reddit like users.
People don't have an agenda against git — it simply doesn't work for them. It's not the holy grail of DVCS', and neither are Hg or bzr; different tools for different people.
Where are you getting your performance results from? The footnote from Google's article[1] on choosing between Mercurial and git states that Hg was faster both over HTTP and when compared to git's wire protocol. But I'm willing to admit those numbers may be old, so is there a newer published benchmark anywhere?
Where does it say that HG http is faster than git://? And second git local operations are way faster than hg's. But google only care about http obviously. Note that android and chromium both use git on google's servers and they employed some of the core git devs so it's only a matter of time before git becomes available on google code.
IMHO too many people trash-talk Git for Windows without even knowing properly what they are talking about. For example, timing clone. WTF? Do you clone all the time? Neither do I. Measure something that you really use very often, if you do not want to be mistaken for an incompetent script kiddie.
Further, I am not exactly thrilled by the claim that it runs okay "as of fairly recently". There haven't been all that many changes over the last year. So you are obviously wrong. It is also a insult on our work, which you should be fairly ashamed of.
Ciao,
Dscho
P.S.: what kind of "Hacker News" are shown on this site when you cannot even comment using w3m? WTF?
First of all, it's better than someone pushing SVN.
Second, it's like Python vs Ruby (Hg vs Git). Doesn't matter.
Third, any attempt to fix the current issues of programming is better than "just hire a super-human-developer and leave him alone". Spolsky pushed bug tracking systems couple years ago, now he's advertising code review and better code commit/build workflow.
I like that Joel decides to say "OK, forget about Subversion or whatever you know about source control in general. I'm going to teach you about the DVCS way from the ground up." It's great that he treats this guide like an introduction to the concept of version control, but I think you really need experience with VCS before you can understand Hg Init.
Is there an easy way to educate older and/or less technical IT professionals about source control? I haven't been able to do it myself, and I wish this was it.
For IT people you should have your /etc/* files under revision control to track any changes and easily roll back changes that break your system. I actually think there are some tools that are specifically for this purpose and not the general purpose SVN/git/hg variety but I cannot think of them off the top of my head.
Kiln gets you a pretty cool (if I do say so myself) code review system, an all-new web interface for managing your code and repositories, tight integration with FogBugz, and support from Fog Creek. If you don't need those things, then by all means, use the open source version.
There's a free trial of the hosted version that you can sign up for at http://www.kilnhg.com/. Also, Kiln and FogBugz are both free for Students and Startups (2 users or less). Give it a shot and let us know what you think.
Kiln also takes care of all configuration/setup for you...and the On Demand version gets you regular off-site backups, secure data center hosting, all that good stuff.
As a kiln user, I'll back up Jason's statements here. Working with it day-to-day, it's not really any different from using the open source version of hg, but the web UI and code reviews are pretty damn cool.
It answered many of my questions on the nuances of Mercurial. The branch model, bare repositories, and command equivalence table were especially helpful for someone like myself who has used both systems but never fully understood the distinctions.
Not having used Hg much at all (just a few hg commits and an hg clone), could it be used on top of a non-distributed source control system like SVN?
E.g., take advantage of hg commit and related commands to try changes out on the local repository, and use svn to commit those changes to the central repository?
You shouldn't have much problem with that. You'd just have to make svn ignore the .hg folder in your local repository, and you can use hg locally for whatever you want, and when you're at a point that you want to push your changes to your svn central repository, you can.
Did someone also notice Kiln has a Dodo as logo? That bird went extinct in the late 17-th century (http://en.wikipedia.org/wiki/Dodo). I wonder what the meaning of this is. Maybe a pun on 'the way of the dodo', a place where your source code certainly won't go, if you use Mercurial.
We were looking for a good mascot for Kiln, but unfortunately, all of the animals that we consulted were already in exclusive contracts with other products except for Strigiphilus garylarsoni and the inverted flame-weasel, neither of which we felt represented our product well.
Late one night in the Kiln alpha period, though, I was hacking around the Mercurial integration, messed up, and suddenly realized that issuing "hg up" held the repository at its current version, but moved time itself to match the requested revision. In other words, I had unintentionally made a time machine out of Mercurial. After riding a dinosaur for awhile, it hit me that I suddenly had a chance to get Kiln a legitimate mascot.
I thought for awhile about where and when to go, then promptly "hg up"d to the mid 1600s. I went to the island of Mauritius, and approached the dodo bird. I explained that, through no fault of the poor bird, it was about to go extinct. But I had an option: I could "hg revert" the thing back into the present, restoring it from extinction, if only it'd be willing to sign an exclusive marketing contract for Kiln. We negotiated a little bit back and forth, but at the end of the day, as you can see, the dodo happily agreed. It now lives a life of luxury, and has even taken up recently to hanging around kiwi birds an awful lot.
Unfortunately, the current version of Kiln can only restore deleted files, not deleted species, but we still think the dodo--a peaceful bird with no natural enemies, restored to the present--makes a nice mascot.
I've just finished the introduction part and there is one thing he got wrong. the changesets vs revisions thing. Changesets and revisions are completely equivalent as far as merging is concerned (and almost anything else) because one is trivially computed from the other. and git which has even better merging support tracks file contents not diffs, which is another proof that this argument is irrelevant.
If you speak of Mercurial's changesets and revisions, they are clearly not trivially computed from one another, being that a revision is clone-specific, and a changeset is a hash computed on a single file by looking at all it's ancestors' states. REPO1 and REPO2 can both have 5 revisions and only one is common to both — a merge is possible, but the changesets considered will be very different.
If you're comparing SVN's revisions with Hg's changesets, still no dice, for the same reason: changesets are unique for a file, given that file's history, and the hash trail allows for a clear way to figure out where changes happened, and merge from that point. A SVN revision just tells you how many commits have happened up to that point.
I find the choice of characters and the paragraph descriptions of them a little strange. I get the point that it helps the story to make up a whole life story for each member of the hypothetical development team. What I don't understand is why each team member is portrayed in such a negative light. Are your co-workers that bad?
I'm generally not a big fan of Spolsky's writing. He tends to read too much like a sales person, and too little like an engineer for me to enjoy his writing.
This is a great read though, even if you already switched to git, because the two are so similar.
OK I just finished the first block (Subversion Reeducation) and one of the main points he makes is In Mercurial, every developer has their own repository, living on their desktop
But if you read the subversion book, or any other good tutorials, you know that developers using svn can just as well make their own private branches
So under branches/ I can have bob/ sue/ alice/ and they can have copies of trunk (or other branches) to their hearts content.
It's a win for DVCS in general, not just Hg. A couple of use cases off the top of my head:
* I can take my repository on the train/bus/wherever and still commit.
* If I'm working with someone who needs to use my 'buggy' code I can push just to their repository (or they can pull from mine).
* I can have my own workflow and create as many branches, checkouts, etc. as I need.
Of course, the example that he gives there is bizarre - effectively the Hg equivalent of hanging onto your code for 6 weeks and then merging all at once...
2 and 3 are easily done in SVN also. 2 is basically merging your changes in personal branch to the personal branch of another user. 3. Well your branch in SVN is your domain, do what you want.
I think the main advantage is really for larger groups. Having 3000 branches in the linux repo would be unmanageable. Also, private branches are something SVN can't do to my knowledge. If I want to hack on a git repo without anyone knowing, it's easy.
But there's many advantages to GIT/Mercurial over SVN/* aside from the "everyone has a repo". I love git but currently use SVN due to legacy and keyword expansion at work and it's not that bad.
Here is how I (try) and explain it to my coworkers when they say "svn branches as well".
You are right. Svn can branch. Can. But branching in svn is always a dangerous proposition. There are a lot of mechanics involved with branching it right initially, making sure that branch is properly tracking Trunk (you have to constantly merge from Trunk down into the branch to hedge the bets on eventually merging that branch back into Trunk). Properly merging a big branch into Trunk is also an undertaking, and more importantly, it requires the whole team to know its happening and "Be careful checking stuff in for I AM MERGING".
Also branches in svn aren't private. Anyone can see them. They are private by convention sure.
So compare all that workflow with a DVCS. The branching is free. It happens all the time and you never notice it. The merging is smarter, because it has to be, and the history is more complete, because it has to be to enable the merging.
When you do consciously branch it's a quicker, more robust operation. Doing big scary feature branch merges isn't as scary since they're happening privately before you push back to the (culturally defined) central repo. Yes you still have to merge from "trunk" to branch in DVCS but, again, it's a baked in feature since thats how you pull changes from someone else (for example in git you fetch changes from the central repo into remotes/master and then merge them into your master. Same operation as merging master into feature branch, or branch into master).
Yes you can walk to San Francisco from New York. But you can also Fly.
That's the end of my rant. Obviously it's based on my experiences with these tools and not yours. Just trying to give some context and justification.
You're ignoring the "living on their desktop" part.
Sure, you can make "private" branches (not actually private) with SVN, but they're still on the server. That means:
1. You can't commit to them (or check out from them) when you're offline.
2. Commits, checkouts, diffs against older revisions, etc are slower when you are online.
3. Bisecting would be painful because of point 2.
4. You can't make a bunch of commits and fold/reorder them with something like the HistEdit extension because someone may have seen them.
79 comments
[ 3.4 ms ] story [ 143 ms ] threadCheap local branching: mercurial has had this since day one, and for a long time has had most of the capabilities mentioned in this section for a while. Unfortunately, it hasn't had good named branching support, so most mercurial users preferred to branch through cloning, but that was never necessary. Right now you can use bookmarks for temporary named branches but there's no built-in support for sharing them. You have to write your own extensions to copy bookmarks files around automatically or just do it manually. Mercurial really needs to deal with this, I think. It's the only feature I've seen in git that I wish mercurial had.
Staging area: mercurial has mq, which is far more powerful than a staging area. In all honesty, I only use mq as a staging area and ignore it's other features most of the time, and using mq only as a staging area is just as easy as using git's staging area. Also, not having a staging area forced on the user by default makes mercurial much easier to pick up than git initially, and later on if a user wants the same functionality he or she can get it.
github: Mercurial has bitbucket. Github is far more popular, but not necessarily technically superior as far as I know.
That puts mercurial almost entirely on par with git in terms of this web site's criteria.
edit: reading more carefully, http://whygitisbetterthanx.com/ doesn't actually claim mercurial doesn't have the features mentioned above. It does just claim that git does things better. They say their local branching is better(it is) and github's social atmosphere is better than competing products(it is). However, with mq and the record extension you can do the same things as with the staging area.
Coming from darcs to git (I add -p more or less exclusively), I didn't think I'd use rebase much but commit reordering/squashing has turned out to be very useful the few times I've wanted it. I know it's doable with mq, but you have to know to mq everything before the fact rather than after.
Another great resource is the official Git User Manual, which I didn't know existed until just the other day: http://www.kernel.org/pub/software/scm/git/docs/user-manual....
I am brand new to git and I've been pleasantly surprised at both how thorough and also how newbie-friendly the User Manual is.
The bigger question is: if you follow this tutorial and like Mercurial, why then use Git instead?
http://tekpub.com/preview/git
Haven't purchased it yet myself, but been meaning to.
http://www.pragprog.com/screencasts/v-jwsceasy/source-contro...
EDIT: The above comment may seem negative but that's not the intention. As much as this site will help their SEO effort, I think the guide itself is awesome. I am a git user and when I was learning git, I went through similar 'examples' to understand git. I think this is the best way to learn git or hg!
EDIT: I wanted to mimic the guide for git at gitinit.com and someone has already registered it!
(Though if you're doing it for narrow SEO reasons, I might consider not breaking it into its own domain. Links pointing at it won't help the product rank if the product is on a domain different than the linkbait.)
FWIW, try to give a few DVCS tools a shot before settling on one.
I was a big hg fan, and really didn't care to switch when my coworkers ganged up on me and decided that git was a better tool, but I think they were right.
The git command line leaves much t be desired; hg was far more intuitive. But I would occasionally have merging issues with hg that were just too annoying (lost or missing file changes, for example) that I haven't had with git.
But that's anecdotal, and I'm sure (if you follow enough dvcs flame/troll threads :)) you'll hear other stories about other tools. The upshot is to try a few to see which works best for your particular needs.
There are scenarios where Git reverts some changes unexpectedly and almost silently, if you don't take care. In contrast, Mercurial's strict "every merge is an explicit commit" principle saved me from a lot of problems.
Regarding the command line interface: Darcs has still the best one. Well, Darcs has some performance issues, but its interactive dialog-based command line interface is outstanding. It is years old, but neither Mecurial nor Git come even close to it.
So if you have a small project or a fast computer, you should definitely have a look at Darcs in addition to Mercurial and Git.
The reason I'm switching is because I like the tools better, and you can be up and running with a repo in about 5 seconds. I think that's argument enough. There's less pain.
But what is so different about merging in hg/git that merging a complex change from a branch is somehow made magically trivial? I mean, the tools for handling changes might be better because they are more modern, but the whole "changeset" thing seems to be hyperbole -- all (well, any good one) VCS's track changesets, that's what those revision numbers (or collectison of rev numbers) mean. :-)
I understand where you are coming from. I used to think the same way. But once you have used git or Mercurial with their powerful branching/merging capabilities, you will never go back to anything else. Also, it's not that the tools aren't better, it's that git and Mercurial have different architecture which makes branching/merging easy and powerful. I would sincerely request you to not dismiss this 'branch/merge' phenomena. Once you understand their power, you would wonder why you ever managed to live with Subversion (or other centralized VCS).
Searching on Google, I came across this example which will show you how powerful Git really is. [warning: PDF link]
http://ietl.univ-lyon2.fr/sites/ietl/IMG/pdf/Git_merging_by_...
The difference is that hg preserves the local commits as part of the upstream commit-set. That gives it a lot of information when making decisions about merging. SVN only has two versions of the file: what's in the server and yours. There's just less information to merge intelligently.
My guess is that there is some intelligence that can tell that "foo missing there, and foo added here" is actually just "foo moved from there to here", unlike SVN, which attempts no such heuristics. I hope someone can correct me if I'm wrong here :)
The end result is that when you have two branches that have become even a little out of sync with each other when you try to merge them together SVN doesn't know what to do because all it can do is diff one version against the other. Imagine how this looks if you've spent a bunch of time refactoring in one branch, moving code around, deleting code, adding new code, etc. The end result is that you basically have to hand-edit each file into the final merge state you need it to be in, entirely defeating the very reason you use source control tooling in the first place. You might as well just print out all the code from each branch and get a committee to merge it all together using scissors and craft glue, it wouldn't take any longer or be any more onerous than it would be using SVN.
In contrast, more sophisticated VCSes, including hg, keep track of changesets, and they are capable of tracking those changesets as they move through different branches. When you merge in Mercurial it's able to trace through the revision history of a file in the source and target branches, find the common revision, then separately apply the diffs from the source and target branches, automatically check for conflicts (e.g. changes from both sides that touch the same blocks of code) and create a sanely merged final result which will only be flagged as a merge conflict requiring manual intervention when there's a high probability that there actually is a merge conflict. More so, the merge conflict will be presented in such a way that it's actually sensible, showing the actual conflicting changes and the resulting conflicting final versions of the file, making it fairly straightforward to resolve even in that case.
Casting this in the form of a real world example, consider a "main" branch with two dev. teams each working in their own child branches. For the most part each dev. team works on their own code within their own set of files, separate from the other team's, but there is some common code which both teams have a tendency to contribute to or change. Team A spends a bunch of time making changes in their own branch (branch A), committing as they go, then merges these changes up to main. Later team B merges their changes to main as well. Instead of running into a merge conflict nightmare that requires huge amounts of developer time be expended in sorting out the state of each and every file, the version control system sees that team B hasn't made any changes to most of the files in the repository, and most of the changes team B has made are to files that haven't been changed by anyone else, and there are only a tiny number of changes to files that had also been changed by team A's recent commits, which hadn't been merged to team B's branch before team A pushed their code up to main. However, most of those edits are to distinctly different parts of the shared files, and are automatically merged without human intervention, only a tiny handful of merges require manual intervention, a process that takes only a tiny number of people a few minutes to sort out. Some of those automated merges may, in theory, not be safe, but that is what testing is for, and the devs can still review and sanity check the merged files before committing if they like.
The ability to turn a show-stopping ordeal into a routine task can be utterly transformative to the development process. There are many big dev. shops that are reliant on dozens or perhaps hundreds of big merges (in multi-thousand file code bases) shuffling around code between various branches every day.
Originally subversion couldn't do this, but it has had merge tracking since version 1.5 (a couple of years already). You can now merge one branch into another multiple times without specifying explicitly which revisions to compare.
I have seen a number of people saying that the merge tracking in subversion still isn't as good as what's in git or mercurial, but I haven't found an explanation of the difference. Can someone elaborate, or point me to some good reading?
lallysingh and nollidge point out that in a DVCS model you tend to make more frequent commits, because committing and publishing are no longer the same action, and that having finer-grained commits makes automatic merging more likely to succeed. This seems quite plausible to me, but it's orthogonal to the problem of merge tracking (isn't it?).
As it happens I started moving to Mercurial yesterday, how is that for luck. I think the Hg site documentation is fine, but I have to say, Joel's is more fun right out the gate. May much Google juice flow his way.
http://mercurial.berkwood.com/
If you're intent on building from source, make sure you're running "sudo python setup.py install; sudo make install-doc". Installing with the makefile directly will place packages in /usr/local, where Python doesn't normally live under OS X.
For reference, mine is:
/usr/local/lib/python2.6/site-packages/:/System/Library/Frameworks/Python.framework/Versions/Current/lib/:
Compare it to the normal dry, unreadable technical writing on similar subjects and it's just night and day.
For a commercial product that needs to be integrated in the windows world like kiln I would have made the same decision that Joel did. (Though I prefer git overall)
(edit change link to the YCombinator discussion)
Oh, what a wonderful world that would be...
Edit: about performance, while Git was slower on windows than on linux, it was still faster than both SVN and Mercurial.
Git still doesn't work well on windows and it's damn slow and only 2 years old, also running it with cygwin was a pain because you had to install it manually and stuff. High 5 y'all!
/me disappointed by HN, expected better than reddit like users.
Where are you getting your performance results from? The footnote from Google's article[1] on choosing between Mercurial and git states that Hg was faster both over HTTP and when compared to git's wire protocol. But I'm willing to admit those numbers may be old, so is there a newer published benchmark anywhere?
[1]: http://code.google.com/p/support/wiki/DVCSAnalysis
Again though, I was curious if you had some numbers. I'm not here to argue which is better, because, really, it's a subjective argument.
Further, I am not exactly thrilled by the claim that it runs okay "as of fairly recently". There haven't been all that many changes over the last year. So you are obviously wrong. It is also a insult on our work, which you should be fairly ashamed of.
Ciao, Dscho
P.S.: what kind of "Hacker News" are shown on this site when you cannot even comment using w3m? WTF?
Second, it's like Python vs Ruby (Hg vs Git). Doesn't matter.
Third, any attempt to fix the current issues of programming is better than "just hire a super-human-developer and leave him alone". Spolsky pushed bug tracking systems couple years ago, now he's advertising code review and better code commit/build workflow.
Is there an easy way to educate older and/or less technical IT professionals about source control? I haven't been able to do it myself, and I wish this was it.
http://betterexplained.com/articles/a-visual-guide-to-versio...
For IT people you should have your /etc/* files under revision control to track any changes and easily roll back changes that break your system. I actually think there are some tools that are specifically for this purpose and not the general purpose SVN/git/hg variety but I cannot think of them off the top of my head.
There's a free trial of the hosted version that you can sign up for at http://www.kilnhg.com/. Also, Kiln and FogBugz are both free for Students and Startups (2 users or less). Give it a shot and let us know what you think.
http://mercurial.selenic.com/wiki/GitConcepts
It answered many of my questions on the nuances of Mercurial. The branch model, bare repositories, and command equivalence table were especially helpful for someone like myself who has used both systems but never fully understood the distinctions.
E.g., take advantage of hg commit and related commands to try changes out on the local repository, and use svn to commit those changes to the central repository?
Late one night in the Kiln alpha period, though, I was hacking around the Mercurial integration, messed up, and suddenly realized that issuing "hg up" held the repository at its current version, but moved time itself to match the requested revision. In other words, I had unintentionally made a time machine out of Mercurial. After riding a dinosaur for awhile, it hit me that I suddenly had a chance to get Kiln a legitimate mascot.
I thought for awhile about where and when to go, then promptly "hg up"d to the mid 1600s. I went to the island of Mauritius, and approached the dodo bird. I explained that, through no fault of the poor bird, it was about to go extinct. But I had an option: I could "hg revert" the thing back into the present, restoring it from extinction, if only it'd be willing to sign an exclusive marketing contract for Kiln. We negotiated a little bit back and forth, but at the end of the day, as you can see, the dodo happily agreed. It now lives a life of luxury, and has even taken up recently to hanging around kiwi birds an awful lot.
Unfortunately, the current version of Kiln can only restore deleted files, not deleted species, but we still think the dodo--a peaceful bird with no natural enemies, restored to the present--makes a nice mascot.
If you're comparing SVN's revisions with Hg's changesets, still no dice, for the same reason: changesets are unique for a file, given that file's history, and the hash trail allows for a clear way to figure out where changes happened, and merge from that point. A SVN revision just tells you how many commits have happened up to that point.
This is a great read though, even if you already switched to git, because the two are so similar.
But if you read the subversion book, or any other good tutorials, you know that developers using svn can just as well make their own private branches
So under branches/ I can have bob/ sue/ alice/ and they can have copies of trunk (or other branches) to their hearts content.
So why is this a big "win" for Mercurial?
(Will read the other sections later, no time now)
* I can take my repository on the train/bus/wherever and still commit.
* If I'm working with someone who needs to use my 'buggy' code I can push just to their repository (or they can pull from mine).
* I can have my own workflow and create as many branches, checkouts, etc. as I need.
Of course, the example that he gives there is bizarre - effectively the Hg equivalent of hanging onto your code for 6 weeks and then merging all at once...
I think the main advantage is really for larger groups. Having 3000 branches in the linux repo would be unmanageable. Also, private branches are something SVN can't do to my knowledge. If I want to hack on a git repo without anyone knowing, it's easy.
But there's many advantages to GIT/Mercurial over SVN/* aside from the "everyone has a repo". I love git but currently use SVN due to legacy and keyword expansion at work and it's not that bad.
You are right. Svn can branch. Can. But branching in svn is always a dangerous proposition. There are a lot of mechanics involved with branching it right initially, making sure that branch is properly tracking Trunk (you have to constantly merge from Trunk down into the branch to hedge the bets on eventually merging that branch back into Trunk). Properly merging a big branch into Trunk is also an undertaking, and more importantly, it requires the whole team to know its happening and "Be careful checking stuff in for I AM MERGING".
Also branches in svn aren't private. Anyone can see them. They are private by convention sure.
So compare all that workflow with a DVCS. The branching is free. It happens all the time and you never notice it. The merging is smarter, because it has to be, and the history is more complete, because it has to be to enable the merging.
When you do consciously branch it's a quicker, more robust operation. Doing big scary feature branch merges isn't as scary since they're happening privately before you push back to the (culturally defined) central repo. Yes you still have to merge from "trunk" to branch in DVCS but, again, it's a baked in feature since thats how you pull changes from someone else (for example in git you fetch changes from the central repo into remotes/master and then merge them into your master. Same operation as merging master into feature branch, or branch into master).
Yes you can walk to San Francisco from New York. But you can also Fly.
That's the end of my rant. Obviously it's based on my experiences with these tools and not yours. Just trying to give some context and justification.
Sure, you can make "private" branches (not actually private) with SVN, but they're still on the server. That means:
1. You can't commit to them (or check out from them) when you're offline. 2. Commits, checkouts, diffs against older revisions, etc are slower when you are online. 3. Bisecting would be painful because of point 2. 4. You can't make a bunch of commits and fold/reorder them with something like the HistEdit extension because someone may have seen them.