If you are at all like me, you have customised configuration files for various CLI programs, so-called "dotfiles" such as ~/.zshrc or ~/.vimrc. If you use more than one computer system, you probably re-use these dotfiles on many of them. Unfortunately, this can make management of the dotfiles, and keeping them up-to-date on differing systems, challenging. Particularly if you use them on a large number of computers.

One solution is to use version control to manage these files, such as with subversion, CVS, or git. This can easily be accomplished by making a subversion repository for storing these files. For instance, on a "master" system that is accessible by the others (via ssh, perhaps), create the repository and store the files in it. A working copy of the repository might exist in ~/svn/configs/ with sub-directories for each type of dotfile: ~/svn/configs/zsh, ~/svn/configs/procmail, ~/svn/configs/zsh, and so on.

Using subversion as a means of distributing these files to varying computers works well, but copying files and keeping them up-to-date may be cumbersome. You could use symlinks so that the actual dotfile points to the working copy: such as symlinking ~/.zshrc to ~/svn/configs/zsh/zshrc.

Another method is to use the standard "make" command to manage them. This solution takes a bit of time to set up at the outset, but only really has to be done once (and updated for new dotfiles you may create later). What follows is an example Makefile that would be placed in the top-level directory of the working copy, such as ~/svn/configs/Makefile:

# Makefile to update dot-files
# $Id$
 
ifndef SRCDIR
SRCDIR := $(shell pwd)
endif
 
DOTDIRS = $(shell find . -type d -depth 1 \! -name .svn | cut -d ‘/’ -f 2 )
REPO_FETCHMAILRC = $(SRCDIR)/fetchmail/fetchmailrc
LOCAL_FETCHMAILRC = $(HOME)/.fetchmailrc
 
REPO_ZSHRC = $(SRCDIR)/zsh/zshrc
REPO_ZSHENV = $(SRCDIR)/zshenv
REPO_ZSH_HOSTS = $(SRCDIR)/zsh_hosts
LOCAL_ZSHRC = $(HOME)/.zshrc
LOCAL_ZSHENV = $(HOME)/.zshenv
LOCAL_ZSH_HOSTS = $(HOME)/.zsh_hosts
 
.PHONY: fetchmail zsh
 
fetchmail:
 @test -d $(SRCDIR)/fetchmail || ( echo “fetchmail sourcedir does not exist!” ; exit 1 )
 cp -afv $(REPO_FETCHMAILRC) $(LOCAL_FETCHMAILRC)
 
fetchmail-diff:
 @test -d $(SRCDIR)/fetchmail || ( echo “fetchmail sourcedir does not exist!” ; exit 1 )
 @diff -uN $(REPO_FETCHMAILRC) $(LOCAL_FETCHMAILRC) || ( echo “”)
 
fetchmail-commit:
 @test -d $(SRCDIR)/fetchmail || ( echo “fetchmail sourcedir does not exist!” ; exit 1 )
 svn commit $(SRCDIR)/fetchmail
 
fetchmail-updaterepo:
 @test -d $(SRCDIR)/fetchmail || ( echo “fetchmail sourcedir does not exist!” ; exit 1 )
 cp -afv $(LOCAL_FETCHMAILRC) $(REPO_FETCHMAILRC)
 
zsh:
 @test -d $(SRCDIR)/zsh || ( echo “zsh sourcedir does not exist!” ; exit 1 )
 cp -afv $(REPO_ZSHRC) $(LOCAL_ZSHRC)
 cp -afv $(REPO_ZSHENV) $(LOCAL_ZSHENV)
 cp -afv $(REPO_ZSH_HOSTS) $(LOCAL_ZSH_HOSTS)
 
zsh-diff:
 @test -d $(SRCDIR)/zsh || ( echo “zsh sourcedir does not exist!” ; exit 1 )
 @diff -uN $(REPO_ZSHRC) $(LOCAL_ZSHRC) || ( echo “”)
 @diff -uN $(REPO_ZSHENV) $(LOCAL_ZSHENV) || ( echo “”)
 @diff -uN $(REPO_ZSH_HOSTS) $(LOCAL_ZSH_HOSTS) || ( echo “”)
 
zsh-commit:
 @test -d $(SRCDIR)/zsh || ( echo “zsh sourcedir does not exist!” ; exit 1 )
 svn commit $(SRCDIR)/zsh
 
zsh-updaterepo:
 @test -d $(SRCDIR)/zsh || ( echo “zsh sourcedir does not exist!” ; exit 1 )
 cp -fv $(LOCAL_ZSHRC) $(REPO_ZSHRC)
 cp -fv $(LOCAL_ZSHENV) $(REPO_ZSHENV)
 cp -fv $(LOCAL_ZSH_HOSTS) $(REPO_ZSH_HOSTS)
 
install: fetchmail zsh
 
diff: fetchmail-diff zsh-diff
 
commit: fetchmail-commit zsh-commit
 
updaterepo: fetchmail-updaterepo zsh-updaterepo
 
help:
 @echo “Usage: make ”
 @echo “Available targets are:”
 @echo “help                          Show this text”
 @echo “install                       Install all dotfiles”
 @echo “diff                          Diff all dotfiles”
 @echo “updaterepo                    Update repository from local dotfiles”
 @echo “”
 @echo “The following dotfiles are available for use with the below commands:”
 @echo “   $(DOTDIRS)”
 @echo “”
 @echo “[dotfile]-install             Install [dotfile] configs”
 @echo “[dotfile]-diff                Diff local [dotfile] configs to that in repository working copy”
 @echo “[dotfile]-commit              Commit [dotfile] from working copy to repository”
 @echo “[dotfile]-updaterepo          Update working copy for [dotfile] from local files”

This Makefile handles zsh and fetchmail and allows for a variety of functions (use "make help" if you need a refresher of the commands). With it, you can manage all the dotfiles at once using the "make install" or "make diff" commands. You can also operate on single dotfile types alone with "make zsh-install" or "make fetchmail-commit". This Makefile, of course, assumes the use of subversion and also assumes you are in ~/svn/configs/ (or wherever it is installed) when you call it.

The REPO_* and LOCAL_* variables are pointers to the various dotfiles, used largely to reduce typing in the Makefile. The Makefile itself is quite self-explanatory and can easily be customised to handle all kinds of files. There may be more efficient ways to create dynamic assignments to reduce the size and complexity of the Makefile; if you have any suggestions for improvement, please share them.

Open Sourcery This was published in Open Sourcery, check every Monday for more stories

Related links

Leave a comment

You must read and type the 6 chars within 0..9 and A..F

* indicates mandatory fields.

Log in


Sign up | Forgot your password?

  • Staff Microsoft shows off IE9 preview

    This week, highlights from Microsoft's MIX10 conference and more in the Roundup. Read more »

    -- posted by Staff

  • Chris Duckett IE9's H.264 vote killed Ogg

    In a split decision by the judges, the winner of the W3C/WHATWG video codec consensus is H.264, taking home the future of video playback on the internet while loser Ogg goes home with nothing but thoughts of what might have been. Read more »

    -- posted by Chris Duckett

  • Staff Google launches Apps Marketplace

    Google launches and app store, while Mozilla plans to re-write its open-source license. More of this week's news in the Roundup. Read more »

    -- posted by Staff

What's on?

  • Optus Deal

    Broadband + home phone + PlayStation®3 in a single package price!