Dotfiles

User-specific application configuration is traditionally stored in so called dotfiles (files whose filename starts with a dot). It is common practice to track dotfiles with a version control system such as Git to keep track of changes and synchronize dotfiles across various hosts. There are various approaches to managing your dotfiles (e.g. directly tracking dotfiles in the home directory v.s. storing them in a subdirectory and symlinking/copying/generating files with a shell script or a dedicated tool). Apart from explaining how to manage your dotfiles this article also contains a list of dotfile repositories from Arch Linux users.

Tracking dotfiles directly with Git

The benefit of tracking dotfiles directly with Git is that it only requires Git and does not involve symlinks. The disadvantage is that host-specific configuration generally requires merging changes into multiple branches.

The simplest way to achieve this approach is to initialize a Git repository directly in your home directory and ignoring all files by default with a gitignore(5) pattern of *. This method however comes with two drawbacks: it can become confusing when you have other Git repositories in your home directory (e.g. if you forget to initialize a repository you suddenly operate on your dotfile repository) and you can no longer easily see which files in the current directory are untracked (because they are ignored).

An alternative method without these drawbacks is the "bare repository and alias method" popularized on Ask Hacker News: What do you use to manage your dotfiles?, which just takes three commands to set up:

$ git init --bare ~/.dotfiles
$ alias config='/usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME'
$ config config status.showUntrackedFiles no

You can then manage your dotfiles with the created alias. If you are using Bash and would like bash completion for this alias, simply install bash-complete-aliasAUR, then add the alias and the following line to your ~/.bashrc.

$ complete -F _complete_alias config

Another way to get completion in bash is adding the following to your ~/.bashrc (taken from ):

source /usr/share/bash-completion/completions/git
__git_complete config __git_main
Tip: To avoid accidentally commiting confidential information, see Git#Filtering confidential information.

Host-specific configuration

A common problem with synchronizing dotfiles across various machines is host-specific configuration.

With Git this can be solved by maintaining a master branch for all shared configuration, while each individual machine has a machine-specific branch checked out. Host-specific configuration can be committed to the machine-specific branch; when shared configuration is modified in the master branch, the per-machine branches need to be rebased on top of the updated master.

In configuration scripts like shell configuration files conditional logic can be used. For example, Bash scripts (i.e. .bashrc) can apply different configuration depending on the machine name (or type, custom variable, etc.):

if [[ "$(hostname)" == "archlaptop" ]]; then
    # laptop specific commands here
else
    # desktop or server machine commands
fi

Similar can also be achieved with .Xresources.

If you find rebasing Git branches too cumbersome, you may want to use a tool that supports file grouping, or if even greater flexibility is desired, a tool that does processing.

Tools

File grouping
How configuration files can be grouped to configuration groups (also called profiles or packages).
Processing
Some tools process configuration files to allow them to be customized depending on the host.
NamePackageWritten inFile groupingProcessing
chezmoi chezmoiGodirectory-basedGo templates
dot-templater Rustdirectory-basedcustom syntax
dotdrop Pythonconfiguration fileJinja2
dotfiles PythonNoNo
Dots Pythondirectory-basedcustom append points
dotter Rustconfiguration fileHandlebars
dt-cli Rustconfiguration fileHandlebars
GNU Stow Perldirectory-basedNo
Mackup Pythonautomatic per applicationNo
mir.qualia PythonNocustom blocks
rcm Perldirectory-based (by host or tag)No

Tools wrapping Git

If you are uncomfortable with Git, you may want to use one of these tools, which abstract the version control system away (more or less).

NamePackageWritten inFile groupingProcessing
dotbare Shell ()repository-wiseNo
dotgit dotgitAURPythonfilename-basedNo
homeshick Bashrepository-wiseNo
homesick Rubyrepository-wiseNo
Pearl Pythonrepository-wiseNo
vcsh Shellrepository-wiseNo
yadm(1) Pythonfilename-based
(by class/OS/distro/hostname/user)
Built-in templates/Jinja2/ESH
(optional)
  1. Supports encryption of confidential files with GPG or OpenSSL.

User repositories

AuthorShell (Shell framework)WM / DEEditorTerminalMultiplexerAudioMonitorMailIRCFile ManagerRSS reader
alfunx zshawesomevimkittytmuxncmpcpp/mpdhtop/lainthunderbird
Ambrevar EshellEXWMEmacsEmacs (Eshell)Emacs TRAMP + dtachEMMSconky/dzenmu4eCirce
ananthu zshbspwmneovimalacrittympvhtop, polybarneomuttweechatranger
awal fishi3vimsttmuxi3statusThe Lounge
ayekat zshkaruiwmvimrxvt-unicodetmuxncmpcpp/mpdkaruibarmuttirssi
bachoseven zshdwmneovimstncmpcppbottomneomuttweechatlf
bamos zshi3/xmonadvim/emacsrxvt-unicodetmuxmpv/cmusconky/xmobarmuttERC
benmezger zsh/bashi3-gapsemacsrxvt-unicode/alacrittytmuxmopidy/ncmpcppi3status-rsmu4e/neomutt/mbsyncweechat
brisbin33 zshxmonadvimrxvt-unicodescreendzenmuttirssi
BVollmerhaus fishi3-gapskakounekittypolybarranger
cinelli zshdwmvimtermite-gitpianobarhtopmutt-kzweechat
dikiaap zshi3-gapsneovimalacrittytmuxi3blocksnnn
Earnestly zshi3/orbmentvim/emacstermitetmuxmpdconkymuttweechat
ErikBjare zshxmonad/xfce4vimterminatortmuxxfce4-panelweechat
falconindy bashi3vimrxvt-unicodencmpcppconkymutt
filiparag fishbspwmvimalacrittytmuxmpv, playerctlhtop, polybarmail-notificationpcmanfm
gardenapple zshswayneovimkittyhtopaerc
graysky zshxfce4vimterminalncmpcppcustomthunderbird
hugdru zshawesomeneovimrxvt-unicodetmuxthunderbirdweechat
insanum bashherbstluftwmvimevilvtetmuxdzenmutt-kz
isti115 pwsh sway neovim alacritty tmux mpv / playerctl waybar / htop / ytop ranger
jasonwryan bash/zshdwmvimrxvt-unicodetmuxncmpcppcustommuttirssi
jdevlieghere zshxmonadvimterminaltmuxhtopmuttweechat
jelly zshi3vimtermitetmuxncmpcppmutt-kz-gitweechat
JonasDe zshi3vimrxvt-unicodetmux
Jorengarenar sh/Bashi3VimxtermtmuxmpvhtopaercWeeChatrangerQuiteRSS
MarkusZoppelt zshgnomevimterminaltmux
maximbaz zshswaykakounekittywaybarneomuttnnn
mehalter zshi3-gapsneovimtermitetmuxcmusgotopneomuttweechatranger
meskarune bashherbstluftwmvimrxvt-unicodescreenconkyweechat
neersighted fishi3neovimalacrittytmuxncmpcpp
nimaipatel fishawesomeneovimalacrittyncmpcpp
oibind fishawesomeneovimsttmuxhtop-vimweechatlf
OK100 bashdwmvimrxvt-unicodecmusconky, dzenmuttweechat
orhun bashi3-gapsneovimalacrittyi3statusweechattere
pablox-cl zsh (zplug)gnome3neovimkitty
peterzuger zshi3-gapsemacsrxvt-unicodescreenmochtop
potamides bashawesomeneovimtermitetmuxncmpcppconky,htopmuttweechatranger
reisub0 fishqtileneovimkittympdconky
Scrumplex fishswayneovimkittyncmpcpp / pipewirewaybaraercranger
sistematico zsh/fish/bashi3-gapsvim/nanotermitetmuxncmpcpppolybarmuttweechat
sitilge zshswayneovimalacrittyhtopthunderbird
thecashewtrader EshellEXWMEmacsEmacs (VTerm)EmacsBongohtopmu4eERCDiredElfeed
thiagowfx bash/zshi3vimalacrittytmuxplayerctli3statusranger
tuurep bashopenboxneovimalacrittytmuxpolybar
vodik zshxmonadvimtermite-gittmuxncmpcppcustommuttweechat
w0ng zshdwmvimrxvt-unicodetmuxncmpcppcustommuttirssi
whitelynx fishi3neovimkittyi3pystatus
whynothugo zshswayneovimalacrittympvwaybar, topneomuttnemo
wryonik zshi3-gaps-roundedvimterminatorcmushtop, i3blocks, gotopranger, nautilus
gollark: I may be referred to as car/cdr if desired.
gollark: The problem with spaces is that you can’t actually see them. So you can’t be sure they’re correct. Also they aren’t actually there anyway - they are the absence of code. “Anti-code” if you will. Too many developers format their code “to make it more maintainable” (like that’s actually a thing), but they’re really just filling the document with spaces. And it’s impossible to know how spaces will effect your code, because if you can’t see them, then you can’t read them. Real code wizards know to just write one long line and pack it in tight. What’s that you say? You wrote 600 lines of code today? Well I wrote one, and it took all week, but it’s the best. And when I hand this project over to you next month I’ll have solved world peace in just 14 lines and you will be so lucky to have my code on your screen <ninja chop>.
gollark: Remove the call stack and do trampolining or something?
gollark: Yes, I think this is possible.
gollark: (ethically)

See also

This article is issued from Archlinux. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.