Managing Config Files with Git
Keeping config files synchronized across multiple computers can be a pain. Simply putting config files into a git repository and cloning it on all your computers still requires you to make symlinks to your config files. I wanted an easier solution, so I wrote some Makefiles to make symlinking new files almost automatic.
Goals:
- Config files are stored in subdirectories at
~/config
- Each subdirectory has rules on where to symlink the config files (eg.
~/config/home
makes symlinks in~
) - Subdirectories are handled automatically (eg.
~/config/home/.ssh/config
makes a symlink in~/.ssh/config
) - Symlinks are updated by running
make install
in directories with Makefiles - Support for both GNU Make and BSD Make
Set up the repository on the server:
$ cd /path/to/git/repositories
$ mkdir config.git
$ cd config.git
$ git init --bare
Clone the repository to a machine and set it up:
# Substitute the location of your git repository
$ git clone http://git.example.com/config
$ cd config
# Make a directory to store config files from ~
$ mkdir home
$ cd home
# Add some files
$ cp ~/.gitconfig .
$ cp ~/.tmux.conf .
$ cp ~/.vimrc .
$ mkdir .ssh
$ cp ~/.ssh/config .ssh
Now, add the Makefiles. Here is config/config.mk
:
GIT_LS_COMMAND= git ls-files | grep -v -e Makefile
GIT_FILES= $(shell $(GIT_LS_COMMAND)) # GNU Make compatible
GIT_FILES!= $(GIT_LS_COMMAND) # BSD Make compatible
FILES?= $(GIT_FILES)
CURDIR?= $(.CURDIR) # BSD Make compatibility
COMMAND?= ln -sf
DEST?= $(HOME)
.PHONY: all
all:
@echo Usage:
@echo make install - Run default command set in the Makefile \(default is to symlink\)
.PHONY: install $(FILES)
install: $(FILES)
$(FILES):
@echo $(DEST)/$@
@if test ! -d `dirname "$(DEST)/$@"`; then \
mkdir -p `dirname "$(DEST)/$@"`; \
fi
@if test -e "$(DEST)/$@"; then \
rm "$(DEST)/$@"; \
fi
@$(COMMAND) "$(CURDIR)/$@" "$(DEST)/$@"
And config/home/Makefile
:
COMMAND= ln -sf
DEST= $(HOME)
include ../config.mk
The makefile only tracks files which are added to git, so make sure to add and commit all the config files you want to track. You can add more directories to the repository and make a Makefile for each. By editing DEST
variable in the Makefile, you can set the destination directory, and by editing COMMAND
to cp
for instance, you can copy files instead of symlinking.
To install the config files on another computer after committing and pushing the repository:
# Substitute the location of your git repository
$ git clone http://git.example.com/config
$ cd config/home
$ make install
Easy as that! Hope this helps someone.