# Cistern Git

> Cistern Git Conventions

- Skill: `michieldean/cistern-git` (Agent Skill)
- Install (CLI): `npx skillmds@latest add michieldean/cistern-git`
- Raw SKILL.md: https://api.skillmd.com/api/skills/michieldean/cistern-git/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: michieldean (https://skillmd.com/u/michieldean)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/michieldean/cistern-git

---


# Cistern Git Conventions

## Worktree model

Each droplet has an isolated worktree at `~/.cistern/sandboxes/<repo>/<droplet-id>/`.
The Castellarius creates and cleans up worktrees. Agents never run `git worktree add/remove`.

## Staging — always exclude CONTEXT.md and InstructionsFile

CONTEXT.md is written by the Castellarius on every dispatch. The provider's
InstructionsFile (AGENTS.md) is also overwritten by the
Castellarius with the cataractae prompt. Never commit either file.

```bash
git add -A -- ':!CONTEXT.md' ':!<InstructionsFile>'
git status --short   # verify no CONTEXT.md, no InstructionsFile, no binaries
```

Replace `<InstructionsFile>` with the provider-specific filename from the
active preset (determined by `provider.ProviderPreset.InstrFile()`).

## Committing — verify HEAD advances

```bash
BEFORE=$(git rev-parse HEAD)
git add -A -- ':!CONTEXT.md' ':!<InstructionsFile>'
git commit -m "<droplet-id>: <description>"
AFTER=$(git rev-parse HEAD)
if [ "$BEFORE" = "$AFTER" ]; then
  echo "ERROR: nothing staged. Commit failed."
  ct droplet recirculate <id> --notes "Commit failed: HEAD did not advance."
  exit 1
fi
```

Replace `<InstructionsFile>` with the provider-specific filename (AGENTS.md).

## Diffing — always use merge-base

```bash
# Correct — shows only this branch's own changes, regardless of rebase state
git diff $(git merge-base HEAD origin/main)..HEAD
git diff $(git merge-base HEAD origin/main)..HEAD --name-only
```

Two-dot (`git diff origin/main..HEAD`) is wrong for unrebased branches: it includes all commits since the branch diverged, meaning other PRs that merged to main after branching appear in the diff. Merge-base is always correct.

To list commits on the branch:
```bash
git log $(git merge-base HEAD origin/main)..HEAD --oneline
```

## No stash

Per-droplet worktrees start clean. **Never run `git stash`** — it silently hides uncommitted work and has caused phantom empty deliveries. If the worktree is dirty before your work, the Castellarius will detect it and recirculate.

## Pushing

```bash
git push origin <branch>
# If rebased:
git push --force-with-lease origin <branch>
```

## Branch name

Your branch is `feat/<droplet-id>`. It is created by the Castellarius. Check with:
```bash
git branch --show-current
```

