cmc/cleberg.net

My personal web garden & blog.

clone: git clone https://gitbay.org/cmc/cleberg.net.git

main: content/blog/2026-02-08-gnu-stow.org · raw

  1#+date:        [2026-02-08 Sun 12:17:42]
  2#+title:       Managing Dotfiles with GNU Stow and Git
  3#+description: How I use GNU Stow to manage my dotfiles and configs across machines.
  4#+slug: gnu-stow
  5#+filetags:    :emacs:linux:
  6
  7* What is GNU Stow?
  8
  9[[https://www.gnu.org/software/stow/][GNU Stow]] is described as a "symlink farm manager" on its homepage, which is
 10true, but feels a bit underwhelming. Rather, I'd describe it as a tool to
 11systematically and logically link, organize, and version control any files on
 12your system.
 13
 14[[https://img.cleberg.net/blog/20260208-gnu-stow/stow.webp]]
 15#+caption: GNU Stow Help Options
 16
 17* Installation
 18
 19First things first: let's install Stow. I'm on macOS, so I run the following
 20command:
 21
 22#+begin_src sh
 23brew install stow
 24#+end_src
 25
 26To ensure it's installed correctly, check the version:
 27
 28#+begin_src sh
 29stow -V
 30#+end_src
 31
 32* Stow Dotfiles
 33
 34Next, let's create a directory to use as the central source for all these files.
 35In my case, I store all git repositories in my ~~/git/~ directory, so I will
 36create a ~dotfiles~ directory here:
 37
 38#+begin_src sh
 39# Create the dotfiles repository
 40mkdir ~/git/dotfiles && cd ~/git/dotfiles
 41#+end_src
 42
 43Next, let's stow our first set of dotfiles. We'll use ~zsh~ as an example here. To
 44do this, we will:
 451. Create a directory for Zsh.
 462. Move our current Zsh configuration files into our Stow directory.
 473. Use Stow to symlink the files back into our home directory.
 48
 49#+begin_src sh
 50# Create the ZSH Stow directory
 51mkdir zsh                          && \
 52# Move your ZSH files into Stow
 53mv ~/.zshrc ~/git/dotfiles/zsh/    && \
 54mv ~/.zprofile ~/git/dotfiles/zsh/ && \
 55# Use Stow to symlink them back to your user home
 56stow zsh
 57#+end_src
 58
 59By default, Stow will symlink your files (e.g., ~zsh~) to the parent directory
 60of the directory in which you execute the command. Since we're in the
 61~~/git/dotfiles~ directory, we need to modify our ~stow~ command to ensure Stow
 62symlinks the files to our home directory:
 63
 64#+begin_src sh
 65stow -t ~ zsh
 66#+end_src
 67
 68At this point, you have a centralized directory (~/git/dotfiles~) where you can
 69stow any file and use ~stow~ to symlink it back to another directory on your
 70system.
 71
 72Therefore, you only need to navigate to this directory to make changes across
 73your system.
 74
 75* Update Dotfiles
 76
 77When you make changes to your Stow directory, you can inform Stow and have the
 78program update its symlinks with the following command:
 79
 80#+begin_src sh
 81cd ~/git/dotfiles && \
 82stow -R zsh
 83#+end_src
 84
 85To summarize:
 86
 87| Action                          | Command           | Why?                                             |
 88|---------------------------------+-------------------+--------------------------------------------------|
 89| Edited a file                   | None (Just save)  | The symlink already exists.                      |
 90| Added a file to existing folder | stow -R <package> | To create the new symlink for that file.         |
 91| Deleted a file from dotfiles    | stow -R <package> | To remove the "dead" symlink from your home dir. |
 92| Created a whole new package     | stow <package>    | To link the new directory for the first time.    |
 93
 94* Save to a Git Repository
 95
 96Lastly, let's finish the puzzle by ensuring that this configuration is
 97long-lasting and can transfer amongst systems.
 98
 99To this end, we will use Git as our VCS. You can simply create the repository,
100add your files, and push to your remote.
101
102#+begin_src sh
103git init                       && \
104git add .                      && \
105git commit -m "initial commit" && \
106git remote add origin GIT_URL  && \
107git push
108#+end_src
109
110If you want to automate this even more, write an alias or a hook into your ~stow~
111command to automatically commit your changes whenever they occur.
112
113At this point, I have organized and managed my dotfiles much more efficiently
114and no longer lose them whenever I wipe my machines.