Syncing configurations across different computers
This post describes my strategy to sync configuration files (dotfiles) across different computers that I use. I’m almost always using Linux, so I haven’t considered extending this to any other OS type.
Git + GNU stow
I use Git for version control, keeping a public remote repository on SourceHut at https://git.sr.ht/~jayc/dotfiles. Git allows me to use local branches and a private remote for changes that I don’t want to share.
Each individual configuration file is symlinked to a local checkout of my
dotfiles git repo. I used to add and remove this manually using the ln
command. Now I make use of GNU Stow to manage the symlinks.
From my dotfiles repo, I can simply run stow PACKAGE
to create symlinks in
the correct place(s). The placement is determined by the --target=~
set in my
.stowrc
combined with the directory structure of my dotfiles repo.
For example, let’s take a look at my git configuration. In my dotfiles repo it has the following directory structure:
dotfiles$ tree -a git
git
└── .config
└── git
├── config
└── gitignore_global
3 directories, 2 files
When I run stow git
, it will create symlinks:
dotfiles$ stow git
dotfiles$ ls -gGh --time-style='+' ~/.config/git
total 8.0K
lrwxrwxrwx 1 57 config -> ../../src/git.sr.ht/~jayc/dotfiles/git/.config/git/config
lrwxrwxrwx 1 67 gitignore_global -> ../../src/git.sr.ht/~jayc/dotfiles/git/.config/git/gitignore_global
💡 Note: An alternate approach to symbolic links would be to XDG_
environment variables to point to the appropriate dotfiles repository paths.
I haven’t experimented with this (yet), but am interested in trying it. Check
out this Arch Linux XDG user directories wiki page for more info.
Automated first time setup
I maintain a bash script to automate first time configuration: setup.sh. This sets up my development environment from scratch.
⚠️ Warning: My personal name, username, e-mail, etc. is hard coded in various places. The setup script as-is is intended for my own personal use. (TODO: Set these are global vars at the top of the script 🙂)
The script does the following:
- Install software packages.
- Preference is to install as much as possible in my
$HOME
directory. This simplifies setup in environments that I don’t have authority to install system level packages.
- Preference is to install as much as possible in my
- Clone my dotfiles repo.
- Call GNU Stow to create soft links to each configuration file.
I still prefer to configure things like private SSH and GPG keys manually.
Local customizations and overrides
Sometimes I make Git configuration changes that only apply to a local system.
For these I keep a local config include in my Git config. I use different PGP
signing keys on each computer, so this is a great place to set the
signingkey
.
[include]
path = ~/.config/git/local_config_overrides
I also find conditional includes to be very convenient. For example, IBM
has a private GitHub Enterprise instance which always requires authentication.
I keep a includeIf
in my local Git config based on a repository’s path to set
a special Git config.
[includeIf "gitdir:~/src/github.ibm.com/"]
path = ~/.config/git/config-ibm
Post history
Date | Description |
---|---|
2024-01-17 | Refactored to describe GNU Stow and local Git configs |
2023-11-07 | Fixed typos / added details |
2023-09-26 | Initial publish |