Thursday, January 08, 2009

Using Git with SVN

Although git might generally be recognized as Southern slang, in web developing, "git" is one of the most useful applications for your local development environment. Git is a version control system similar to SVN or CVS, however using git is a bit different SVN or CVS. In this post, we will assume that you are familiar with version control systems, and you are currently using or have used SVN.


Learning Git

There is usually a little learning curve when looking into a new concept. Git is no different, however it is well worth the time investment to learn, because it will certainly save you time in the future. Here are the pro's and cons of learning git:

PRO's
  • Increase productivity and speed in local developing - Git is fast and it works locally. Git allows you to take an entire project, copy it, totally trash it with debug code so you can get the task done, and then completely restore the original files almost instantly.
  • Less hassle - Git's commands are purposefully easy. With one command you can commit all of your changes. With another single command you can create a new branch and immediately start working.
  • Keeps you on track and focused - with the branching functionality of Git, you can work on two or three projects in the same code base at the same time. Switching between your code is almost as easy as Alt-Tab in windows.
  • Git is powerful - Git's merging functionality is very quick, simple, and powerful. There are conflict resolution tools that help you to merge safely without breaking things. It also allows you to go back and fix mistakes and recover lost changes.
  • Git is local - The entire repository for Git is contained in a .git directory in your root path. This means if you have a project with several hundred directories, you won't have hundreds of .svn or CVS directories. Just one .git directory.
CONS
  • About the only con of Git is the intimidation factor. Currently there is no TortoiseGit to make the familiar transition from TortoiseSVN. The best way to use git on windows is to use the command line using MsysGit.
Where To Start

Screencasts and tutorials are some of the best places to start to familiarize yourself with something new. Here is what I did to learn git:
  • Watch some screencasts - I started out with the free screencast from debuggable. It gives you a step by step process on how to setup Git along with examples of building a repository.
  • Read the Documentation - Yeah I know, writing code is much more fun than reading about it, but hey, it's worth it. I would suggest reading and focusing on the first 3 chapters of the Git User's Manual. It will provide you with specific walkthroughs and examples of each concept.
  • Do it yourself - Now you should be ready to start implementing git in your own projects.
Development Process

Here is a development process to get you started with git with a project that you are already working on.
  1. Open the git bash window.
  2. Navigate to the root directory of your project.

    cd /c/www/myproject

  3. Set up your git repository in that folder.

    git init

  4. Set up any .gitignore files that you may want. Often this would be for tmp folders, dynamically generated files, or any .svn or CVS folders.
  5. Add and commit everything

    git add .
    git commit .
    or
    git commit -a .

  6. Create a new development branch and switch to it.

    git checkout master
    git branch t.setup_test_cases
    git checkout t.setup_test_cases
    or
    git checkout -b t.setup_test_cases master

  7. Now you are safe to start coding your task. You are now working on a copy of your files, everything is backed up and recoverable. Add, Delete and Commit as you go, and everything will be stored to the branch.

    7a. At any time during development you can repeat step 6 to create an additional branch to get a high priority item finished, then go back to your main project. You can also have two or three simaltanious projects open at once.

  8. When you're done with your changes to a branch, simply merge back to the master.

    git checkout master
    git merge
    t.setup_test_cases
    #Resolve any conflicts here
    git status

  9. Use gitk to examine your changes to see what happened.

And it's that simple.

Using Git with SVN

Now that you know the basics of git, you can implement it alone, or within your SVN repository. Git only adds a single directory .git within the base of your application and it does not interfere with SVN. From the Git side, you will need to filter out .svn directories. The implementation is easy enough. Simply add the following line to the file: ".gitignore"

.svn

Basically the .gitignore file will allow git to ignore any matching file or directory. You can use wildcards to find more specific file matching.

At this point you will be able to use the git steps above within an SVN repository to keep up with your local changes without having to commit to the svn repository as much.

Why Use Git in SVN?

Using git inside of SVN has its advantages and disadvantages. One advantage is you gain the flexability of simple branching without having to download the entire repository from the SVN server. It is like adding tabs to a web browser. You can multi-task, branch and merge all locally, and then once your modification is tested and ready, simply SVN commit.

Let's look at an example.

I have an SVN repository setup in my development environment called /www/coolwebsite/ I created the git repository as described above and I setup my .gitignore. I have a 3 item project list for changes on the website.
  • change the design of the home page
  • create an email autoresponder
  • create a contact us form
The first thing I would do is decide on one project to start on and branch off of the git master.

git checkout -b t.home_page_design master

This says that I am going to create a new branch called 't.home_page_design' based on the 'master' copy, and I'm going to switch to that branch.

So 'git branch -l' should look like:

master
* t.home_page_design

Now let's start working on the project. I edit the home page and save it. I edit 2 css files and save them. Then I add 3 new images. I do a 'git status' and see:

$ git status
# On branch master
# Changed but not updated:
# (use "git add ..." to update what will be committed)
#
# modified: index.html
#
# Untracked files:
# (use "git add ..." to include in what will be committed)
#
# images/banner.gif
# images/logo.jpg
# images/test.gif
no changes added to commit (use "git add" and/or "git commit -a")

Now simply add and commit to the branch.

git add .
git commit .

If you're using TortoiseSVN you will find that the changes have become red in your file browser. This should reflect the changes that you've done in your files. Before committing to SVN, you first want to merge the changes back to the master branch.

git checkout master
git merge t.home_page_design

When you checked out the master, the red files in TortiseSVN should have turned green, but they should have turned red again when you did the merge. There should be no conflicts here and now the master branch should reflect all fo the changes of your branch. An additonal commit is not necessary.

It is now safe to publish your changes to the SVN Repository.

The next project is to create an email autoresponder. Again we make a new branch.

git checkout -b t.autoresponder master

This time as we start working on the autoresponder branch, our client comes to us and says that they need the contact us form built ASAP, and the other project needs to go on hold. We don't want to lose any of our changes to the autoresponder either. Git handles this quite well.

First commit all of your changes:

git commit -a

Second, create a new branch for the contact us form.

git checkout -b t.contact_us master

Now you can start on the contact us form and still hold on to the changes from the autoresponder. While you are editing and adding files, you will notice your changes reflected in
TortoiseSVN. During the middle of a project you can easily switch branches and work on them without affecting any other branches.

You finish the contact us form, commit it to the branch and then merge to the master.

git commit -a
git checkout master
git merge t.contact_us

Now master has the contact us additions. Commit to SVN from the master branch, and then checkout t.autoresponder

git checkout t.autoresponder

Finish the autoresponder and commit the changes. Commit to SVN, and there you have it.

Final Thoughts

As you can see, there are some great advantages to using SVN with Git, and there are a few disadvantages. If you branch for every change, it will force you to keep tasks separate which could be a good thing or a bad one. There is a little bit of overhead during development to keep both repositories in sync, but the flexability that you gain is sure to outweigh any lost time.

Feel free to comment.




1 comment:

Parag Shah said...

Thanks for the post. I found it very useful.

I plan to use git on top of cvs. I assume except for .gitinore, everything will remain the same.

--
Thanks
Parag