Bart’s article “svn-branches-in-git”

The original URL of Bart Trojanowski’s article is, but that site now seems permanently gone, so this version of that post is copied from the Internet Archive at

I must say that I am no fan of SVN, but SVN and I get a long a lot better since I started
using git-svn. Long ago a good friend of mine, Dave O’Neill, taught me how to handle
multiple branches using git-svn. I had used that technique until Dave taught me how to do it better.

Recently I saw this blog post which referenced Dave’s article talking about the first method. I guess Dave never got around to updating his blog with the better way. So I am going to do that here:

A few of my clients use SVN. Some I am guilty of introducing to SVN. But for this post
I need to give you an example that you can follow along with. So let’s use
shell-fm — my favorite
client — with an SVN repo located at svn://

NOTE: You should use a modern git release. If git --version is older then 1.5.3, you need to upgrade.

Let’s start by cloning this repository using git-svn:

    $ git svn clone svn:// -T trunk -b branches -t tags

NOTE: if you have commit access you may want to modify your svn:// url appropriately.

UPDATE: --stdlayout is a short form for -T trunk -b branches -t tags, and new versions of git-svn support it.

This process will take longer then an svn checkout would… a lot longer. There
are two reasons for this. (1) you are getting all the history of the project, and
(2) SVN has a very slow protocol for this purpose.

Anyway, once it’s done (it took me about 5 minutes) you will have a directory called
shell-fm with the contents of trunk checked out in it. If not for the fact that the
.svn directory is replaced with a .git directory you would have thought that you were
using a slower SVN.

Enter into your new repository and you will see that you have a master branch that is,
by default, following trunk.

    $ git branch
    * master

This is not a git tutorial
or a git svn tutorial; but I should at least show
how to update your tree, and commit to upstream.

I would like to insert here an advanced topic of packing your repository. I don’t want to explain
it here, see the [man page], but trust me it will make your git experience much more enjoyable
if you run the following once in a while:

    $ git gc

Now, to update your working tree to the latest of the branch you are currently tracking, you would run:

    $ git svn rebase

This is similar to svn update. There are likely no updates available now, so this will
do nothing.

Next, if you want to share something with the upstream svn server you would run:

    $ vim source/main.c
    $ git commit -m"this is a test" source/main.c
    $ git svn dcommit

This is similar to svn commit.

Now, let’s look at these branches I was promising:

    $ git branch -r

Each of the above is tracking a remote branch in SVN, except for trunk which is tracking trunk.
When you run git svn fetch all branches will be updated, and new branches on the remote
will be added. git svn fetch fetches the updates with out modifying the local working files
(which git svn rebase would). git svn fetch mimics standard git fetch behaviour with an
upstream git server.

Working off remote branches is usually done on local topic branches — that is to say, not
on master — but you can use whatever you want as git-svn doesn’t care.

Let’s thus create a new branch for fixing a mythical bug on the 1.2 branch.

    $ git checkout -b fixing-bad-1.2-bug 1.2

Almost immediately, and without server interaction, we get a checkout of branch 1.2
contents. You can see where you are with:

    $ git branch
    * fixing-bad-1.2-bug

If you carefully inspect output of git log you can see that git-svn reveals
the branch name and upstream SVN commit ID on the last line of each commit:

    $ git log -1
    commit 308244b0d275db460e3b4527afd51258cece4d33
    Author: strogg <strogg@7df44517-d413-0410-91cf-82ca28b36b55>
    Date:   Thu Sep 13 19:39:51 2007 +0000

        This is a patch from Wisq to make shell-fm accept 302 redirects as well as 301.

        git-svn-id: svn:// 7df44517-d413-0410-91cf-82ca28b36b55

We are on branches/1.2 commit id 252. If you prefer it, you can even get the
svn style log output with git svn logbut why?

Working on this branch is as easy as working off trunk. You edit, commit, and git svn dcommit to upstream.

Switching between your local branches is easy…

    $ git checkout -f master
    $ hack hack hack
    $ git commit

    $ git checkout -f fixing-bad-1.2-bug
    # and we're back on 1.2 bug fixing

Note that you don’t have to push your commits back to upstream immediately, or ever for that matter, to
make use of the git repository to store your local changes. But if you do decide to you just need to
run git svn dcommit.

If you’re interesting in migrating CVS to git, have a look at the CVS to git Transition Guide.

iOS 4.2.1 Download links

Handy for people jailbreaking with the Greenpois0n..

These are the Apple links to iOS 4.2.1 for each specific device.

If you wanted to upgrade to these, you would hold down the alt/option key when clicking on the “Upgrade” / “Restore” button in iTunes. This brings up a file dialog where you can choose the file to be used.

Best of Breed

At work I’m involved with setting up some new infrastructure, and I thought I’d write up what I am finding as well as solicit advice from others. We need what most development shops need, all of it company-wide and cross-platform (Mac, Windows):

Source Control — Git

This is pretty straightforward. We were using Subversion and are moving to Git.
There are other distributed source systems around like
etc. but git is the clear winner in terms of power, extensibility, space and speed.

Source Hosting — Gitorious / GitHub

A little less straightforward. I honestly thought Github was a good choice, but an almost-as-good choice if you want to keep your code inside the company firewall is Gitorious, which is kind of an open-sourced Github that you can deploy for free.

Unfortunately, Gitorious is a beast to set up, with its many dependencies, some at specific versions.

Fortunately, TurnKeyLinux is on the verge of releasing a Gitorious VM appliancet. I’ve gotten a server running using some pre-release patches (you can see progress on the TurnKey Linux forums).

Bug Database

No clear winner here.

  • Bugzilla is a mainstay, but can be a beast to administer.
  • Trac has great integration with source and wiki, but is a bit limited.
  • Redmine seems ok, but has a very busy interface (all those fields!).
  • Mantis isn’t bad.

Build Machine

Every time someone checks code in, a build should kick off.
Additionally, some testing should be done.
If checkins are frequent enough, simple unit test are enough,
with full regression tests saved for the nightly builds.

Code Review

Ideally, code checked in must be reviewed before it is accepted into the tree.

  • Gerrit is often mentioned, but it runs on Java.
  • CodeCollab is really good, but commercial.
  • Gitorious has a method involving checking code into a temporary branch, which is reviewed and then merged with the trunk/current branch if it passes muster. Haven’t tried this much though.


Having a central wiki, editable by all the developers is essential to a good dev community, even within a company.

  • MediaWiki, the heavy hitter.
  • Twiki, a popular, light-weight wiki.
  • Gitorious has a built-in wiki.
  • Redmine has a wiki.
  • Trac has a wiki with good source integration

How to build 64-bit, EFI-enabled grub on Mac OS X

# in your dev directory..
mkdir grub; cd grub

mkdir objconv; cd objconv
# "objconv" is required by the grub build. Its home page is
g++ -o objconv -O2 *.cpp
sudo cp objconv /usr/local/bin

# rehash if you are running csh
cd ..

# you may want to pick a more recent release; release_1_97 was the latest as of this writing
svn co svn://
cd release_1_97
./configure --with-platform=efi --target=x86_64

# edit kern/misc.c and add after line 53:
# void *memcpy (void *dest, const void *src, grub_size_t n);
# void *memmove (void *dest, const void *src, grub_size_t n);

# edit symlist.c and add after line 19:
# #include <string .h>
make -j `hwprefs cpu_count`
sudo make install

# This all results in:
# /usr/local/bin/x86_64-grub-editenv
# /usr/local/bin/x86_64-grub-fstest
# /usr/local/bin/x86_64-grub-mkelfimage
# /usr/local/bin/x86_64-grub-mkfont
# /usr/local/bin/x86_64-grub-mkimage

Git – it’s just that simple

sudo port install git-core +doc +gitweb +svn +bash_completion

The above is my command-line command of the day.
I’ve been doing some research over the weekend, reading up on all the current source control systems
(for which, by the way, there is no consistent acronym. The closest I can find now is DVCS – Distributed Version Control System)
and have come to the conclusion that:

  1. The developer behind Shoes is one intensively creative fucker
  2. Git is as good as it gets

The kicker came when I found the script git-p4, which allows me to use Perforce at work in conjunction with all of git’s way-cool features!

What are these features you ask? Well, if you’ve ever heard of SVK, you will love git. Because git does what SVK does natively. And SVK is known to be like a castle on shifting sand in terms of stability. Git is rock-solid.

For the uninitiated (which would be most of you), SVK lets you check out code from a Subversion (svn) repository, and then do local-only checkins and checkouts. Then once you are happy with your changes (perhaps after 20 revisions, all tracked locally by SVK), you can “push” your changes to the main svn repo.

In the same way, git lets you “pull” changes from a central repo, do many modifcations, checking them in to git each time, and do a final “push” back to the central repo. Indeed, the concepts of “central” and “non-central” repos is not embedded into git. The central repo is only central by convention. All repos are equally “central”.

Mac OS X command-line gotcha: path_helper

Ran into an issue where my terminals were coming up **really** slowly.
It ended up being a line in the script /usr/libexec/path_helper.

It turns out Apple has set up a whole process for modifying users’ PATHs by adding text files in /etc/paths.d, which is really a good idea, since install/uninstall scripts can just add/remove text files instead of mucking around with users’ login scripts.
For some reason it was taking about 30 seconds to execute this line of bash:

[[ /Users/t_ellir/bin/Darwin:/Users/t_ellir/bin/Darwin-i386:/Users/t_ellir/bin/noarch:/Users/t_ellir/bin/osx-rae:/opt/local/bin:/opt/local/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin:/usr/lib:/Developer/Tools:/usr/X11/bin:/Applications/ccollab_client:/Users/t_ellir/mudbox/dev/bin/macos:/System/Library/Frameworks/Python.framework/Versions/Current/bin:/opt/local/Library/Frameworks/Python.framework/Versions/2.4/bin:/System/Library/Frameworks/Python.framework/Versions/Current/bin:/opt/local/Library/Frameworks/Python.framework/Versions/2.4/bin = *(*:)/usr/local/bin*(:*) ]]

But it had no problem zipping through other directories, e.g.:

[[ /Users/t_ellir/bin/Darwin:/Users/t_ellir/bin/Darwin-i386:/Users/t_ellir/bin/noarch:/Users/t_ellir/bin/osx-rae:/opt/local/bin:/opt/local/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin:/usr/lib:/Developer/Tools:/usr/X11/bin:/Applications/ccollab_client:/Users/t_ellir/mudbox/dev/bin/macos:/System/Library/Frameworks/Python.framework/Versions/Current/bin:/opt/local/Library/Frameworks/Python.framework/Versions/2.4/bin:/System/Library/Frameworks/Python.framework/Versions/Current/bin:/opt/local/Library/Frameworks/Python.framework/Versions/2.4/bin = *(*:)/usr/sbin*(:*) ]]

so it has something specifically to do with it being /usr/local/bin.
I didn’t have that directory so I created it, but that didn’t help.
I finally kludged around it by removing the directory and then patching the script to test for the existence of the directory before trying the test:

--- path_helper 2008-11-04 11:54:18.000000000 -0500
+++ /usr/libexec/path_helper    2008-11-04 11:54:47.000000000 -0500
@@ -15,6 +15,7 @@
        for f in "$DIR" "$DIR".d/* ; do
          if [ -f "$f" ]; then
                for p in $(< "$f") ; do
+                       [ ! -d "${p}" ] && continue
                        [[ "$NEWPATH" = *(*:)${p}*(:*) ]] && continue
                        [ ! -z "$NEWPATH" ] && SEP=":"

Props to
for having a blog post about this.

Uploading video

Luisa shot some video of her parents making some wine with a grape press and wanted them uploaded. So I went through a few iterations of encoding+uploading to see what worked best.

Pre-encoding files means you only upload about 1/10th as much, saving tons of time.

I used ffmpegX to encode and eventually found that just using H.264 mp4 encoding at the original size worked best, giving me the much-coveted “Watch in high quality” option on YouTube.
I’m uploading the videos to my YouTube account now,
and then I’ll upload them to my Vimeo account,
which shows them at much higher resolution.

Making Wine 2 from Reid on Vimeo

Qik on the (jailbroken) iPhone

So they seem to have worked out the kinks with the beta Qik client for the iPhone.
Actually, the kinks were in their website’s handling of iPhone-originated video.

In any case, you can go to
and see my short masterpieces.
Plus, if I happen to be recording at that moment, you can watch it live!
Ooooh, ahhh.

I will embed the video I just took at work for your edification and amusement. :-)

Jailbreaking an iPhone

This is just a note about living with a jailbroken iPhone. I think I’ll update it over time.

Current jailbreak tool is PwnageTool_2.0.2.tbz,
which works with the first iPhone 2.0 update, 2.0.1.

If you find you can’t use WiFi after jailbreaking, try:

  1. removing your WiFi network and adding it back again
  2. use BossPrefs to “repair user dir permissions”

Interesting apps for jailbroken phones include:

manually installed; it was pulled from the App store
NES emulator
play tons of old games!
Quake 1
Lets you tweak lots of stuff, including jailbreak-specific things like “SSH Server” on/off

How to install a *.app file

cribbed from MacRumors forums.

Using an SFTP application (I use Cyberduck), drag the folder from the desktop into the iPhone’s /Applications folder.

Open a terminal window, and open an SSH session with the iPhone:

$ ssh root@

(replace the IP address above with your iPhone’s IP Wi-Fi address.) The default root login password is “alpine”.

Next, go to the folder:

# cd /Applications/

and change the access file mask of the main application file:

# chmod 755 NetShare

Reboot (or re-spring if you know how) your iPhone.

You’re done!

My Installed Apps

Here are links to my 9 app screens:

Fun, eh?

Trying out “Disqus” for comments


Let me know what you think of the new comment system.
I’ve installed if for all zero-comment posts (which includes all new posts), so old posts with comments still have the old WordPress commenting system.

This may involve you having to create a Disqus account, but the idea is that you can use that account across blogs.
I am also setting up Disqus on
my blog
so you only have to create your account once for both places.

Leo Laporte has also set up his blog to use it.
Maybe it will spread everywhere.

The idea is that your comments belong to you, and Disqus makes it easier to follow people, as opposed to blogs.