/HOME/ /prev/ /Hotline Webring/ /next/
Dotfiles Management 2026-08-02 ________________________________________________________________________________ This guide describes how I manage my dotfiles. It is heavily inspired by Drew DeVault's approach, but I have adapted it over the years to better suit my own workflow. Drew's blog on dotfiles: https://drewdevault.com/2019/12/30/dotfiles.html --- [001] Setup Options -------------------------------------------------------- In this setup, the $HOME directory is a Git repository. This guide assumes you are starting with an empty $HOME and have basic familiarity with operating a UNIX-like system. On a real system you would typically move existing files out of the way first, or use an existing repository as described below. +----------------------------------------------------------------------------+ | | | $ cd $HOME; git init | | | +----------------------------------------------------------------------------+ Alternatively, you can use an existing repository. This is preferable if you already have dotfiles backed up using this or a similar layout and want to deploy them to a new environment. A plain git clone refuses to write into a directory that is not empty, so initialise the repository in place and fetch into it instead: +----------------------------------------------------------------------------+ | | | $ cd $HOME | | $ git init | | $ git remote add origin https://codeberg.org/pigeon/dotfiles | | $ git fetch origin | | $ git checkout -f master | | | +----------------------------------------------------------------------------+ The -f option overwrites any local files that clash with tracked ones, so back up anything you care about first. In practice, I always use my existing dotfiles repository on a new machine. The git init route above is there to teach the underlying idea, as you will only ever run it once: the first time you start tracking your dotfiles. --- [002] Ignore Everything by Default ----------------------------------------- By default this setup would track every file in your $HOME directory. To avoid this, add a rule that ignores everything unless it is explicitly tracked. Do this straight after creating the repository: +----------------------------------------------------------------------------+ | | | $ echo "*" >> $HOME/.git/info/exclude | | | +----------------------------------------------------------------------------+ I find this better than a .gitignore file in the root of the repository, as that would be one extra file polluting /home/$USER/ --- [003] Adding Dotfiles ------------------------------------------------------ I do not limit this to shell and editor configs. Pretty much anything config-related gets tracked this way, including River, Kakoune and whatever else I have tweaked. If it is a file I would be annoyed to lose or retype on a new machine, it goes in. Force-add the files you want to track: +----------------------------------------------------------------------------+ | | | $ git add -f .bashrc | | $ git commit -m "initial commit" | | | +----------------------------------------------------------------------------+ If you started with git init, point the repository at your remote and push for the first time: +----------------------------------------------------------------------------+ | | | $ git remote add origin https://codeberg.org/pigeon/dotfiles | | $ git push -u origin HEAD | | | +----------------------------------------------------------------------------+ Repeat for other files: +----------------------------------------------------------------------------+ | | | $ git add -f .config/river/config | | $ git add -f .config/kakoune/kakrc | | $ git add -f .profile | | $ git commit -m "add more files" | | $ git push | | | +----------------------------------------------------------------------------+ I also use shell scripts to track things related to / or the root user. One automatically backs up a list of my manually installed packages to $HOME/.local/packages, and another does the same for my init services and user groups. This is handy for backing up system-level settings on a single-user system. --- [004] Hiding Files --------------------------------------------------------- I mainly use this for README and LICENSE. I want them visible when browsing the repository on Codeberg, but they have no reason to sit in $HOME cluttering things day to day. For files you want Git to ignore locally: +----------------------------------------------------------------------------+ | | | $ git update-index --assume-unchanged README LICENSE | | $ rm README LICENSE | | | +----------------------------------------------------------------------------+ Check hidden files: +----------------------------------------------------------------------------+ | | | $ git ls-files -v | grep "^h" | | | +----------------------------------------------------------------------------+ Restore them later: +----------------------------------------------------------------------------+ | | | $ git update-index --no-assume-unchanged README LICENSE | | $ git restore README LICENSE | | | +----------------------------------------------------------------------------+ --- [005] Untracking a File Without Removing It -------------------------------- Sometimes you want Git to stop tracking a file but keep it sitting in $HOME exactly as it is, with no deletion involved. This is different from hiding a file with assume-unchanged, since that keeps the file tracked and just tells Git to stop checking it for changes. Untracking actually removes it from the repository's index while leaving the file on disk untouched. Untrack a file, keeping it in the working tree: +----------------------------------------------------------------------------+ | | | $ git rm --cached .bashrc | | $ git commit -m "untrack .bashrc" | | $ git push | | | +----------------------------------------------------------------------------+ --- [006] Final Thoughts ------------------------------------------------------- That is the whole method: a $HOME repository, everything ignored by default, and files force-added one at a time as you decide they are worth tracking. It does not require extra tooling such as stow, and it scales fine whether you are tracking three files or thirty. I prefer this over the popular bare-repository approach because it behaves like a normal Git repository, requires no shell aliases and works with standard Git commands. If you want to see it in practice rather than just in theory, my own dotfiles are public and follow this exact layout: https://codeberg.org/pigeon/dotfiles
________________________________________________________________________________ Flockless (C) 2021-2026 by Joseph is licensed under CC BY-SA 4.0