Using Git like svn:externals

Slave to fashion that I am I just couldn’t help but drink the git Kool-aide. And because I’m so insecure about falling behind on the latest trend I thought I’d go ahead and try to patch Rails with some git plugin support.

Have you ever done this?:

$ script/plugin install http://svn.techno-weenie.net/my_code_is_prettier_than_your_girlfriend

Or (getting tricky) this?:

$ script/plugin install svn://svn.techno-weenie.net/seriously_this_stuff_is_gorgeous

Well, pretty soon you’re going to find yourself pasting this into a terminal somewhere:

$ script/plugin install git://github.com/technoweenie/sexy_code_fu

And you’re going to get a big fat error. Unless you comment on this ticket and help get it committed.

h3. Why Git and legacy SVN apps work so well together

It can be pretty easy to clobber something installed via svn. If you’ve got a plugin and you overwrite the vendor/plugins/some_code/.svn directory your svn client is going to be totally befuddled. If you mangle the svn:externals property on that directory you’ll have an equally difficult time. So it’s natural you’d expect Git to hose your app. Not so.

If you’ve got an app that’s tied to subversion you can insert a Git plugin as easily as this:

$ git clone git://some_git_address vendor/plugins/my_git_plugin

What that does is like a ‘checkout’ of the Git plugin with full repository history into your app. You can now add all these files into subversion (svn add vendor/plugins/my_git_plugin) and forget that it’s even a Git app stored in there. And, when you want to update the plugin, it’s as simple as:

$ cd vendor/plugins/my_git_plugin
$ git pull

Why does that work? Because when you cloned it you got a .git directory in the plugin that manages all the Git information for you and remembers where the code needs to be updated from.

Now, there’s a downside to this. When you clone via git it creates a FULL copy of all the history of that plugin in your app. This can be huge. But it’s not. Because we’re going to opt to keep this directory to a minimum with the ”–depth 1” option when we clone (thanks to evolving_jerk for the tip).

$ git clone --depth 1 git://some_git_address vendor/plugins/my_git_plugin

Now that .git directory is going to be tiny and manageable.

You’ve got nothing to lose! Check out all the lovely projects on Gitorious and GitHub for some fun ideas for plugins.

  • labria said: Too bad git doesn't have real externals. I sometimes use svn's external property to share models between projects, and manually pulling every update (and not forgeting to do so) can be more pain than vanilla "svn up".
  • Chu Yeow said: This is a really awesome patch (just noticed your patch got committed and came here to thank you for it).
blog comments powered by Disqus