Auto-sync, and Auto-symlink Dotfiles for Multiple OS with System Specific Values
There are more than a few systems to manage dotfiles (examples 1, 2, and 3).
I needed a system that would be compatible with Windows (WSL), Mac, and Linux.
I wanted to share some of the functionality between all OSes/systems, but I also wanted to keep some configurations/aliases to be OS specific and system specific.
Unlike the above solutions, I didn't want to install extra software just for this task.
I wanted to automatically have my my most recent changes on any machine, and I didn't want to manually copy (cp
) files to the expected destination directories.
I settled on a simple private git repo + symlink solution.
Below I've individually outlined how I implemented each feature of my system in the hope that others can pull each feature they want in ad-hoc.
Splitting files between OS/System
I put individual system configurations in a named file (ex: personal_wsl
), while keeping OS specific configurations in separate files (windowsspecific
, macspecific
, and linuxspecific
).
Then for any aliases I wanted to share across all OSes/systems I would place them in a commonzshrc
file.
At shell startup my .zshrc
file would be sourced, so I use that as a simple entry point for a specific machine, and as such I don't include each individual .zshrc
file in my dotfiles repo.
Thus for a Windows, Mac and Linux system the .zshrc
would respectively be:
# System specific source ...
source ~/dotfiles/windowsspecific
source ~/dotfiles/commonzshrc
# source ~/dotfiles/machinespecific
# System specific source ...
source ~/dotfiles/macspecific
source ~/dotfiles/commonzshrc
# source ~/dotfiles/machinespecific
# System specific source ...
source ~/dotfiles/linuxspecific
source ~/dotfiles/commonzshrc
# source ~/dotfiles/machinespecific
Auto-pull
commonzshrc
:
alias dotpull="git -C ~/dotfiles pull"
alias dotpush="git -C ~/dotfiles push"
alias dotcommit="git -C ~/dotfiles add -A && git -C ~/dotfiles commit -m \"Default common commit message\""
alias dotcommitandpush="dotcommit && dotpush"
alias dotcap="dotcommit && dotpush"
# SSH agent initialize
{ eval `ssh-agent`; ssh-add; } &>/dev/null
# Try and pull the most recent version of the files
# This should give errors if it hits a merge conflict
{ git -C ~/dotfiles pull } 1>/dev/null
I still have to manually push any changes (dotcap
), but in practice that hasn't been a big issue.
Auto-symlink
commonzshrc
:
# Pull logic ...
{ln -s ~/dotfiles/.tmux.conf ~/.tmux.conf} &>/dev/null
{ln -s ~/dotfiles/.gitconfig ~/.gitconfig} &>/dev/null
{ln -s ~/dotfiles/.vimrc ~/.vimrc} &>/dev/null