Dotfiles & Developer Environment. Supports Ubuntu2004+, macOS Catalina+, Windows 10 w WSL
symlink-free dotfiles using the
$HOME
as thegit work-tree
technique
Used daily on macOS & BluefinDX/Bazzite/BazziteDX Fedora Linux systems.
git clone --bare https://github.com/jthegedus/dotfiles.git "$HOME/.dotfiles.git"
alias dotfiles='git --git-dir="$HOME/.dotfiles.git/" --work-tree="$HOME"'
dotfiles checkout
Handle Conflicts: If the checkout
command fails due to existing files you can perform one of two actions:
Repeat the above for any other reported conflicting folders/files.
# eg: backup the existing .config directory and git checkout
mv ~/.config ~/.config.bak
dotfiles checkout
dotfiles checkout -f
Configure the repository to ignore other untracked files in $HOME
:
dotfiles config --local status.showUntrackedFiles no
This creates the following files in your $HOME
directory:
# in $HOME
.config/** <-- configuration files
.dotfiles/ <-- template files for this repo
.dotfiles.git/ <-- .git dir for this repo
.gitconfig <-- core git config file
.gitconfig.proj <-- created from .dotfiles/*.template
README.md <-- this repo README
.zshenv <-- tell ZSH to look at ~/.config/zsh/*
cp ~/.dotfiles/.gitconfig.project.template ~/.gitconfig.proj
name
and email
properties in ~/.gitconfig.proj
gpg
, commit
, tag
, and user
sections from the filesigningkey
properties in ~/.gitconfig.proj
Install tools in .config/brewfile/Brewfile*
using Homebrew and Homebrew File:
brew install rcmdnk/file/brew-file
brew file install
.zshenv
.config/brewfile/Brewfile*
I use Development Containers in most projects to manage project-specific dependencies. This keeps my OS installation relatively clean. Since devcontainers can mount your home directory, this repository contains some configuration files for tooling I commonly use within devcontainers that may not appear on my machine and therefore Brewfile.
The list of tools I use as a base on each system/OS are:
Use the following tools to change the shell on most Unix systems:
chsh -s $(which <DESIRED_SHELL>) $USER
sudo usermod --shell $(which <DESIRED_SHELL) $USER
(when chsh
is not available)I use the .gitconfig
conditional includeIf
directive to manage per-project Git settings in a separate configuration file to the ones committed to this repository (see the template in .dotfiles/.gitconfig.project.template
directory for an example).
This is useful to manage different usernames, emails or authentication settings per project.
The includeIf
directive allows for the following conditionals:
gitdir:<pattern>
: Matches if the Git directory path matches the pattern, useful for applying settings to projects in specific locations (e.g., ~/work/
).onbranch:<branch-name-pattern>
: Matches if the current branch name matches the pattern, useful for branch-specific workflows or settings.hasconfig:remote.<name>.url:<pattern>
: Matches if a remote’s URL matches the pattern, useful for loading different user configs for work vs. personal projects or different Git platforms.See the documentation for full explanations - https://git-scm.com/docs/git-config#_conditional_includes
As an example, this configuration applies the same config for remotes using GitHub via SSH & HTTPS, with another config for a singular organisation remote on BitBucket:
# git settings - GitHub SSH & HTTPS
[includeIf "hasconfig:remote.*.url:https://github.com/**"]
path = ~/.gitconfig.proj
[includeIf "hasconfig:remote.*.url:git@github.com:**"]
path = ~/.gitconfig.proj
# git settings - project specific SSH
# NOTE: ensure this does not overlap with any other includeIf conditions
[includeIf "hasconfig:remote.*.url:git@bitbucket.org:<organisation_name>/**"]
path = ~/<org_name>/.gitconfig.proj_<project_name>
This includes the specified configuration file if the repository you are running git
commands against ( where the .git
directory is) matches the provided pattern.
Here is a quick guide to creating your own bare repository for dotfiles using the $HOME
as the git work-tree
technique:
git init --bare $HOME/.dotfiles.git
alias dotfiles='git --git-dir=$HOME/.dotfiles.git/ --work-tree=$HOME'
dotfiles config --local status.showUntrackedFiles no
dotfiles remote add origin git@github.com:<username>/<repo>.git
Now add any of your existing .config
files, track with git
& push:
cd $HOME
dotfiles add .config/starship.toml
dotfiles status
dotfiles commit -m "feat: capture starship configuration"
dotfiles push
For more examples and inspiration see the HackerNews post where I learnt about this technique.
NB: The dotfiles
alias is a temporary alias for the current shell session. I include it in my Fish & ZSH configuration files in this repository as a permanent way to quickly interact with my dotfiles repository.
NB: Even though all files are untracked thanks to the status.showUntrackedFiles no
setting, I still recommend using .gitignore
files when the configuration you wish to include is in a directory with other files you do not wish to include. This is purely a precautionary measure to avoid accidents. Though allow-listing files in .gitignore
is a recommended practice.
Zero-Clause BSD
=============
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE
FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.