Dotfiles are files and directories that define application configurations. They are preceded with a “.” which hides them, by default, within many file browsers. To maintain a uniform experience, users may aim to sync their dotfiles across development environments. This management process is often cumbersome, and is compounded by the number of machines a user frequently access’. Although historically I have a single laptop, where I favor simplicity over functionality, I am plagued by an addition for distro-hopping and fresh installs. This makes dotfile management important.
My dotfiles management approach is a blend of many solutions, most notably Atlassian’s dotfile tutorial. Basically it relies on (1) defining your $HOME
directory as a git repository, (2) renaming the git directory (e.x., $HOME/.dotfiles
), and (3) aliasing a command to automatically set this environment.
I encapsulate this functionality in a dotfiles script within my scripts repository. This script wraps git by overriding the init
and clone
commands with short sequences to manage the aforementioned environment. Then all other commands are forwarded to git using the line below:
git --git-dir=$HOME/.dotfiles --work-tree=$HOME "${args[@]}"
Here is the output of this scripts help
command:
hamersaw@ragnarok:~$ dotfiles help
USAGE: dotfiles COMMAND
COMMAND:
help display this help menu
clone <git-repo> clone an existing dotfiles repository
init initailize a new dotfiles repository
version display the application version
* forward arguments to git
Creating a new dotfiles repository
Initializing a fresh dotfiles repository using this script is very similar to a conventional git repository – call init
, make an initial commit, and push to a remote repository. The script aliases the init
command to setup a bare repository in the users $HOME
directory and configures it to not show untracked files (a personal preference).
# initialize new dotfiles repository
dotfiles init
# add a remote repository
dotfiles remote add <name> <url>
# redacted - make initial commit
# push local commits to remote repository
dotfiles push -u origin
Manage dotfiles
Non-overridden arguments, which are basically everything except init
and clone
, are forwarded to git. This means that git operations work more or less identical to a conventional git repository. Therefore, tracking the status, adding untracked changes or new files, committing these modifications, and pushing the commits works as shown below:
# view dotfiles modifications
dotfiles status
# add an untracked change
dotfiles add .config/foo/bar.yaml
# commit tracked repository changes
dotfiles commit -m "baz"
# push dotfiles to remote repo
dotfiles push
Clone an existing dotfiles repository
Syncing dotfiles between environments requires cloning the remote git repository within the new system. The script overrides the clone
command to setup a bare repository and again configures it not to show untracked files. Sometimes I have encountered git repository checkout conflicts, this is common when using different distros or replacing an existing configuration. Fortunately, git makes merging or replacing existing files simple by warning of any conflicts. With this setup it is typically easy to delete the existing dotfile to continue the checkout
command.
# setup tracking of remote repository
dotfiles clone <url>
# checkout all files within the remote repository
dotfiles checkout
This post is part 2 / 5 of the Script Series:
- Introduction
- A Script for Managing Dotfiles
- Due: A Kanban TODO List Script
- Scripting Your UI Color-Palette
- Password Management with Stash
4 day(s) offloaded in the 100DaysToOffload challenge.