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.