Developers are very picky about their working environment. We may consolidate
. files tailed for our tastes over years and track the change in a
version control system, preferably
git. Unfortunately, git or other VCS is not
designed to maintain multiple working copies in a single directory. We may
end up copying or linking the dot files to the home directory, like dfm
does. The more external projects are added as
subtree, the harder to manage. The
last straw to me is that the monolithic
dotfiles is not portable: not even
across my Linux workstation to the VPS.
LinuxJournal has a great tutorial about
vcsh for the rescue. After
poking around and some error and trial, it is now dead simple to duplicate the
brew install vcsh mr vcsh clone email@example.com/kunxi/mrrc.git mr mr update
The next step is to
chsh -s /bin/zsh; then launch vim. NeoBundle will prompt
to download and install the vim plugins, voilà.
Behind the scenes
It is quite impressive how concise vcsh is, mere 462 loc in shell as version
1.20130829 is. It leverages the awesome git to do all the heavy-lifting. When
you clone a remote repository
foo, vcsh does the following behind the scene:
- create a folder in
.config/vcsh/repo.d/foo.git, and export it as
$VCSH_BASEdirectory, i.e your home directory by default; and export it as
- Thus the work tree and git meta data, aka .git folder, are separated. We
git fetchto pull the remote repository into the
GIT_DIR, and merge the changes back to the
This approach allows us to share the
$HOME across multiple git repositories, a
perfect solution to address the dotfiles problem!
With the mechanism in the mind, we can explore other use cases to streamline the dotfiles.
Mount the submodule
If your dotfile depends on an external project, like NeoBundle.vim to .vimrc, you can use mr to mount the external project to the specified destination:
[$HOME/.config/vcsh/repo.d/neobundle.git] checkout = mkdir -p ~/.vim/bundle; VCSH_BASE=~/.vim/bundle/neobundle.vim vcsh clone https://github.com/Shougo/neobundle.vim neobundle
The trick here is to override the
VCSH_BASE environment variable, so the git
meta data is cloned in
$HOME/.config/vcsh/repo.d/neobundle.git, but the
working copy is merged in the specified bundle directory.
Divide and Merge
As the above examples shows, each git repository is an atomic configuration for a specific application. We can checkin the screenrc and tmuxrc, and pick whatever available in the target environment.
Some application supports configuration inclusion, then we can leave the
personal credentials to a private git repository and pick them with
The separation of the git meta data and working copy solves the dotfiles issues elegantly, just as the FTSE claims:
We can solve any problem by introducing an extra level of indirection.