Why is Git better than Subversion?

Viewed 918586

I've been using Subversion for a few years and after using SourceSafe, I just love Subversion. Combined with TortoiseSVN, I can't really imagine how it could be any better.

Yet there's a growing number of developers claiming that Subversion has problems and that we should be moving to the new breed of distributed version control systems, such as Git.

How does Git improve upon Subversion?

30 Answers

Git is not better than Subversion. But is also not worse. It's different.

The key difference is that it is decentralized. Imagine you are a developer on the road, you develop on your laptop and you want to have source control so that you can go back 3 hours.

With Subversion, you have a Problem: The SVN Repository may be in a location you can't reach (in your company, and you don't have internet at the moment), you cannot commit. If you want to make a copy of your code, you have to literally copy/paste it.

With Git, you do not have this problem. Your local copy is a repository, and you can commit to it and get all benefits of source control. When you regain connectivity to the main repository, you can commit against it.

This looks good at first, but just keep in mind the added complexity to this approach.

Git seems to be the "new, shiny, cool" thing. It's by no means bad (there is a reason Linus wrote it for the Linux Kernel development after all), but I feel that many people jump on the "Distributed Source Control" train just because it's new and is written by Linus Torvalds, without actually knowing why/if it's better.

Subversion has Problems, but so does Git, Mercurial, CVS, TFS or whatever.

Edit: So this answer is now a year old and still generates many upvotes, so I thought I'll add some more explanations. In the last year since writing this, Git has gained a lot of momentum and support, particularly since sites like GitHub really took off. I'm using both Git and Subversion nowadays and I'd like to share some personal insight.

First of all, Git can be really confusing at first when working decentralized. What is a remote? and How to properly set up the initial repository? are two questions that come up at the beginning, especially compared to SVN's simple "svnadmin create", Git's "git init" can take the parameters --bare and --shared which seems to be the "proper" way to set up a centralized repository. There are reasons for this, but it adds complexity. The documentation of the "checkout" command is very confusing to people changing over - the "proper" way seems to be "git clone", while "git checkout" seems to switch branches.

Git REALLY shines when you are decentralized. I have a server at home and a Laptop on the road, and SVN simply doesn't work well here. With SVN, I can't have local source control if I'm not connected to the repository (Yes, I know about SVK or about ways to copy the repo). With Git, that's the default mode anyway. It's an extra command though (git commit commits locally, whereas git push origin master pushes the master branch to the remote named "origin").

As said above: Git adds complexity. Two modes of creating repositories, checkout vs. clone, commit vs. push... You have to know which commands work locally and which work with "the server" (I'm assuming most people still like a central "master-repository").

Also, the tooling is still insufficient, at least on Windows. Yes, there is a Visual Studio AddIn, but I still use git bash with msysgit.

SVN has the advantage that it's MUCH simpler to learn: There is your repository, all changes to towards it, if you know how to create, commit and checkout and you're ready to go and can pickup stuff like branching, update etc. later on.

Git has the advantage that it's MUCH better suited if some developers are not always connected to the master repository. Also, it's much faster than SVN. And from what I hear, branching and merging support is a lot better (which is to be expected, as these are the core reasons it was written).

This also explains why it gains so much buzz on the Internet, as Git is perfectly suited for Open Source projects: Just Fork it, commit your changes to your own Fork, and then ask the original project maintainer to pull your changes. With Git, this just works. Really, try it on Github, it's magic.

What I also see are Git-SVN Bridges: The central repository is a Subversion repo, but developers locally work with Git and the bridge then pushes their changes to SVN.

But even with this lengthy addition, I still stand by my core message: Git is not better or worse, it's just different. If you have the need for "Offline Source Control" and the willingness to spend some extra time learning it, it's fantastic. But if you have a strictly centralized Source Control and/or are struggling to introduce Source Control in the first place because your co-workers are not interested, then the simplicity and excellent tooling (at least on Windows) of SVN shine.

With Git, you can do practically anything offline, because everybody has their own repository.

Making branches and merging between branches is really easy.

Even if you don't have commit rights for a project, you can still have your own repository online, and publish "push requests" for your patches. Everybody who likes your patches can pull them into their project, including the official maintainers.

It's trivial to fork a project, modify it, and still keep merging in the bugfixes from the HEAD branch.

Git works for the Linux kernel developers. That means it is really fast (it has to be), and scales to thousands of contributors. Git also uses less space (up to 30 times less space for the Mozilla repository).

Git is very flexible, very TIMTOWTDI (There is more than one way to do it). You can use whatever workflow you want, and Git will support it.

Finally, there's GitHub, a great site for hosting your Git repositories.

Drawbacks of Git:

  • it's much harder to learn, because Git has more concepts and more commands.
  • revisions don't have version numbers like in subversion
  • many Git commands are cryptic, and error messages are very user-unfriendly
  • it lacks a good GUI (such as the great TortoiseSVN)

Other answers have done a good job of explaining the core features of Git (which are great). But there's also so many little ways that Git behaves better and helps keep my life more sane. Here are some of the little things:

  1. Git has a 'clean' command. SVN desperately needs this command, considering how frequently it will dump extra files on your disk.
  2. Git has the 'bisect' command. It's nice.
  3. SVN creates .svn directories in every single folder (Git only creates one .git directory). Every script you write, and every grep you do, will need to be written to ignore these .svn directories. You also need an entire command ("svn export") just to get a sane copy of your files.
  4. In SVN, each file & folder can come from a different revision or branch. At first, it sounds nice to have this freedom. But what this actually means is that there is a million different ways for your local checkout to be completely screwed up. (for example, if "svn switch" fails halfway through, or if you enter a command wrong). And the worst part is: if you ever get into a situation where some of your files are coming from one place, and some of them from another, the "svn status" will tell you that everything is normal. You'll need to do "svn info" on each file/directory to discover how weird things are. If "git status" tells you that things are normal, then you can trust that things really are normal.
  5. You have to tell SVN whenever you move or delete something. Git will just figure it out.
  6. Ignore semantics are easier in Git. If you ignore a pattern (such as *.pyc), it will be ignored for all subdirectories. (But if you really want to ignore something for just one directory, you can). With SVN, it seems that there is no easy way to ignore a pattern across all subdirectories.
  7. Another item involving ignore files. Git makes it possible to have "private" ignore settings (using the file .git/info/exclude), which won't affect anyone else.

"Why Git is Better than X" outlines the various pros and cons of Git vs other SCMs.

Briefly:

  • Git tracks content rather than files
  • Branches are lightweight and merging is easy, and I mean really easy.
  • It's distributed, basically every repository is a branch. It's much easier to develop concurrently and collaboratively than with Subversion, in my opinion. It also makes offline development possible.
  • It doesn't impose any workflow, as seen on the above linked website, there are many workflows possible with Git. A Subversion-style workflow is easily mimicked.
  • Git repositories are much smaller in file size than Subversion repositories. There's only one ".git" directory, as opposed to dozens of ".svn" repositories (note Subversion 1.7 and higher now uses a single directory like Git.)
  • The staging area is awesome, it allows you to see the changes you will commit, commit partial changes and do various other stuff.
  • Stashing is invaluable when you do "chaotic" development, or simply want to fix a bug while you're still working on something else (on a different branch).
  • You can rewrite history, which is great for preparing patch sets and fixing your mistakes (before you publish the commits)
  • … and a lot more.

There are some disadvantages:

  • There aren't many good GUIs for it yet. It's new and Subversion has been around for a lot longer, so this is natural as there are a few interfaces in development. Some good ones include TortoiseGit and GitHub for Mac.
  • Partial checkouts/clones of repositories are not possible at the moment (I read that it's in development). However, there is submodule support. Git 1.7+ supports sparse checkouts.
  • It might be harder to learn, even though I did not find this to be the case (about a year ago). Git has recently improved its interface and is quite user friendly.

In the most simplistic usage, Subversion and Git are pretty much the same. There isn't much difference between:

svn checkout svn://foo.com/bar bar
cd bar
# edit
svn commit -m "foo"

and

git clone git@github.com:foo/bar.git
cd bar
# edit
git commit -a -m "foo"
git push

Where Git really shines is branching and working with other people.

Well, it's distributed. Benchmarks indicate that it's considerably faster (given its distributed nature, operations like diffs and logs are all local so of course it's blazingly faster in this case), and working folders are smaller (which still blows my mind).

When you're working on subversion, or any other client/server revision control system, you essentially create working copies on your machine by checking-out revisions. This represents a snapshot in time of what the repository looks like. You update your working copy via updates, and you update the repository via commits.

With a distributed version control, you don't have a snapshot, but rather the entire codebase. Wanna do a diff with a 3 month old version? No problem, the 3 month old version is still on your computer. This doesn't only mean things are way faster, but if you're disconnected from your central server, you can still do many of the operations you're used to. In other words, you don't just have a snapshot of a given revision, but the entire codebase.

You'd think that Git would take up a bunch of space on your harddrive, but from a couple benchmarks I've seen, it actually takes less. Don't ask me how. I mean, it was built by Linus, he knows a thing or two about filesystems I guess.

The main points I like about DVCS are those :

  1. You can commit broken things. It doesn't matter because other peoples won't see them until you publish. Publish time is different of commit time.
  2. Because of this you can commit more often.
  3. You can merge complete functionnality. This functionnality will have its own branch. All commits of this branch will be related to this functionnality. You can do it with a CVCS however with DVCS its the default.
  4. You can search your history (find when a function changed )
  5. You can undo a pull if someone screw up the main repository, you don't need to fix the errors. Just clear the merge.
  6. When you need a source control in any directory do : git init . and you can commit, undoing changes, etc...
  7. It's fast (even on Windows )

The main reason for a relatively big project is the improved communication created by the point 3. Others are nice bonuses.

The funny thing is: I host projects in Subversion Repos, but access them via the Git Clone command.

Please read Develop with Git on a Google Code Project

Although Google Code natively speaks Subversion, you can easily use Git during development. Searching for "git svn" suggests this practice is widespread, and we too encourage you to experiment with it.

Using Git on a Svn Repository gives me benefits:

  1. I can work distributed on several machines, commiting and pulling from and to them
  2. I have a central backup/public svn repository for others to check out
  3. And they are free to use Git for their own

Subversion is still a much more used version control system, which means that it has better tool support. You'll find mature SVN plugins for almost any IDE, and there are good explorer extensions available (like TurtoiseSVN). Other than that, I'll have to agree with Michael: Git isn't better or worse than Subversion, it's different.

One of the things about SubVersion that irks me is that it puts its own folder in each directory of a project, whereas git only puts one in the root directory. It's not that big of a deal, but little things like that add up.

Of course, SubVersion has Tortoise, which is [usually] very nice.

Git also makes branching and merging really easy. Subversion 1.5 just added merge tracking, but Git is still better. With Git branching is very fast and cheap. It makes creating a branch for each new feature more feasible. Oh and Git repositories are very efficient with storage space as compared to Subversion.

It's all about the ease of use/steps required to do something.

If I'm developing a single project on my PC/laptop, git is better, because it is far easier to set up and use. You don't need a server, and you don't need to keep typing repository URL's in when you do merges.

If it were just 2 people, I'd say git is also easier, because you can just push and pull from eachother.

Once you get beyond that though, I'd go for subversion, because at that point you need to set up a 'dedicated' server or location.

You can do this just as well with git as with SVN, but the benefits of git get outweighed by the need to do additional steps to synch with a central server. In SVN you just commit. In git you have to git commit, then git push. The additional step gets annoying simply because you end up doing it so much.

SVN also has the benefit of better GUI tools, however the git ecosystem seems to be catching up quickly, so I wouldn't worry about this in the long term.

Easy Git has a nice page comparing actual usage of Git and SVN which will give you an idea of what things Git can do (or do more easily) compared to SVN. (Technically, this is based on Easy Git, which is a lightweight wrapper on top of Git.)

Git and DVCS in general is great for developers doing a lot of coding independently of each other because everyone has their own branch. If you need a change from someone else, though, she has to commit to her local repo and then she must push that changeset to you or you must pull it from her.

My own reasoning also makes me think DVCS makes things harder for QA and release management if you do things like centralized releases. Someone has to be responsible for doing that push/pull from everyone else's repository, resolving any conflicts that would have been resolved at initial commit time before, then doing the build, and then having all the other developers re-sync their repos.

All of this can be addressed with human processes, of course; DVCS just broke something that was fixed by centralized version control in order to provide some new conveniences.

I like Git because it actually helps communication developer to developer on a medium to large team. As a distributed version control system, through its push/pull system, it helps developers to create a source code eco-system which helps to manage a large pool of developers working on a single project.

For example say you trust 5 developers and only pull codes from their repository. Each of those developers has their own trust network from where they pull codes. Thus the development is based on that trust fabric of developers where code responsibility is shared among the development community.

Of course there are other benefits which are mentioned in other answers here.

A few answers have alluded to these, but I want to make 2 points explicit:

1) The ability to do selective commits (for example, git add --patch). If your working directory contains multiple changes that are not part of the same logical change, Git makes it very easy to make a commit that includes only a portion of the changes. With Subversion, it is difficult.

2) The ability to commit without making the change public. In Subversion, any commit is immediately public, and thus irrevocable. This greatly limits the ability of the developer to "commit early, commit often".

Git is more than just a VCS; it's also a tool for developing patches. Subversion is merely a VCS.

Thanks to the fact it doesn't need to communicate with a central server constantly, pretty much every command runs in less than a second (obviously git push/pull/fetch are slower simply because they have to initalise SSH connections). Branching is far far easier (one simple command to branch, one simple command to merge)

I absolutely love being able to manage local branches of my source code in Git without muddying up the water of the central repository. In many cases I'll checkout code from the Subversion server and run a local Git repository just to be able to do this. It's also great that initializing a Git repository doesn't pollute the filesystem with a bunch of annoying .svn folders everywhere.

And as far as Windows tool support, TortoiseGit handles the basics very well, but I still prefer the command line unless I want to view the log. I really like the way Tortoise{Git|SVN} helps when reading commit logs.

First, concurrent version control seems like an easy problem to solve. It's not at all. Anyway...

SVN is quite non-intuitive. Git is even worse. [sarcastic-speculation] This might be because developers, that like hard problems like concurrent version control, don't have much interest in making a good UI. [/sarcastic-speculation]

SVN supporters think they don't need a distributed version-control system. I thought that too. But now that we use Git exclusively, I'm a believer. Now version control works for me AND the team/project instead of just working for the project. When I need a branch, I branch. Sometimes it's a branch that has a corresponding branch on the server, and sometimes it does not. Not to mention all the other advantages that I'll have to go study up on (thanks in part to the arcane and absurd lack of UI that is a modern version control system).

http://subversion.wandisco.com/component/content/article/1/40.html

I think it's fairly safe to say that amongst developers, the SVN Vs. Git argument has been raging for some time now, with everyone having their own view on which is better. This was even brought up in the of the questions during our Webinar on Subversion in 2010 and Beyond.

Hyrum Wright, our Director of Open Source and the President for the Subversion Corporation talks about the differences between Subversion and Git, along with other Distributed Version Control Systems (DVCS).

He also talks about the upcoming changes in Subversion, such as Working Copy Next Generation (WC-NG), which he believes will cause a number of Git users to convert back to Subversion.

Have a watch of his video and let us know what you think by either commenting on this blog, or by posting in our forums. Registration is simple and will only take a moment!

Related