Dotfiles: keep your shell setup in git
Put .bashrc, .zshrc, .gitconfig and your editor settings into a git repository so a new machine is set up in minutes: a bare-repo layout, a simple symlink layout, and what must never be committed.
Drafted with AI from official documentation. Scripts were run in a test environment and repository links verified. Awaiting a human check. Did it work for you? Last edited Outdated?
Dotfiles are the hidden configuration files in your home directory: .bashrc, .zshrc, .gitconfig, .vimrc, .config/nvim, .ssh/config and so on. Years of aliases and settings live in them, and they vanish the day a laptop dies. Keeping them in a git repository gives you history, a backup and a one-command setup on every new machine or server.
Before you start
- You need git and a remote you control (GitHub, GitLab, Gitea or a bare repo on your own server).
- Decide now what is secret.
~/.ssh/id_*,~/.aws/credentials,~/.netrc,.envfiles, tokens inside.gitconfigor.npmrcand shell history must never go into the repo. If the repository is public, treat even your.ssh/confighost list as sensitive.
Layout 1: a bare repository with a git alias
This layout tracks files directly in your home directory without turning ~ itself into a repository. The git directory lives in ~/.dotfiles and a shell alias points git at it.
git init --bare "$HOME/.dotfiles"
alias dot='git --git-dir="$HOME/.dotfiles" --work-tree="$HOME"'
dot config status.showUntrackedFiles no
dot add .bashrc .zshrc .gitconfig .vimrc .config/nvim
dot commit -m "Initial dotfiles"
dot remote add origin [email protected]:you/dotfiles.git
dot push -u origin main
Add the alias dot=... line to your .bashrc or .zshrc (which is itself tracked) so it exists everywhere. status.showUntrackedFiles no keeps dot status from listing every file in your home directory.
On a new machine:
git clone --bare [email protected]:you/dotfiles.git "$HOME/.dotfiles"
alias dot='git --git-dir="$HOME/.dotfiles" --work-tree="$HOME"'
dot checkout
dot config status.showUntrackedFiles no
If dot checkout complains that existing files would be overwritten (a fresh system often ships a default .bashrc), move those files aside first: mkdir -p ~/.dotfiles-backup && mv ~/.bashrc ~/.dotfiles-backup/, then run the checkout again.
Layout 2: a normal repository plus symlinks
The other common approach is an ordinary repo in ~/dotfiles with a small install script that symlinks each file into place. It is easier to understand and to browse, and GNU Stow can do the linking for you.
mkdir -p ~/dotfiles/bash ~/dotfiles/git
mv ~/.bashrc ~/dotfiles/bash/.bashrc
mv ~/.gitconfig ~/dotfiles/git/.gitconfig
cd ~/dotfiles && git init && git add . && git commit -m "Initial dotfiles"
# Link everything back with GNU Stow (brew install stow / apt install stow)
cd ~/dotfiles
stow bash git
ls -l ~/.bashrc # -> dotfiles/bash/.bashrc
Machine-specific and secret settings
Keep the shared repo clean and let each machine add its own layer. At the end of .bashrc or .zshrc, source an untracked local file if it exists:
[[ -f "$HOME/.bashrc.local" ]] && source "$HOME/.bashrc.local"
Git supports the same idea natively. Keep ~/.gitconfig tracked and put your work email or signing key in an untracked file:
# in ~/.gitconfig (tracked)
[include]
path = ~/.gitconfig.local
[includeIf "gitdir:~/work/"]
path = ~/.gitconfig.work
Add a .gitignore inside the repo (or a global one at ~/.config/git/ignore) that lists the files you never want tracked, for example .ssh/id_*, .*_history, .netrc and *.local. Before the first push, run dot ls-files or git ls-files and read the list.
Check that it works
- Open a new terminal and confirm your aliases and prompt are there.
- Run
git ls-files(ordot ls-files) and confirm no key, token or history file is listed. - Clone the repository into a throwaway VM or container and run the setup steps; fix anything that assumed a tool you forgot to install.
Next steps
- Add an
install.shthat installs the packages your config depends on (fzf,ripgrep,stow) and then links the files. - Use branches or
includeIffor work versus personal machines instead of copying the repo. - If you ever committed a secret, rotate it. Removing it from history is not enough once it has been pushed.
Official documentation
Did this work for you?
No votes yet. Be the first.
If it did not work, the report form below tells the editors what went wrong.
See also
- 0032 First-time Git setup: name, email, default branch, SSH or HTTPS Tell Git who you are, pick sensible defaults, and choose between SSH and HTTPS for GitHub. Includes a small script that applies… Beginner · Step by step · Linux, macOS, Windows Script Setup 15 Oct 2026
- 0033 The everyday Git workflow: status, add, commit, push, pull Git moves your changes through three places: the working folder, the staging area, and the commit history. These five commands, plus .gitignore… Beginner · Explains an idea · Any system Article Housekeeping · Setup 15 Oct 2026
- 0262 Make your first pull request: Git and GitHub from first commit to merged change A complete beginner's path through Git and GitHub: set up Git, make commits, ignore files, use branches, push to GitHub, open a… Beginner · Guided project · Any system Article Branching & rebasing · Pull requests · Setup 15 Oct 2026
- 0318 Fix: fatal: not a git repository Git looked in the current directory and every parent for a .git folder and found none. You are in the wrong directory,… Beginner · Fixes an error · Any system Article Common errors · Setup 15 Oct 2026
- 0381 pre-commit hooks: catch mistakes before they are committed Install the pre-commit framework, configure hooks for whitespace, YAML and JSON syntax, large files, leaked private keys, Python linting and shellcheck, run… Beginner · Step by step · Linux, macOS, Windows Article Pipelines, runners & hooks · Setup 15 Oct 2026
- 0390 Install Git on Linux, macOS and Windows Install Git from your package manager, Xcode's command line tools or the Windows installer, confirm the version, and do the one-time configuration… Beginner · Step by step · Linux, macOS, Windows Article Installing languages & tools · Setup 15 Oct 2026
History
Every saved edit is kept. The plot on the sleeve draws one line per edit. Open any edit to see exactly what changed.
- Dominik +4,211 chars