Version control for ~ (v3.0)

For a long time I used NFS for my home dir. That worked great at home and at work where I’d have a desktop and server. But then I got a laptop and that stopped working. For a while I’d rsync things but then I came across a “version control your home dir” article (this one?) and was hooked.

First I used subversion. My earliest commit was in early 2008, but I stripped out a lot of older binaries I’d committed (bad Kevin, no cookie) so supect the initial start was in 2007. It worked well. I had to write a few scripts to fix permissions but otherwise it was fine.

Next up, mercurial. By July 2010 it was well-past clear that subversion had a dark future and that distributed VC systems were the way to go. I held out against git so instead used mercurial.

But at the same time I was using git for code. And as time went on the differences between hg and git were getting more and more annoying. They weren’t really diverging, I was just less interested in remembering them. I wanted to use it for my home dir, but for a number of reasons the idea of a .git dir at the base of my home dir seemed like a bad idea. A git add . in the wrong place would make me sad.

Until this weekend when I came across vcsh. Not only does it use git and not put a .git dir in your home dir, but it actually allows you to use multiple repos for your home dir. The command line is different, but it’s the same concepts. Since I use pass which has a subset of git commands, it’s a similar concept.

The nice part is that setup is a cinch. The annoying part with my svn or hg methods was setup, with vcsh it goes like this:

vcsh clone ssh://git@mygitrepo/kevin/home.git home
vcsh home git co -f master

The first clones my home repo. It will usually fail in my case because something is in the way. So I run the second command (note: clobbers files) to just force it to go.

After that you can run vcsh push or vcsh pull to do the obvious action in all your home dir repos. To run a command for a specific repo (say a commit) you just prefix the repo: vcsh home commit -m "A change" a.changed.file.

Now, you do need to be careful. Running vcsh home status will show loads of missing files. Vcsh has a per-repo gitignore system which I haven’t explored yet, but should avoid a number of errors. Wouldn’t want to run vcsh home add . accidentally in ~/Dropbox for instance.

Vcsh also makes use of myreposmr command. This is a dependency of the vcsh package on Ubuntu but not on homebrew so I’ve just added mr to my ~/bin. It’s a useful command. Several projects I work on have a number of relevant git repos which I organise in ~/src/PROJECT dirs. Now I’ve just added .mrconfig files to each and updating a project’s git repos is just a simple mr up when I get into the project dir.

Both vcsh and mr are just single-file scripts (perl and shell respectively) so port pretty nicely anywhere.

All in all quite happy with them.