Friday, May 10, 2013

Moving your development team to GIT from SVN

About a year ago I had to move our development team completely off of SVN. This isn't an easy task since GIT is conceptually different from SVN. GIT outclasses other SCM tools (SVN, CVS and friends) because they are all built in the same version control repository concept - I strongly suggest you to watch Linus Trovalds talk on YouTube: "Tech Talk: Linus Trovalds on git".

Why did we move completely off of SVN?

GIT is a distributed SCM and this feature allowed us to manage efficiently all the integration of code - each developer could commit his changes to some repository and we could integrate their code into one centralized repository. All the advanced workflows of feature branching and merging are allowed, while in SVN it's very difficult to perform them. Usually you would like to keep two main branches: first branch is your production branch where you maintain your production code and the other branch is your development day-to-day place where you write new features, fixing bugs, etc. Merging your maintenance code from your production branch into your development branch isn't an easy task to do while using SVN. GIT makes it a lot easier.

One major difference is that in GIT nearly all operations are done locally, just as an example, you can still commit your changes while you are not connected to the VPN or even check your project history while you are offline.
There are many other benefits of using GIT: git only adds data and saving storage while you are working with many branches, its fast, folders and files are check-summed and a lot more. I'm not going to go through them here, there are plenty of great docs at: http://git-scm.com/doc.

What do you need to remember before you migrate to GIT?
There are three main states that your working copy files can reside in:
1. Committed - files are stored in the GIT repository.
2. Modified - working copy files have been modified.
3. Staged  - the modified files have been marked and will go at your next commit.
GIT keeps track of file system by taking snapshots of it each time you commit and stores a reference to that snapshot. GIT is efficient and adds data only, which means that if files haven't been changed, it just stores a reference link to the previous identical file version already stored.
The general workflow is that you first pull a working copy, modify files and adding a snapshot of them to your staging area and then you do a commit of your staging.
It's very important to understand the GIT basics before you are moving, I strongly suggest reading more here: http://git-scm.com/book/en/Getting-Started-Git-Basics.

Migration steps:

We had one centralized SVN repository server installed and stored on a CentOS Linux server. Developers could access the SVN repository through HTTP (Apache).  We didn't have a complex SVN repository hierarchy - just trunk and tags. So the first step was to install a GIT bare repository and configure our Apache server to serve GIT requests:
1. Download and install GIT
2. Create a dedicated GIT repositories folder, i.e. /var/www/repositories:
cd /var/www/repositories
git init --bare TestRepository.git (this will create a new bare GIT repository called: TestRepository)
3. There are many ways to access GIT (SSH, git daemon, HTTP, and more). We used git-http-backend  (read more here: https://www.kernel.org/pub/software/scm/git/docs/git-http-backend.html).
Add a new VirtualHost node into your Apache vhosts configuration file, for example:
<VirtualHost localhost:80>
       ServerAdmin webmaster@localhost
       DocumentRoot /var/www/repositories/TestRepository.git
       ServerName localhost
       ErrorLog "logs/localhost-error.log"
       CustomLog "logs/localhost-access.log" common
       <Directory /var/www/repositories/TestRepository.git>
               Options Includes Indexes FollowSymLinks ExecCGI
               AllowOverride All
               Order allow,deny
       Allow from all  
</Directory>
SetEnv GIT_HTTP_EXPORT_ALL
SetEnv GIT_PROJECT_ROOT /var/www/repositories/TestRepository.git
ScriptAlias /TestRepository.git $PATH-TO-YOUR-GIT-INSTALLED-DIR$\git-http-backend
</VirtualHost>

4. add a Location node to your httpd.conf file:
<Location /TestRepository.git>
     AuthType Basic
     AuthName "Git"
     AuthUserFile auth-users
     Require valid-user
 </Location>


NOTE: use the same AuthUserFile you used to authenticate the SVN repository.
5. Restart Apache
6. Validate that it's possible to clone your TestRepository project:
cd /home/eran
git clone http://localhost/TestRepository.git
cd /home/eran/TestRepository

git config --global user.name "Eran Levy"
git config --global user.email eran@localhost
git-config remote.upload.url http://eran@localhost/TestRepository.git
echo test > testfile.txt
git add testfile.txt
git commit -m "test commit"
git push origin master

If you didn't have any error, you are ready to start the migration:
It's a bit tricky now, there are a few things that you have to consider. Since SVN tags and branches are different from GIT, there isn't a simple way to migrate them into your GIT repository. There are several ways that you can go with:


7. As written above, we moved the latest production and development trunk into GIT. In order to do so, we used git svn clone - you can read more in here: http://git-scm.com/book/en/Git-and-Other-Systems-Git-and-Subversion.

8. The developers were using the Eclipse IDE installed on a Windows client. Each one of them had to perform the following:

Please read the getting started documentation in order to tune the GIT configuration for your needs (http://git-scm.com/book/en/Getting-Started-First-Time-Git-Setup). 


There are many other things to consider: how do you handle your branches, are you going to merge or rebase, what's the main workflow that your development team is going to work in, etc - it's strongly suggested to read the GIT documentation and make decisions. Try not to stick to your "SVN Workflows" and be open minded to use the "power of GIT".

Good luck,
Eran


1 comment:

Eran Levy said...

Update: I've found a tool that can be useful during the svn to git migration and it's called: Subgit (http://subgit.com/). I dont have any experience with it, but I think you should give it a try.