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
    # desktop or server machine commands

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.


File grouping
How configuration files can be grouped to configuration groups (also called profiles or packages).
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
  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

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.