Xcode and Expandrive/git Workaround

I’ve been using Xcode 4 for editing everything these past couple of days largely due to its (good enough) git integration, but have come up against an irritating issue while trying to use Expandrive to work on a remote repository (I sometimes work inside Linux VMs when dealing with stuff like crufty dependencies and staging environments).

In short, git (both inside and outside Xcode) would refuse to work atop sshfs, failing with miscellaneous errors pertaining to “permissions” and SHA1 checksums, the upshot being that I couldn’t do commits and (sometimes) diffs for some reason. And Xcode 4 makes you want to do diffs all the time…

This seems to be a recurring issue with all sorts of sshfs access to git (including other favorites like Transmit) and would normally be fixed with cloning the repository locally in the usual way, except that when you’re doing debugging and fixes you need to have your edits propagated in real time - I’m messing about with Catalyst (of all things) and it reloads modules dynamically, so saving, committing, pushing (and, optionally, pulling into staging) is a royal pain.

Enter Unison, which I am saddened to see still has no real alternative (I still hate its OCaml guts and its stupid requirement of having fully matching versions on each end, but, alas, nobody seems to have come up with a better solution).

After setting up a profile for my VM, having changes propagated in real time is simply a matter of having:

unison vm-dev -batch -repeat 15 -times -ui text

…running in the background, and using Xcode on the local replica.

Your mileage may vary, of course, but it works well enough for now. Let’s hope Expandrive implements a workaround of their own for this.

Update: A few people pointed out that you can achieve similar results using only git and a post-commit hook like so:

cd ..
env -i git reset --hard

…provided your workflow allows for you to commit/push to the development machine. Since this pollutes the logs a bit (and requires you to add something like denyCurrentBranch = ignore to the receive section of the repo’s config file) it’s not ideal, but there is another trick that might help:

Set up the push as an Xcode build target (as if it were a custom build step, with git as the build command). The beauty of this is that you can, of course, set up several targets to push to several different environments (dev, staging, main repo, etc.), and have it all nicely integrated with Xcode.

Update 2: I eventually decided to simply install netatalk onto the VM, since version 2.0 is actually easier to setup than Samba (and you can even bind it to localhost and tunnel it trivially - if slowly - on top of SSH if that’s the only connectivity you have).

See Also: