Keeping your dotfiles in git

martin f krafft madduck at
Wed Aug 27 14:28:47 CEST 2008

also sprach chombee at <chombee at> [2008.08.26.2255 +0100]:
> Google and you can find lots of people who keep their dotfiles in
> a git repository. Usually they create a directory such as
> ~/dotfiles/ and they move all the dotfiles they want to track into
> that directory, and create the git repository in that directory.
> Then they have a script of some kind (I've seen scripts in half
> a dozen languages for this) that creates symlinks from the root of
> their homedir into their dotfiles directory, e.g. linking
> ~/.muttrc/ to ~/dotfiles/muttrc/.

I found this too ugly and cumbersome and never liked the redundancy
a script would introduce, or the mess of symlinks cluttering ~.

Therefore I started to experiment with "detached worktrees" with
Git. The concept is easy: ~/dotfiles/vim.git is what I call
a fake-bare Git repository (meaning ~/dotfiles/vim.git/config holds
the Git config, but core.bare is false), with core.worktree set to
../../. As a result, ~/.vimrc is actually a plain file versioned in
the repository at ~/dotfiles/vim.git.

This works reasonably well for me, but I have yet to figure out how
to deal with .gitignore.

Also, to commit or otherwise interact with the vim repository,
I have to set $GIT_WORK_TREE and $GIT_REPO accordingly prior to any
command using /usr/bin/git. At the moment, I am using a script
called vcsh[0] for that, which spawns a subshell with these
variables set (and the $PS1 modified to help me keep track), and
I am actually liking it a lot, even though at first I tought this
explicit "context-switching" would quickly get on my nerves.


The approach has the advantage that my /bin/ls -l output is not
polluted with a lot of symlinks, and that I can tell someone else to
look at e.g. and know
immediately what goes where. No explanation, no script, no
redundancy, little room for failure.

Joey's mr script knows how to deal with "fake-bare" Git
repositories, so "cd ~/dotfiles/vim.git && mr commit" will work as
expected, as will "cd ~/dotfiles && mr update".

As mentioned before, the problem is simply that in the context of
~/.git or ~/dotfiles/vim.git a file like ~/.mutt/muttrc is "unknown"
and will show up in git-status output. One way to deal with that is
to put stuff like


into ~/dotfiles/vim.git/info/exclude, but unfortunately, that has to
be done on every machine and cannot be synchronised. It would be
possible to version ~/.gitignore.d/vim in ~/dotfiles/vim.git and set
core.excludesfile in ~/dotfiles/vim.git/config, but that too is
something that has to be done on all machine and won't be

There's also an issue with certain Git repositories requiring
post-processing after cloning and merging (see;f=.ssh;hb=HEAD for an
example, which uses make to generate the configuration actually used
by SSH). This can either be done with something like mr, but it's
hackish, or with ~/dotfiles/ssh.git/hooks/update, but that isn't
versioned or synchronised.

Maybe someone has an idea how to deal with those issues?

> I'm not entirely clear on why, in the examples I've seen, the -s
> option is used to create symbolic links instead of just using hard
> links.

Many "editors" don't respect hardlinks and would unlink them,
causing your files in ~ to become detached from the Git-versioned

> What about the permissions of your dotfiles? Git does not track
> file permissions, except for the executable bit, so people often
> create scripts to somehow store and restore the permissions of all
> the files.

I have ~ at 711 and a umask of 077 and have been happy so far.

martin | |
"nothing can cure the soul but the senses,
 just as nothing can cure the senses but the soul."
                                                        -- oscar wilde
spamtraps: madduck.bogus at
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: Digital signature (see
URL: <>

More information about the vcs-home mailing list