How to Sync Dotfiles Across Multiple Machines Using Git and Dotbot
You can sync dotfiles across multiple machines by storing configurations in a Git repository, using Dotbot to create symbolic links, and leveraging Git hooks to automatically reapply changes whenever you pull updates.
The issmirnov/dotfiles repository demonstrates a robust pattern to sync dotfiles across multiple machines using a combination of Git version control and the Dotbot symlink manager. This approach treats your home directory configuration as source code, enabling consistent environments across macOS and Linux with minimal manual intervention.
Bootstrap a New Machine
To establish your dotfiles on a fresh system, clone the repository into ~/.dotfiles and execute the installer:
git clone https://github.com/issmirnov/dotfiles.git ~/.dotfiles
~/.dotfiles/install
The install script bootstraps Dotbot and executes the appropriate configuration for your operating system. As shown in lines 10-22 of the script, it initializes submodules and invokes Dotbot with the correct config file:
git submodule update --init --recursive "$DOTBOT_DIR"
"${BASEDIR}/${DOTBOT_DIR}/${DOTBOT_BIN}" -d "${BASEDIR}" -c "default${CONFIG_SUFFIX}"
# OS-specific configuration
if [[ $OSTYPE == 'linux-gnu' ]]; then
"${BASEDIR}/${DOTBOT_DIR}/${DOTBOT_BIN}" -d "${BASEDIR}" -c "ubuntu${CONFIG_SUFFIX}"
elif [[ $OSTYPE == darwin* ]]; then
"${BASEDIR}/${DOTBOT_DIR}/${DOTBOT_BIN}" -d "${BASEDIR}" -c "osx${CONFIG_SUFFIX}"
fi
How Dotbot Manages Cross-Machine Consistency
Dotbot reads default.conf.yaml to create symbolic links from your home directory to the repository files. This ensures that every machine maintains the exact same file structure without duplicating configuration data.
The link: section in default.conf.yaml defines how files like .zshrc or .vimrc map to their counterparts in ~/.dotfiles/. When you run the installer, Dotbot idempotently creates these symlinks, making it safe to re-run the script after pulling updates.
Automated Synchronization with Git Hooks
The repository includes a post-checkout hook at git/hooks/post-checkout that detects changes to any *.conf.yaml file or other tracked configurations. When you pull updates that modify these files, the hook automatically executes ~/.dotfiles/install to re-link dotfiles and apply changes immediately.
This hook also handles auxiliary tasks such as updating Vim plugins, rebuilding the bat cache, and regenerating i3 configuration files. The relevant logic uses a check_run function to monitor specific file patterns and trigger the appropriate actions.
The One-Command Update Workflow
For daily synchronization, the gld alias defined in zsh/aliases/utilities.zsh (lines 29-30) combines pulling, submodule updates, and environment reloading:
alias gld='cd ~/.dotfiles && git pull && \
git submodule update --init --recursive && \
zgen update && popd'
Running gld on any machine fetches the latest changes and triggers the post-checkout hook, which automatically re-runs the installer if configuration files changed. This single command keeps your entire fleet of machines synchronized without manual linking.
Making Changes on Any Machine
To propagate configuration changes across your machines:
-
Edit the relevant file in
~/.dotfiles(e.g.,zsh/config/aliases.zsh). -
Commit and push your changes:
cd ~/.dotfiles git add zsh/config/aliases.zsh git commit -m "Add new alias for git status" git push -
On other machines, run
gldto pull and automatically apply the updates.
Because the post-checkout hook monitors *.conf.yaml files, any structural changes to your dotfile layout are immediately re-linked without additional commands.
OS-Specific Configurations
The install script automatically detects the operating system via $OSTYPE and loads additional Dotbot configurations. Linux systems process ubuntu.conf.yaml while macOS systems process osx.conf.yaml, allowing you to maintain platform-specific settings alongside your common base configuration.
This detection happens within the main install script, ensuring that cross-platform differences in paths or package managers are handled transparently during the sync process.
Minimal Installation for Zsh Only
If you only need the shell environment on a temporary or lightweight machine, use the minimal installation path:
git clone https://github.com/issmirnov/dotfiles.git ~/.dotfiles
~/.dotfiles/minstall
The minstall script reads minimal.conf.yaml, which contains only essential link: entries for Zsh and Git hooks, skipping window manager and editor configurations.
Summary
- Clone the repository to
~/.dotfilesand run./installto bootstrap any new machine with your complete environment. - Dotbot creates idempotent symbolic links defined in
default.conf.yaml, ensuring consistent file layouts across hosts. - The Git
post-checkouthook atgit/hooks/post-checkoutautomatically re-runs the installer when you pull changes that affect configuration files. - Use the
gldalias fromzsh/aliases/utilities.zshto pull updates, refresh submodules, and trigger automatic re-linking in one command. - OS-specific branches in the
installscript handle platform differences between macOS and Linux automatically.
Frequently Asked Questions
What is Dotbot and why use it for dotfiles?
Dotbot is a lightweight tool that automates the creation of symbolic links and execution of shell commands based on YAML configuration files. According to the issmirnov/dotfiles source code, using Dotbot ensures that symlinks from your home directory to the repository are created consistently and idempotently across every machine, eliminating manual copying or path management errors.
How do Git hooks automate dotfile synchronization?
The post-checkout hook in git/hooks/post-checkout monitors for changes to *.conf.yaml files and other tracked configurations after every Git operation that updates the working directory. When detected, the hook automatically executes ~/.dotfiles/install, ensuring that pulled changes are immediately reflected in your home directory without requiring manual intervention.
Can I use this setup on macOS and Linux simultaneously?
Yes, the install script detects the operating system via the $OSTYPE environment variable and automatically applies OS-specific configurations. Linux systems load ubuntu.conf.yaml while macOS loads osx.conf.yaml, allowing the same repository to support divergent platform requirements while maintaining a synchronized core configuration.
What happens if I forget to run the install script after pulling?
If you use the gld alias or standard git pull commands, you do not need to remember to run the install script manually. The post-checkout Git hook automatically detects when configuration files change and re-runs the installer for you. However, if you disable hooks or use git pull --no-verify, you can manually execute ~/.dotfiles/install at any time to re-apply your configuration.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →