docs: explain checkpoints, /rollback, and git worktrees
* docs: explain checkpoints, rollback, and git worktrees * fix: correct hermes -w description — auto-creates worktree, takes no path arg --------- Co-authored-by: aydnOktay <xaydinoktay@gmail.com>
This commit is contained in:
parent
4298c6fd9a
commit
aaacab7de7
2 changed files with 353 additions and 0 deletions
180
website/docs/user-guide/checkpoints-and-rollback.md
Normal file
180
website/docs/user-guide/checkpoints-and-rollback.md
Normal file
|
|
@ -0,0 +1,180 @@
|
||||||
|
---
|
||||||
|
sidebar_position: 8
|
||||||
|
title: "Checkpoints and /rollback"
|
||||||
|
description: "Filesystem safety nets for destructive operations using shadow git repos and automatic snapshots"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Checkpoints and `/rollback`
|
||||||
|
|
||||||
|
Hermes Agent can automatically snapshot your project before **destructive operations** (like file write/patch tools) and restore it later with a single command.
|
||||||
|
|
||||||
|
This safety net is powered by an internal **Checkpoint Manager** that keeps a separate shadow git repository under `~/.hermes/checkpoints/` — your real project `.git` is never touched.
|
||||||
|
|
||||||
|
## How Checkpoints Work
|
||||||
|
|
||||||
|
At a high level:
|
||||||
|
|
||||||
|
- Hermes detects when tools are about to **modify files** in your working tree.
|
||||||
|
- Once per conversation turn (per directory), it:
|
||||||
|
- Resolves a reasonable project root for the file.
|
||||||
|
- Initialises or reuses a **shadow git repo** tied to that directory.
|
||||||
|
- Stages and commits the current state with a short, human‑readable reason.
|
||||||
|
- These commits form a checkpoint history that you can inspect and restore via `/rollback`.
|
||||||
|
|
||||||
|
Internally, the Checkpoint Manager:
|
||||||
|
|
||||||
|
- Stores shadow repos under:
|
||||||
|
- `~/.hermes/checkpoints/<hash>/`
|
||||||
|
- Keeps metadata about:
|
||||||
|
- The original working directory (`HERMES_WORKDIR` file in the shadow repo).
|
||||||
|
- Excluded paths such as:
|
||||||
|
- `node_modules/`, `dist/`, `build/`
|
||||||
|
- `.venv/`, `__pycache__/`, `*.pyc`
|
||||||
|
- `.git/`, `.cache/`, `.pytest_cache/`, etc.
|
||||||
|
|
||||||
|
The agent creates **at most one checkpoint per directory per turn**, so long running sessions do not spam snapshots.
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart LR
|
||||||
|
user["User command\n(hermes, gateway)"]
|
||||||
|
agent["AIAgent\n(run_agent.py)"]
|
||||||
|
tools["File tools\n(write/patch)"]
|
||||||
|
cpMgr["CheckpointManager"]
|
||||||
|
shadowRepo["Shadow git repo\n~/.hermes/checkpoints/<hash>"]
|
||||||
|
|
||||||
|
user --> agent
|
||||||
|
agent -->|"tool call"| tools
|
||||||
|
tools -->|"before mutate\nensure_checkpoint()"| cpMgr
|
||||||
|
cpMgr -->|"git add/commit"| shadowRepo
|
||||||
|
cpMgr -->|"OK / skipped"| tools
|
||||||
|
tools -->|"apply changes"| agent
|
||||||
|
```
|
||||||
|
|
||||||
|
## Enabling Checkpoints
|
||||||
|
|
||||||
|
Checkpoints are controlled by a simple on/off flag and a maximum snapshot count **per directory**:
|
||||||
|
|
||||||
|
- `checkpoints_enabled` – master switch
|
||||||
|
- `checkpoint_max_snapshots` – soft cap on history depth per directory
|
||||||
|
|
||||||
|
You can configure these in `~/.hermes/config.yaml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
agent:
|
||||||
|
checkpoints_enabled: true
|
||||||
|
checkpoint_max_snapshots: 50
|
||||||
|
```
|
||||||
|
|
||||||
|
Or via CLI flags (exact wiring may depend on your version of the CLI):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
hermes --checkpoints
|
||||||
|
# or
|
||||||
|
hermes chat --checkpoints
|
||||||
|
```
|
||||||
|
|
||||||
|
When disabled, the Checkpoint Manager is a no‑op and never attempts git operations.
|
||||||
|
|
||||||
|
## Listing Checkpoints
|
||||||
|
|
||||||
|
Hermes exposes an interactive way to list checkpoints for the current working directory.
|
||||||
|
|
||||||
|
From the CLI session where you are working on a project:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Ask Hermes to show checkpoints for the current directory
|
||||||
|
/rollback
|
||||||
|
```
|
||||||
|
|
||||||
|
Hermes responds with a formatted list similar to:
|
||||||
|
|
||||||
|
```text
|
||||||
|
📸 Checkpoints for /path/to/project:
|
||||||
|
|
||||||
|
1. a1b2c3d 2026-03-13 10:24 auto: before apply_patch
|
||||||
|
2. d4e5f6a 2026-03-13 10:15 pre-rollback snapshot (restoring to a1b2c3d0)
|
||||||
|
|
||||||
|
Use /rollback <number> to restore, e.g. /rollback 1
|
||||||
|
```
|
||||||
|
|
||||||
|
Each entry shows:
|
||||||
|
|
||||||
|
- Short hash
|
||||||
|
- Timestamp
|
||||||
|
- Reason (commit message for the snapshot)
|
||||||
|
|
||||||
|
## Restoring with `/rollback`
|
||||||
|
|
||||||
|
Once you have identified the snapshot you want to go back to, use `/rollback` with the number from the list:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Restore to the most recent snapshot
|
||||||
|
/rollback 1
|
||||||
|
```
|
||||||
|
|
||||||
|
Behind the scenes, Hermes:
|
||||||
|
|
||||||
|
1. Verifies the target commit exists in the shadow repo.
|
||||||
|
2. Takes a **pre‑rollback snapshot** of the current state so you can “undo the undo” later.
|
||||||
|
3. Runs `git checkout <hash> -- .` in the shadow repo, restoring tracked files in your working directory.
|
||||||
|
|
||||||
|
On success, Hermes responds with a short summary like:
|
||||||
|
|
||||||
|
```text
|
||||||
|
✅ Restored /path/to/project to a1b2c3d
|
||||||
|
Reason: auto: before apply_patch
|
||||||
|
```
|
||||||
|
|
||||||
|
If something goes wrong (missing commit, git error), you will see a clear error message and details will be logged.
|
||||||
|
|
||||||
|
## Safety and Performance Guards
|
||||||
|
|
||||||
|
To keep checkpointing safe and fast, Hermes applies several guardrails:
|
||||||
|
|
||||||
|
- **Git availability**
|
||||||
|
- If `git` is not found on `PATH`, checkpoints are transparently disabled.
|
||||||
|
- A debug log entry is emitted, but your session continues normally.
|
||||||
|
- **Directory scope**
|
||||||
|
- Hermes skips overly broad directories such as:
|
||||||
|
- Root (`/`)
|
||||||
|
- Your home directory (`$HOME`)
|
||||||
|
- This prevents accidental snapshots of your entire filesystem.
|
||||||
|
- **Repository size**
|
||||||
|
- Before committing, Hermes performs a quick file count.
|
||||||
|
- If the directory has more than a configured threshold (e.g. `50,000` files),
|
||||||
|
checkpoints are skipped to avoid large git operations.
|
||||||
|
- **No‑change snapshots**
|
||||||
|
- If there are no changes since the last snapshot, the checkpoint is skipped
|
||||||
|
instead of committing an empty diff.
|
||||||
|
|
||||||
|
All errors inside the Checkpoint Manager are treated as **non‑fatal**: they are logged at debug level and your tools continue to run.
|
||||||
|
|
||||||
|
## Where Checkpoints Live
|
||||||
|
|
||||||
|
By default, all shadow repos live under:
|
||||||
|
|
||||||
|
```text
|
||||||
|
~/.hermes/checkpoints/
|
||||||
|
├── <hash1>/ # shadow git repo for one working directory
|
||||||
|
├── <hash2>/
|
||||||
|
└── ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Each `<hash>` is derived from the absolute path of the working directory. Inside each shadow repo you will find:
|
||||||
|
|
||||||
|
- Standard git internals (`HEAD`, `refs/`, `objects/`)
|
||||||
|
- An `info/exclude` file containing a curated ignore list
|
||||||
|
- A `HERMES_WORKDIR` file pointing back to the original project root
|
||||||
|
|
||||||
|
You normally never need to touch these manually; they are documented here so advanced users understand how the safety net works.
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
- **Keep checkpoints enabled** for interactive development and refactors.
|
||||||
|
- **Use `/rollback` instead of `git reset`** when you want to undo agent‑driven changes only.
|
||||||
|
- **Combine with Git branches and worktrees** for maximum safety:
|
||||||
|
- Keep each Hermes session in its own worktree/branch.
|
||||||
|
- Let checkpoints act as an extra layer of protection on top.
|
||||||
|
|
||||||
|
For running multiple agents in parallel on the same repo without interfering with each other, see the dedicated guide on [Git worktrees](./git-worktrees.md).
|
||||||
|
|
||||||
173
website/docs/user-guide/git-worktrees.md
Normal file
173
website/docs/user-guide/git-worktrees.md
Normal file
|
|
@ -0,0 +1,173 @@
|
||||||
|
---
|
||||||
|
sidebar_position: 9
|
||||||
|
title: "Git Worktrees"
|
||||||
|
description: "Run multiple Hermes agents safely on the same repository using git worktrees and isolated checkouts"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Git Worktrees
|
||||||
|
|
||||||
|
Hermes Agent is often used on large, long‑lived repositories. When you want to:
|
||||||
|
|
||||||
|
- Run **multiple agents in parallel** on the same project, or
|
||||||
|
- Keep experimental refactors isolated from your main branch,
|
||||||
|
|
||||||
|
Git **worktrees** are the safest way to give each agent its own checkout without duplicating the entire repository.
|
||||||
|
|
||||||
|
This page shows how to combine worktrees with Hermes so each session has a clean, isolated working directory.
|
||||||
|
|
||||||
|
## Why Use Worktrees with Hermes?
|
||||||
|
|
||||||
|
Hermes treats the **current working directory** as the project root:
|
||||||
|
|
||||||
|
- CLI: the directory where you run `hermes` or `hermes chat`
|
||||||
|
- Messaging gateways: the directory set by `MESSAGING_CWD`
|
||||||
|
|
||||||
|
If you run multiple agents in the **same checkout**, their changes can interfere with each other:
|
||||||
|
|
||||||
|
- One agent may delete or rewrite files the other is using.
|
||||||
|
- It becomes harder to understand which changes belong to which experiment.
|
||||||
|
|
||||||
|
With worktrees, each agent gets:
|
||||||
|
|
||||||
|
- Its **own branch and working directory**
|
||||||
|
- Its **own Checkpoint Manager history** for `/rollback`
|
||||||
|
|
||||||
|
See also: [Checkpoints and /rollback](./checkpoints-and-rollback.md).
|
||||||
|
|
||||||
|
## Quick Start: Creating a Worktree
|
||||||
|
|
||||||
|
From your main repository (containing `.git/`), create a new worktree for a feature branch:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# From the main repo root
|
||||||
|
cd /path/to/your/repo
|
||||||
|
|
||||||
|
# Create a new branch and worktree in ../repo-feature
|
||||||
|
git worktree add ../repo-feature feature/hermes-experiment
|
||||||
|
```
|
||||||
|
|
||||||
|
This creates:
|
||||||
|
|
||||||
|
- A new directory: `../repo-feature`
|
||||||
|
- A new branch: `feature/hermes-experiment` checked out in that directory
|
||||||
|
|
||||||
|
Now you can `cd` into the new worktree and run Hermes there:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ../repo-feature
|
||||||
|
|
||||||
|
# Start Hermes in the worktree
|
||||||
|
hermes
|
||||||
|
```
|
||||||
|
|
||||||
|
Hermes will:
|
||||||
|
|
||||||
|
- See `../repo-feature` as the project root.
|
||||||
|
- Use that directory for context files, code edits, and tools.
|
||||||
|
- Use a **separate checkpoint history** for `/rollback` scoped to this worktree.
|
||||||
|
|
||||||
|
## Running Multiple Agents in Parallel
|
||||||
|
|
||||||
|
You can create multiple worktrees, each with its own branch:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /path/to/your/repo
|
||||||
|
|
||||||
|
git worktree add ../repo-experiment-a feature/hermes-a
|
||||||
|
git worktree add ../repo-experiment-b feature/hermes-b
|
||||||
|
```
|
||||||
|
|
||||||
|
In separate terminals:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Terminal 1
|
||||||
|
cd ../repo-experiment-a
|
||||||
|
hermes
|
||||||
|
|
||||||
|
# Terminal 2
|
||||||
|
cd ../repo-experiment-b
|
||||||
|
hermes
|
||||||
|
```
|
||||||
|
|
||||||
|
Each Hermes process:
|
||||||
|
|
||||||
|
- Works on its own branch (`feature/hermes-a` vs `feature/hermes-b`).
|
||||||
|
- Writes checkpoints under a different shadow repo hash (derived from the worktree path).
|
||||||
|
- Can use `/rollback` independently without affecting the other.
|
||||||
|
|
||||||
|
This is especially useful when:
|
||||||
|
|
||||||
|
- Running batch refactors.
|
||||||
|
- Trying different approaches to the same task.
|
||||||
|
- Pairing CLI + gateway sessions against the same upstream repo.
|
||||||
|
|
||||||
|
## Cleaning Up Worktrees Safely
|
||||||
|
|
||||||
|
When you are done with an experiment:
|
||||||
|
|
||||||
|
1. Decide whether to keep or discard the work.
|
||||||
|
2. If you want to keep it:
|
||||||
|
- Merge the branch into your main branch as usual.
|
||||||
|
3. Remove the worktree:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /path/to/your/repo
|
||||||
|
|
||||||
|
# Remove the worktree directory and its reference
|
||||||
|
git worktree remove ../repo-feature
|
||||||
|
```
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
- `git worktree remove` will refuse to remove a worktree with uncommitted changes unless you force it.
|
||||||
|
- Removing a worktree does **not** automatically delete the branch; you can delete or keep the branch using normal `git branch` commands.
|
||||||
|
- Hermes checkpoint data under `~/.hermes/checkpoints/` is not automatically pruned when you remove a worktree, but it is usually very small.
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
- **One worktree per Hermes experiment**
|
||||||
|
- Create a dedicated branch/worktree for each substantial change.
|
||||||
|
- This keeps diffs focused and PRs small and reviewable.
|
||||||
|
- **Name branches after the experiment**
|
||||||
|
- e.g. `feature/hermes-checkpoints-docs`, `feature/hermes-refactor-tests`.
|
||||||
|
- **Commit frequently**
|
||||||
|
- Use git commits for high‑level milestones.
|
||||||
|
- Use [checkpoints and /rollback](./checkpoints-and-rollback.md) as a safety net for tool‑driven edits in between.
|
||||||
|
- **Avoid running Hermes from the bare repo root when using worktrees**
|
||||||
|
- Prefer the worktree directories instead, so each agent has a clear scope.
|
||||||
|
|
||||||
|
## Using `hermes -w` (Automatic Worktree Mode)
|
||||||
|
|
||||||
|
Hermes has a built‑in `-w` flag that **automatically creates a disposable git worktree** with its own branch. You don't need to set up worktrees manually — just `cd` into your repo and run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /path/to/your/repo
|
||||||
|
hermes -w
|
||||||
|
```
|
||||||
|
|
||||||
|
Hermes will:
|
||||||
|
|
||||||
|
- Create a temporary worktree under `.worktrees/` inside your repo.
|
||||||
|
- Check out an isolated branch (e.g. `hermes/hermes-<hash>`).
|
||||||
|
- Run the full CLI session inside that worktree.
|
||||||
|
|
||||||
|
This is the easiest way to get worktree isolation. You can also combine it with a single query:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
hermes -w -q "Fix issue #123"
|
||||||
|
```
|
||||||
|
|
||||||
|
For parallel agents, open multiple terminals and run `hermes -w` in each — every invocation gets its own worktree and branch automatically.
|
||||||
|
|
||||||
|
## Putting It All Together
|
||||||
|
|
||||||
|
- Use **git worktrees** to give each Hermes session its own clean checkout.
|
||||||
|
- Use **branches** to capture the high‑level history of your experiments.
|
||||||
|
- Use **checkpoints + `/rollback`** to recover from mistakes inside each worktree.
|
||||||
|
|
||||||
|
This combination gives you:
|
||||||
|
|
||||||
|
- Strong guarantees that different agents and experiments do not step on each other.
|
||||||
|
- Fast iteration cycles with easy recovery from bad edits.
|
||||||
|
- Clean, reviewable pull requests targeted at v0.2.0’s new capabilities.
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue