Parent metadata
sm records every stack relationship in .git/config. There is no separate database, no .stacman/ directory, no remote service. If you want to know what sm knows, run git config --list --local | grep stac-man.
The keys
For every tracked branch:
[branch "feat/api-endpoints"]
stac-man-parent = feat/db-schema # who am I stacked on
stac-man-parent-sha = 4f1e2a91… # tip of parent at last restack
stac-man-pr = 42 # GitHub PR number, if submittedAnd one repo-level key:
[stac-man]
trunk = main # see Concepts → Trunk
version = 2 # metadata schema versionThat's the entire on-disk surface in steady state. (Two more files appear during a paused restack and the undo log; see below.)
What each key means
branch.<n>.stac-man-parent
The name of the parent branch. May be trunk or another tracked branch. If absent, the branch is untracked — sm ignores it.
branch.<n>.stac-man-parent-sha
The tip of the parent branch the last time this branch was rebased onto it. The restack engine compares the parent's current tip to this value to decide if work is needed.
If the SHAs match: this branch is already on top of its parent's current tip. Skip.
If they differ: the parent moved (someone amended, the user ran sm modify, sync fast-forwarded trunk, …). Rebase, then update this key.
branch.<n>.stac-man-pr
The GitHub PR number, recorded when sm submit opens or adopts a PR. Used by sm log, sm show, sm land, and sm sync --retarget-bases. Can be re-bound by re-running sm submit.
The transient files
Two small JSON files appear under .git/stac-man/ for the duration of specific operations:
restack.json— the in-flight queue while a restack is paused on a conflict. Cleared bysm continue(when the queue drains) orsm abort.history.json— the rolling undo log, capped at 50 entries.sm undoconsumes it.
You should not edit these by hand. If restack.json is malformed, sm abort is always safe.
What sm doctor checks
sm doctor (alias sm status) re-derives the truth from git itself and compares it to the metadata above. It reports:
| Issue | What it means | Fix |
|---|---|---|
needs restack | Parent SHA differs from parent's current tip. | sm restack |
stale parent SHA | Recorded SHA is no longer reachable. | sm restack |
drifted parent SHA | Branch's tip rewrote outside sm. | sm restack, or fix manually |
untracked branch with unique commits | A branch you might want in the stack but haven't tracked. | sm checkout <name> && sm track |
graph issues | Cycles, missing parents, etc. — should be impossible in steady state. | Surface as a bug |
Run sm doctor whenever the stack feels off. It's read-only.
Why git config
- It's already there. No new file format to learn, no new place state can drift to.
git configis the same on every platform.- Cloning the repo elsewhere wipes
smstate automatically — the metadata is intentionally per-clone, not pushed to origin. sm get <PR-number>is the recovery path for moving a stack between machines: it walks the GitHub PR'sbase_refchain and re-records the keys on the new clone.
Why not a remote source of truth
sm deliberately never pushes its own metadata. Two reasons:
- No SaaS, no login. That's the project's whole point.
- The PR base graph on GitHub already holds the same shape. If you lose
.git/config,sm get <PR>reconstructs it.
If you want a richer collaborative experience, use a hosted product. sm is for the local-first half of the spectrum.
