Cách Quản Lý Dotfiles Như Dân Pro với Git và Stow

~ 6 phút đọc

Have You Ever Managed Your Dotfiles? 🤔

If you’re a developer, chances are you’ve customized your environment—tweaking your .config, .bashrc, .czrc, .zshrc, .vimrc, or .tmux.conf to fit your workflow. But have you ever switched machines and realized you forgot to back them up? Or worse, you messed up your config and wished you had version control?

That’s where dotfile management comes in. Instead of manually copying files, let’s explore how to use Git to store them—and how GNU Stow can make managing them effortless. 🚀


My dotfiles configurations:

{% embed https://github.com/crafts69guy/.dotfiles %}


Installing Stow 🛠️

Before we dive into using Stow, let’s install it on your system.

On macOS (using Homebrew)

brew install stow

On Debian/Ubuntu

sudo apt update && sudo apt install stow -y

On Arch Linux

sudo pacman -S stow

Once installed, you can verify the installation by running:

stow --version

The Old-School Way: Manual Syncing with Git 📂

Before discovering Stow, I used to manage my dotfiles like this:

  1. Copy the dotfiles to a dedicated folder:

    mkdir -p ~/.dotfiles
    cp -r -f -v ~/.config ~/.dotfiles/.config
    cp -r -f -v ~/.zshrc ~/.dotfiles/.zshrc
    ...
  2. Initialize a Git repository and push to GitHub:

    cd ~/.dotfiles
    git init
    git add .
    git commit -m "Initial commit"
    git remote add origin git@github.com:yourusername/.dotfiles.git
    git push -u origin main
  3. Manually restore dotfiles when needed:

    cp -r -f -v ~/.dotfiles/.config ~/.config
    cp -r -f -v ~/.dotfiles/.zshrc ~/.zshrc

This worked, but it was tedious. Every time I updated my dotfiles, I had to manually copy them back and forth. There had to be a better way—and that’s when I found GNU Stow. 🎉


Meet Stow: A Simple Yet Powerful Tool for Dotfiles 🛠️

GNU Stow is a symlink farm manager that helps manage the installation of software packages by creating symbolic links (symlinks) in a structured way.

  • It allows users to keep software files organized in a single directory (source) and symlink them into another location (target) without directly copying or modifying the files.
  • It was originally designed for managing software packages, but it’s perfect for handling dotfiles.

How Stow Works

  • Instead of copying files, Stow creates symbolic links from a central directory (like ~/.dotfiles) to their actual locations (like ~/.config).
  • This means you only need to track files in one place, and Stow takes care of placing them in the right locations.
ConceptExplanationExample (macOS)
package_nameThe folder that contains the files you want to symlink (e.g., a software package or configuration files).A directory named vim that contains configuration files for Vim.
Source DirectoryThe location where packages are stored before being linked.~/.dotfiles/ is the source directory where vim, git, and tmux configurations are stored.
Target DirectoryThe location where symlinks will be created, pointing to files in the package.~/.config/ is the target directory where the actual symlinks will be placed.

GNU Stow cheat sheet

Example of Stow in Action 🔗

Imagine your dotfiles are structured like this:

~/.dotfiles/
├── nvim/
│   ├── .config/nvim/init.lua
├── tmux/
│   ├── .tmux.conf
├── zshrc/
│   ├── .zshrc

Instead of manually copying them, you can simply run:

stow -d ~/.dotfiles -t ~ nvim
stow -d ~/.dotfiles -t ~ tmux
stow -d ~/.dotfiles -t ~ zshrc

Let’s break it down:

  • stow: The command to run GNU Stow.
  • -d ~/.dotfiles: Specifies the source directory where the dotfiles are stored (~/.dotfiles). Stow assumes that inside this directory, there are subdirectories for different applications (e.g., nvim, zsh, etc.).
  • -t ~: Sets the target directory (~, which is your home directory). Stow will create symlinks in this directory.
  • nvim: The subdirectory inside ~/.dotfiles that contains the actual configuration files for Neovim. Stow will take the files inside ~/.dotfiles/nvim and symlink them into your home directory.

This creates symlinks:

~/.config/nvim/init.lua → ~/.dotfiles/nvim/.config/nvim/init.lua
~/.tmux.conf → ~/.dotfiles/tmux/.tmux.conf
~/.zshrc → ~/.dotfiles/zshrc/.zshrc

Alternatively, you can use:

cd ~/.dotfiles
stow -v .

This applies symlinks for all directories inside .dotfiles. The -v flag gives verbose output, so you can see what Stow is doing.

[!WARNING] When using stow -v . a little different.

What It Does:

  • -v → Enables verbose mode, showing which symlinks are created.
  • . → Assumes you are inside ~/.dotfiles and applies stow to all directories inside it.

and the output should creates symlinks become:

~/nvim/.config/nvim/init.lua  →  ~/.dotfiles/nvim/.config/nvim/init.lua
~/tmux/.tmux.conf → ~/.dotfiles/tmux/.tmux.conf
~/zshrc/.zshrc                 →  ~/.dotfiles/zshrc/.zshrc

To remove symlinks, you can run:

stow -D tmux

To restow (apply changes after updating dotfiles):

stow -R tmux

How to Manage Dotfiles with Stow and Git (Step by Step) 📌

Here’s a simple workflow to manage dotfiles with Stow and Git:

1. Create a dotfiles Directory

mkdir -p ~/.dotfiles
cd ~/.dotfiles

2. Organize Your Dotfiles

Let’s move all dotfiles you want to stow and manage.

mv -f ~/.config ~/.dotfiles/.config
mv -f ~/.tmux.conf ~/.dotfiles/.tmux.conf
mv -f ~/.zshrc ~/.dotfiles/.zshrc

Apply all dotfiles at once:

stow -v .

Awesome :cowboy_hat_face:

4. Initialize a Git Repository and Push to GitHub

cd ~/.dotfiles
git init

git add .
git commit -m "Initial dotfiles setup"
git remote add origin git@github.com:yourusername/.dotfiles.git
git push -u origin main

5. Restore Dotfiles on a New Machine 🖥️

When setting up a new machine, simply clone the repo and re-run Stow:

git clone git@github.com:yourusername/.dotfiles.git ~/.dotfiles
cd ~/.dotfiles
stow -v .

That’s it! No more copying files manually. 🚀
Note: make sure stow installed.


Ignoring Files with stow-local-ignore 📜

Sometimes, you may want Stow to ignore specific files or directories within your dotfiles setup. For this, you can use a .stow-local-ignore file inside the respective package directory.

How to Use .stow-local-ignore

  1. Create a .stow-local-ignore file inside the package directory:

    touch ~/.dotfiles/.stow-local-ignore
  2. Add the names of files or directories you want Stow to ignore:

    .DS_Store
    .gitconfig
    .git
    .gitignore
    
    backup/
    tmp_config.json
  3. Now, when running Stow, these files will be skipped while symlinking.

This is useful for keeping temporary or machine-specific files out of your Stow-managed dotfiles!


Bonus: Ignore Unwanted Files 🛑

To avoid pushing unnecessary files, create a .gitignore:

# Ignore system-specific files
.history
.local
.cache

This keeps your repo clean and portable.


Conclusion 🎯

Managing dotfiles manually is painful, but with Git and Stow, you can:

✔ Keep all your configurations versioned and backed up.
✔ Easily sync dotfiles across machines.
✔ Avoid cluttering your home directory with redundant copies.

Try setting up Stow today—it might just change the way you manage your development environment forever! 💡

Do you have a favorite dotfile management trick? Share your thoughts in the comments! 💬

{% embed https://dev.to/insideee_dev %}

{% cta https://x.com/crafts69guy %}🚀 Follow me on X(Twitter){% endcta%}

{% cta https://www.linkedin.com/in/cuong-cao-ngoc-792992229/ %}🚀 Connect with me on Linkedin{% endcta %}

{% cta https://github.com/crafts69guy %}🚀 Checkout my GitHub{% endcta %}

See you soon.

Thanks for reading!