Learn Version Control with Git
A step-by-step course for the complete beginner
Switching from Subversion to Git
Actually, switching from Subversion to Git isn't very complicated - but only if you don't treat Git like a fancier Subversion. Once you understand where the concepts differ, the transition becomes easy.
Distributed vs. Centralized
Subversion is a centralized version control system: all team members work towards a single central repository, placed on a remote server. A "checkout" from this central repository will place a "working copy" on the user's machine. This is a snapshot from a certain version of the project on his disk.
In Git, a distributed version control system, things work a little differently. Instead of a "checkout", a Git user will "clone" a repository from a remote server. In return, he receives a full-fledged repository, not just a working copy. The user then has his own repository on his local machine - including all of the project's history.
You can do everything on your local machine: commit, inspect history, restore older revisions, etc. Only if you want to share your work with the world you have to connect to a remote server.
Repository Structure and URLs
A Subversion repository is typically organized with a couple of directories: "trunk" for the main line of development, "branches" for alternative contexts, and "tags" to mark certain revisions. To address these different parts, URLs are used that point to these locations inside the repository:
Git repositories, on the other hand, consist of only a single ".git" folder in the root of a project. Addressing branches or tags is done via commands, not URLs. In Git, the URL only points to the location of the Git repository.
As just mentioned, branches in Subversion are just simple directories that happen to have a special meaning. When creating a new branch, you effectively create a (very efficient) copy of your project in a new folder.
In Git, branching was one of the core design goals and therefore required a quite different concept. A branch in Git is simply a pointer to a certain revision - thereby creating no copy, no new directories, and no overhead.
You are always working on a branch in Git, even if it’s just the default “master” branch that gets created automatically. Your working directory contains the files that belong to this currently active branch (in Git called the "HEAD"). All other versions and branches are stored in your local repository, ready to be restored in an instant.
Also keep in mind the distributed nature of Git: branches can exist remotely and - much more important for your daily work - locally.
When making a commit in Subversion, a couple of rules apply:
- You can only commit when you have a connection to the central repository. You can't commit while you're offline.
- The commit gets instantly transferred to the central repository.
- It gets assigned an ascending revision number.
Committing in Git differs in some aspects:
- You don't have to be online or connected to any "central" repository - because you have a full-blown repository on your local disk. Therefore, commits are recorded only in your local repository. They're not transferred to any remote repository until you explicitly decide to share them.
- Only because a file was changed doesn't mean it will automatically be included in the next commit. You have to explicitly mark the changes you want in the next commit by adding them to the so-called "Staging Area". You can even mark parts or individual lines of a file to be included, while other parts are left for a later commit.
- Revision numbers are replaced by "commit hashes". Since commits happen offline on the developers' local machines, you cannot assign one commit #5 and another one #6 - who's first in such a distributed scenario? However, of course, there must still be a way to uniquely identify commits in Git. Therefore, a hashed string is used instead of the ascending revision number.
With Subversion, your work is automatically transferred to the central server when you commit. And committing is only possible when you can connect to this central server.
In Git, nothing gets uploaded automatically. You can decide for each of your branches when (and if at all) you want to share them with your team. Besides that, sharing work is very safe: conflicts can only occur on your local machine and not on the remote server. This leaves you with the confidence that you cannot break things.