stow + git = version controlled dot files
Today I set up my system to use version controlled dotfiles via stow and git.
What are 'dotfiles'? They are configuration files that allow one to customize the behaviour of programs on Linux. They specify key-bindings, colour themes, etc. in plain text files. Often they are very personal. It is a little dizzying to use a familiar piece of software without the usual dotfiles in place.
What is GNU stow? It is a symlink manager that allows you to deploy and remove collections of symlinks conveniently. One creates several "packages" in directories, and then stow manages the task of creating or removing symlinks to the various files in these packages.
What is git? Git is Linus Torvald's other wunderkind. It is a version control system that tracks how files have been modified. Presently, it is the industry standard.
Example stow Usage
stow manages packages of files in the following way: A package is just a directory of files. When you stow a package, it will create symlinks to all the files in the package together with the appropriate file hierarchy.
For example, suppose you have the following file structure:
~/dotfiles/foo ├── .foorc └── .config └── foo-config ~/dotfiles/bar/ ├── .bar.ini └── .config └── bar ├── bar-config └── bar.theme
That is, you've got a dotfiles directory containing two packages foo and bar. Notice that both packages contain directories called .config. These directories allow you to seperate out the parts of the package foo that go in to ~/.config and the parts of bar that go in to ~/.config
If you enter the directory ~/dotfiles/ and run stow foo it will create symlinks at ~/.foorc and ~/.config/foo-config which point to the corresponding files in your dotfiles directory.
If you enter the directory ~/dotfiles/ and run stow bar it will create symlinks at ~/.bar.ini and ~/.config/bar/bar-config and ~/.config/bar/bar.theme which point to the corresponding files in your dotfiles directory.
(By default stow installs the package the directory containing the current working directory. One can change this using stow -t TARGET.)
Managing Dotfiles with Stow and Git
I followed the advice these people put up:
To get started:
- Make a ~/dotfiles/ directory.
- Initialize a git repo in that directory using git init.
- Make a sub-directory for each package of configuration files you want to track. E.g: vim, screen, mc.
- Copy the configuration files you want to track in to each ~/dotfiles/package/ directory.
- Run stow --adopt package to adopt current dotfiles for each package.
- Run git add . to add all the new file to the git repo.
- Run git commit to commit the new files.
- Run stow package to stow each package.
To maintain your repo:
- Everytime you change a dotfile, update the git repo using git add .changed-dotfile
- Commit when you feel like it.
Other useful things:
- stow -D package removes the symlinks to a package
- stow -R package to reload package. It removes, and then re-stows it.
ssh and vim
Two things that hose dotfiles I'd like to track are ssh and vim. Unfortunately, ~/.ssh/ and ~/.vim/ both contain sensitive data. One has my private keys, and the other has temporary files related to potentially sensitive documents.
Thus, I only track the relevant non-sensitive data in ~/dotfiles/
/home/pgadey/dotfiles/ssh/: .ssh /home/pgadey/dotfiles/ssh/.ssh: config known_hosts /home/pgadey/dotfiles/vim/: .vim .vimrc snippets plugin /home/pgadey/dotfiles/vim/.vim/plugin: emmet.vim matchit.vim snipMate.vim surround.vim /home/pgadey/dotfiles/vim/.vim/snippets: tex.snippets vim.snippets
$ mkdir ~/dotfiles/ # setup the package of dotfiles for foo $ mkdir ~/dotfiles/foo/ $ cp ~/.foo ~/dotfiles/foo/ $ mkdir ~/dotfiles/foo/config/ $ cp ~/.config/foo-config ~/dotfiles/foo/.config/foo-config # adopt the currently existing files for the package foo $ cd ~/dotfiles/ $ stow --adopt foo # create symlinks for the package foo $ stow foo