Also, I'd still recommend using git or mercurial over svn, even for a single developer. For one, you can use both offline and they are much, much faster than svn, but also, and I'm just gonna repeat myself here - branching and merging is far superior. See the above quote...
"Before I begin explaining this, which is actually my favorite feature of Git, I need you to do me a favor. Forget everthing you know about branches. Your knowledge of what a ‘branch’ means in Subversion is poisonous, especially if you internalized it pre-1.5, like I did, before Subversion finally grew some basic merge tracking capabilities. Forget how painful it was to merge, forget how long it took to switch branches, forget how impossible it was to merge from a branch more than once – Git gives you a whole new world when it comes to branching and merging.
In Git, branches are not a dirty word – they are used often and merged often, in many cases developers will create one for each feature they are working on and merge between them possibly multiple times a day, and it’s generally painless. This is what hooked me on Git in the first place, and in fact has changed the entire way I approach my development.
When you create a branch in Git, it does so locally and it happens very fast. Here is an example of creating a branch and then switching to your new branch to start doing development.
$ time git branch myidea real 0m0.009s user 0m0.002s sys 0m0.005s $ time git checkout myidea Switched to branch "myidea" real 0m0.298s user 0m0.004s sys 0m0.017s
It took about a third of a second for both commands together. Think for a second about the equivalent in Subversion – running a `copy` and then a `switch`
$ time svn copy -m 'my idea' real 0m5.172s user 0m0.033s sys 0m0.016s $ time svn switch real 0m8.404s user 0m0.153s sys 0m0.835s
Now the difference between 1/3 of a second and 13 seconds (not to mention the time it takes to remember each long URL) may not seem huge at first, but there is a significant psychological difference there. Add to that the fact that your network speed, server load and connectivity status are all factors in Subversion, where it always takes 1/3 of a second in Git and that makes a pretty big difference. Also, branching is considered a fast operation in Subversion – you will see even more pronounced speed differences in other common operations like log and diff.
However, that is not the real power of Git branches. The real power is how you use them, the raw speed and ease of the commands just makes it more likely that you will. In Git, a common use case is to create a new local branch for everything you work on. Each feature, each idea, each bugfix – you can easily create a new branch quickly, do a few commits on that branch and then either merge it into your mainline work or throw it away. You don’t have to mess up the mainline just to save your experimental ideas, you don’t have to be online to do it and most importantly, you can context switch almost instantly.
Now, once you have work on a couple of branches, what about merging? If you’re from the world of Subversion, you may cringe at that word, ‘merge’. Since Git records your commit history as a directed graph of commits, it’s generally easy for it to automatically figure out the best merge base to do a 3 way merge with. Most Subversion users are used to having to figure that out manually, which is an error prone and time consuming process – Git makes it trivial. Furthermore, you can merge from the same branch multiple times and not have to resolve the same conflicts over and over again. I often do dozens of merges a day on certain Git projects of mine and rarely have even trivial merge conflicts – certainly nothing that isn’t predictable. Raise your hand if you’ve ever done a dozen branch merges on a Subversion project at least once a week and didn’t end each day by drinking heavily.
As an anecdotal case study, take my Pro Git book. I put the Markdown source of the book on GitHub, the social code hosting site that I work for. Within a few days, I started getting dozens of people forking my project and contributing
copy edits, errata fixes and even translations. In Git, each of these forks is treated as a branch which I could pull down and merge individually. I spend a few minutes once or twice a week to pull down all the work that has happened, inspect each branch and merge the approved ones into my mainline.
network graph Why You Should Switch from Subversion to Git
As of the time of writing this article, I’ve done 34 merges in about 2 weeks – I sit down in the morning and merge in all the branches that look good. As an example, during the last merge session I inspected and merged 5 seperate branches in 13 minutes. Once again, I will leave it as an exercise to the reader to contemplate how that would have gone in Subversion.
Becoming a Code Artist
You get home on Friday after a long week of working. While sitting in your bean bag chair drinking a beer and eating Cheetos you have a mind blowing idea. So, you whip out your laptop and proceed to work on your great idea the entire weekend, touching half the files in your project and making the entire thing 87 times more amazing. Now you get into work and connect to the VPN and can finally commit. The question now is what do you do? One great big honking commit? What are your other options?
In Git, this is not a problem. Git has a feature that is pretty unique called a “staging area”, meaning you can craft each commit at the very last minute, making it easy to turn your weekend of frenzied work into a series of well thought out, logically separate changesets. If you’ve edited a bunch of files and you want to create several commits of just a few files each, you simply have to stage just the ones you want before you commit and repeat that a few times.
$ git add file1.c file2.c file3.c $ git commit -m 'files 1-3 for feature A' $ git add file4.c file5.c file6.c $ git commit -m 'files 4-6 for feature B'
This allows other people trying to figure out what you’ve done to more easily peer-review your work. If you’ve changed three logically different things in your project, you can commit them as three different reviewable changesets as late as possible.
Not only that, which is pretty powerful in itself, but Git also makes it easy to stage parts of files. This is a feature that has prevented coworkercide in my professional past. If someone has changed 100 lines of a file, where 96 of them were whitespace and comment formatting modifications, while the remaining 4 were significant business logic changes, peer-reviewing that if committed as one change is a nightmare. Being able to stage the whitespace changes in one commit with an appropriate message, then staging and committing the business logic changes seperately is a life saver (literally, it may save your life from your peers). To do this, you can use Git’s patch staging feature that asks you if you want to stage the changes to a file one hunk at a time (git add -p).
These tools allow you to craft your commits to be easily reviewable, cherry-pickable, logically seperate changes to your project. The advantages to thinking of your project history this way and having the tools to easily maintain that discipline without having to carefully plan out every commit more than a few seconds before you need to create them gives you a freedom and flexibility that is very empowering.
In Subversion the only real way to accomplish the same thing is with a complicated system of diffing to temporary files, reverting and partially applying those temporary files again. Raise your hand if you’ve ever actually taken the time to do that and if you would consider the process ‘easy’ in any way. Git users often do this type of operation on a daily basis and you need nothing outside of Git itself to accomplish it."