# How to Manage Dotfiles Using Git: A Complete Guide to the issmirnov/dotfiles Workflow

> Effectively manage dotfiles using Git. Track configs, use submodules, and automate symlinks with Dotbot for a reproducible dev environment across all your machines.

- Repository: [Ivan Smirnov/dotfiles](https://github.com/issmirnov/dotfiles)
- Tags: how-to-guide
- Published: 2026-03-04

---

**Manage dotfiles using Git by tracking configuration files in a central repository, using Git submodules for external tools, and automating symlink creation with Dotbot to maintain a reproducible development environment across machines.**

The `issmirnov/dotfiles` repository demonstrates a production-ready approach to managing dotfiles using Git. This system treats every personal configuration file—whether for bash, zsh, vim, or tmux—as a regular file tracked in Git, while external tools like Dotbot and Oh-My-Zsh are isolated as submodules.

## Why Use Git to Manage Dotfiles?

Using Git to manage dotfiles provides version control for your entire development environment. You can roll back breaking changes, diff configurations between machines, and bootstrap a new computer in minutes by cloning a single repository. The `issmirnov/dotfiles` approach adds automation through Dotbot and post-commit hooks, eliminating manual symlink management.

## Core Architecture of the issmirnov/dotfiles Repository

### Git as the Single Source of Truth

Every configuration file lives under version control in the repository root or organized subdirectories. This enables rollbacks, diffs, and easy sharing across machines. The repository does not store external tools directly; instead, it references them through Git submodules declared in `.gitmodules`.

### Submodule Isolation for External Tools

Heavy third-party tools like Dotbot, zgen, cheat, and tmux-yank are kept in separate Git submodules. This prevents them from cluttering the primary repository history while maintaining reproducibility via `git submodule update --init`. The `.gitmodules` file defines these relationships, ensuring that cloning with `--recursive` pulls all dependencies.

### Dotbot Orchestration and Symlink Management

The `install` script serves as a Bash driver that bootstraps Dotbot using a YAML manifest. The [`default.conf.yaml`](https://github.com/issmirnov/dotfiles/blob/main/default.conf.yaml) file defines all file-to-symlink mappings, shell commands, and default behaviors like `relink` and `force` options. This makes the installation idempotent—running `./install` repeatedly never corrupts existing links.

### Automatic Post-Commit Hooks

The `git/hooks/post-commit` hook parses `git diff-tree` output to detect which logical components changed (e.g., `vim`, `zsh`, `bat/syntaxes`). It then executes targeted commands—such as `vim +PlugInstall +PlugUpdate` or `bat cache --build`—to keep the live environment synchronized with the repository without manual intervention.

## How to Manage Dotfiles Using Git: Step-by-Step Workflow

### Initial Setup: Clone and Install

To bootstrap a new machine with the `issmirnov/dotfiles` system:

```bash
git clone --recursive https://github.com/issmirnov/dotfiles.git ~/.dotfiles
cd ~/.dotfiles
./install

```

The `--recursive` flag ensures all submodules defined in `.gitmodules` are pulled. The `./install` script detects `$OSTYPE` and selects the appropriate configuration—[`ubuntu.conf.yaml`](https://github.com/issmirnov/dotfiles/blob/main/ubuntu.conf.yaml) or [`osx.conf.yaml`](https://github.com/issmirnov/dotfiles/blob/main/osx.conf.yaml)—before invoking Dotbot with [`default.conf.yaml`](https://github.com/issmirnov/dotfiles/blob/main/default.conf.yaml).

### Adding New Configuration Files

To track a new dotfile in the repository:

1. Place the file in an appropriate subdirectory (e.g., [`zsh/myalias.zsh`](https://github.com/issmirnov/dotfiles/blob/main/zsh/myalias.zsh)).
2. Add a mapping to [`default.conf.yaml`](https://github.com/issmirnov/dotfiles/blob/main/default.conf.yaml) under the `link` section:

```yaml
- link:
    ~/.myalias: zsh/myalias.zsh

```

3. Commit the changes:

```bash
git add zsh/myalias.zsh default.conf.yaml
git commit -m "Add custom alias file"

```

The post-commit hook automatically detects the change and runs the install step to create the new symlink.

### Updating External Dependencies

When submodules like `zgen` or `tmux-yank` receive upstream updates:

```bash
git submodule update --remote
git add .
git commit -m "Update submodule versions"

```

The next `./install` execution—or the automatic hook—will pick up the refreshed binaries.

### Synchronizing Across Multiple Machines

To update an existing installation on another machine:

```bash
cd ~/.dotfiles
git pull
git submodule update --init --recursive
./install

```

The post-commit hook ensures that any configuration changes pulled from the remote are instantly reapplied to the live environment.

## Key Files and Their Roles

| Path | Role |
|------|------|
| [`README.md`](https://github.com/issmirnov/dotfiles/blob/main/README.md) | Introductory guide, prerequisites, and high-level description |
| `install` | Bash driver that bootstraps Dotbot, chooses OS-specific manifests, and ensures submodules are present |
| [`default.conf.yaml`](https://github.com/issmirnov/dotfiles/blob/main/default.conf.yaml) | Main Dotbot manifest defining default behaviors, shell commands, and all file-to-symlink mappings |
| `.gitmodules` | Declares external dependencies as submodules (Dotbot, zgen, cheat, tmux-yank, ubersicht/simple-bar) |
| `git/hooks/post-commit` | Hook that parses `git diff-tree` to detect changed components and runs targeted refresh commands |

## Summary

- **Git as version control**: The `issmirnov/dotfiles` repository treats every configuration file as tracked source code, enabling rollbacks and diffs.
- **Submodule isolation**: External tools live in separate Git submodules defined in `.gitmodules`, keeping the main history clean while ensuring reproducibility.
- **Dotbot automation**: The `install` script and [`default.conf.yaml`](https://github.com/issmirnov/dotfiles/blob/main/default.conf.yaml) manifest automate symlink creation, making the setup idempotent across Ubuntu and macOS.
- **Post-commit hooks**: The `git/hooks/post-commit` script automatically refreshes the live environment when configuration changes are committed, eliminating manual sync steps.

## Frequently Asked Questions

### What is the best way to manage dotfiles using Git?

The best way to manage dotfiles using Git is to create a bare repository or a standard repository with symlink orchestration, as demonstrated by `issmirnov/dotfiles`. This approach tracks configuration files in version control while using tools like Dotbot to automatically create symlinks from the home directory to the repository. Git submodules isolate external dependencies, ensuring a clean history and reproducible setups across multiple machines.

### How do Git submodules help with dotfile management?

Git submodules keep third-party tools like Dotbot, zgen, and tmux-yank in separate repositories while maintaining a reference in the main dotfiles project. This prevents external code from cluttering your configuration history and allows you to pin specific versions of tools. When cloning the repository, the `--recursive` flag or `git submodule update --init` command ensures all dependencies are present, creating a fully reproducible environment.

### What is Dotbot and why is it used in the issmirnov/dotfiles repository?

Dotbot is a lightweight tool that automates the creation of symlinks and execution of shell commands based on YAML configuration files. In the `issmirnov/dotfiles` repository, the `install` script invokes Dotbot with [`default.conf.yaml`](https://github.com/issmirnov/dotfiles/blob/main/default.conf.yaml) to map repository files to their appropriate locations in the home directory. Dotbot's options like `relink` and `force` make the installation idempotent, meaning it can be run repeatedly without corrupting existing links or overwriting user data.

### How do post-commit hooks automate dotfile maintenance?

The `git/hooks/post-commit` hook in the `issmirnov/dotfiles` repository automatically detects which configuration files changed during a commit by parsing `git diff-tree` output. When it identifies changes to specific components—such as Vim plugins, bat syntaxes, or window manager settings—it executes targeted refresh commands like `vim +PlugInstall` or `bat cache --build`. This automation ensures the live environment stays synchronized with the repository without requiring manual intervention after each commit.