My first source control system was SVN with TortoiseSVN. I’ve used this for years.
I started using Git about 5 months ago.
I’d dabbled with it previously, using it to push to Heroku or clone some repositories from GitHub, but nothing major. Then I started working at Igloo Software (we make a cloud based Intranet platform that you’ll actually like) and they had recently made the switched from SVN to Git. My previous job had me using SVN with TortoiseSVN, so of course the first thing I did was boot up TortoiseGit.
TortoiseGit is great at allowing you to work with Git while still pretending it’s SVN. Of course after a month I started to get concerned that I really didn’t understand what Git was doing and how it worked. This was frustrating when I’d find myself trying to accomplish different things and the results were not what I expected. In fact, more than once I completely blew away my local repository and cloned it again from scratch figuring that a fresh clone was really the best way to be comfortable with my source control.
Yes. I really was that clueless.
The smart people I work with advised me that TortoiseGit seemed to be pretty bad for working in Git, and suggested that I use SourceTree, which is a much better graphical tool for abstracting away Git’s mysterious inner workings. I did take a look at it, watched people do some work with it, and even attended a lunch and learn explaining it. In the end, I decided to get rid of the abstraction entirely and move straight to the command line.
This post is not really intended to talk about how Git works. There’s a lot of other material out there covering that topic. The first thing I did was read Pro Git, written by Scott Chacon and published by Apress. (The book is available in full online, and dead tree copies can be purchased from Amazon.) Well, I did read the first four chapters of the book. But honestly, those four chapters were incredibly and really helped me gain my footing. Suddenly I found myself being transformed from clueless newbie to someone in the office who could actually provide solid information and answers regarding the workings of Git. (That knowledge base is increasing all the time as I continue to learn, read, and watch various videos on Git.)
So what tripped me up about this transition?
SVN is a centralized source control system, while Git is decentralized. I’d heard this many times, but never really understood what it meant.
When I was working with SVN, whenever I’d commit I’d have to deal with potential conflicts and everyone would need to refresh their branches in order to receive my changes. I had gotten into the habit of notifying my team when I’d push a commit that I thought might have conflicts with their work, or that had code they needed to continue their own work. This is not needed in Git.
It’s not needed after a commit anyways. Git is completely decentralized. When you clone a repository, you have the whole thing. You have every version of every file that has existed in the repository. Local. On your device. When you commit, you are only committing your changes to a branch that exists locally. Others can only receive your changes when two things happen: you push your changes back to origin (origin being the distributed system where you are storing a copy of the repository), and they pull the changes from origin to their local repository.
This means that unlike SVN, if the server is down you can continue to commit, you just can’t push those changes to your distributed system. You can still provide those commits to your coworkers by sharing through your machine or a different distributed machine. The flowing nature of Git makes it extremely fault tolerant.
Because your repository lives locally, you can also create and destroy new branches easily. These branches never have to live on the server. They can exist only locally and no one else will ever have access to them unless you decide to push them to origin, of course you can always merge these changes back into branches that are linked with branches that exist on origin without needing to share your local branches. I found that this made it extremely easy to create a new branch to test out refactoring or look at how new features would function with minor changes without ever needing to pollute another branch — and I could still commit all my changes because everything occurred locally.
Another thing I didn’t understand were the differences between staging, working copy, and committed code. When you are working in SVN and you have some code ready to commit, you can decide which files to commit and which not to commit. In Git, you can do this on an ongoing basis without needing to decide when it’s commit time. When you commit in Git, by default only files in your staging area are committed and you can easily control which files are added to your staging area (or you can add all changed files in one go if you so choose). At the same time, you can continue to make changes to files already in staging without needing to commit the changes to the file since they were changed. At any point you can discard those changes or add them to staging as well without ever needing to commit them. Once they are committed, they are going to be added to your local repository and you’ll need to checkout old versions in order to revert that code.
Most of the problems that I encountered between SVN and Git were terminology differences and the basic differences between centralized and decentralized systems. I found that once the terminology was cleared up, I was able to find answers to issues that I was having and pass along those answers to coworkers. Pro Git was the most invaluable resource for me during this time.
I do recommend making the switch to Git. There are a lot of advantages to it, but there is likely going to be a learning curve as well. You’ll likely have an easier go of it if there’s someone on your team working with Git regularly already who can help the team transition and understand what is happening. And if you want to really understand how to work with Git, and not simply try to pretend Git is SVN, I’d recommend staying away from TortoiseGit for the time being. It seems like it’s more likely to hinder your learning than it is to foster it.