Latest from the Bamboo Blog

A few weeks ago we start experimenting with Git for Rails development.

I am not going to highlight the all of the advantages of using git here, but let me mention that Git is one of the few SCM out there that really understands merges.

As Linus, the creator of git, says in this thread

“The important part of a merge is not how it handles conflicts (which need to be verified by a human anyway if they are at all interesting), but that it should meld the history together right so that you have a new solid base for future merges. In other words, the important part is the trivial part: the naming of the parents, and keeping track of their relationship. Not the clashes. And it looks like 99% of SCM people seem to think that the solution to that is to be more clever about content merges. Which misses the point entirely.”

Git tracks content, not files. Git is really a filesystem, represented by tree structures. So you are really comparing trees between commits, and tracking the changes of the nodes in the tree.

There are enough tutorials out there for you to start grasping git. I can recommend these ones:

You may want to consider Git if you have ever run into a merge marathon on a big project with SVN. If you have ever tried it, it is just painful and it does not work, not the SVN way.

Enter Git

Git makes branches easy to create and merge. Git branches are only a 40-digit hex hash, with the origin of the branch. Branches are cheap, and easy. You start using git, and before you realise it, you are merging and branching all the time.

So a regular working pattern would be:


------------------------------------
git branch mywork
git checkout mywork
...hack some files (file1 file2 file3)...
git add file1 file2 file3
git commit
git checkout master
git merge mywork
------------------------------------

Yes that’s good, but what happens when all your development repositories are under SVN control? Well here comes a little script that will help us integrate with our existing repositories.

Enter git-svn

git-svn is a little perl script (that comes bundled with the Git distribution) that lets you track SVN repositories. You can also commit back between Git and SVN. This is very good, you can start using git without converting your working repositories yet… well until you are ready to migrate them.

GIT RAILS RECIPE


mkdir beast
cd beast
git-svn init http://svn.techno-weenie.net/projects/beast/trunk  (for example) 
git-svn fetch -r2940                                            (get a particular repository revision)
git-svn fetch                                                   ( get the whole repository history)

then REPEAT{ 

git checkout -b mywork        (start my own branch)
   ....START HACKING          (fix some bugs)
git commit -a                 (commit the changes to git)
git checkout master           (switch to master branch) 
git-svn rebase                (update master with the upstream svn repository)
git checkout -b mymerge       (create a branch mymerge and checkout from master)
git merge --squash mywork     (merge into current branch, mywork branch) 
git commit                    (commit the changes to git)
git-svn dcommit               (commit the changes to svn repository....if you have enough permissions)
git checkout master           (switch to master branch) 
git-svn rebase                (update master with the upstream svn repository again)
git branch -D mywork mymerge  (get rid of branch mywork and mymerge)

}

See http://cheat.errtheblog.com/s/gitsvn/ for a cheat sheet on this.

Here James Bowes tells us why rebase is important: http://jbowes.dangerouslyinc.com/2007/01/26/git-rebase-keeping-your-branches-current/

There is one problem with git-svn. It can not handle svn:externals yet.

But there is a workaround to it. Once you fetch your RAILS svn project, you may want Rails edge in your vendor directory, or some handy plugins as well.

Get RAILS EDGE into a separate git clone as well as your handy plugins. Then do a symlink into the vendor directory.


mkdir rails_edge
cd rails_edge
git-svn init http://svn.rubyonrails.org/rails/trunk  (for example)
git-svn fetch -r7300  (get just the latest revision you know about) 

git-svn fetch   (perform a fetch once in a while to keep it up to date)

then cd myproj/vendor
ln -s ../../rails_edge rails

Perform the same task for every plugin you use. You may also track a stable version of rails like http://svn.rubyonrails.org/rails/branches/1-2-stable

There are pros and cons of this approach. You can decide if this is enough for your current needs or wait until git supports subprojects. Keeping Rails stable and edge in different repositories, and tracking their changes independently seems to be a very clean way to work.

I hope that gives you a warm welcome to the world of git, and that you start enjoying Rails development along with Git.

11 Responses to “Talk @ 2: Using GIT for Rails Development”

  • Pedro

    In the Rubinius project we have migrated to GIT instead of SVN.

    http://rubini.us/forums/3/topics/60
  • Cristi Balan

    A shorter version of git-svn init blah && git fetch -r is git-svn clone -r.

    For the plugins, another, albeit freaky, idea is to do a svn checkout in the vendor dir and commit all that into git, .svn directory and all. That way, when you want to update the plugin, you use svn and commit that back to git.

    I think this might seriously freak out svn when you checkout your project tho. I didn’t even try this so I have no idea what happens. :)

  • Alex Payne

    Thanks much for this! Super helpful.

  • topfunky

    I’ve been using git and git-svn for a few weeks. In svn I often make changes, then decide to revert by deleting the relevant file and doing an “svn update”.

    However, git-svn seems to freak out at this point (“some_file.rb: needs update”). Is there a better way to revert or refresh with git-svn?

  • Pablo Geoffrey, you have think of git-svn solely as a “fetch and push” utility for keeping track of svn repositories. If I understood correctly, in order to revert a mistake, normally you delete a file and then svn update to restore a fresh copy form the repository…right? Well you are handling a git repository now, so if you delete a file, git tracks that file removal; in order to restore that file you use the command :
    git checkout HEAD some_file.rb
    
    git will then restore the file “some_file.rb” from the HEAD or the last git commit you made.

    You’re best to use only git-svn (git-svn dcommit, git-svn rebase and git-svn fetch) whilst you are getting used to things. Ideally you only operate with the svn repository when you are ready to commit some changes.

    Hope you liked the intro/recipe and will encourage other rails developers to use git.

  • topfunky

    @Pablo: Thanks for the detailed answer!

    I should have mentioned that I was trying to do the same thing with “git-svn rebase”, but it looks like the “git checkout” command is what I need.

  • Doodles

    Any idea on how to handle empty directories in the rails dir? What I do currently is to place .gitignore’s in each empty dir, which is ugly especially during the initial creation of the rails tree when lots of directories are still empty (e.g., app/models).

  • Hendy Irawan

    You can also (I would say, recommended) track branches/tags:

    git-svn clone … -t tags -b branches -T trunk

    This will give you access to all of these branches. Good for most Subversion projects.

    So you’re not only tracking trunk :)

  • Hendy Irawan

    Anyone learning Git (esp. from SVN) should check out below:

    • http://tsunanet.blogspot.com/2007/07/learning-git-svn-in-5min.html
    • http://utsl.gen.nz/talks/git-svn/intro.html
    • http://wiki.ruby-id.web.id/wiki/Git#Sumber (just the links)
  • Helder

    Just what I was looking for! Thanks for the tip :)

  • riles

    Great article, thanks. When I attempt to invoke git-svn it complains that it can’t find SVN/Core.pm. A bit more research seems to indicate that SVN/Core.pm comes with subversion. I have subversion, but perhaps need to do a build from source? Any help would be appreciated.

Sorry, comments are closed for this article.