gz git-sync¶
Guarded git sync ritual for gzkit repositories.
Usage¶
Options¶
| Option | Type | Description |
|---|---|---|
--branch |
string | Branch to sync (defaults to current branch) |
--remote |
string | Remote name (default: origin) |
--apply |
flag | Execute actions (dry-run by default) |
--lint/--no-lint |
flag | Run gz lint before and after sync |
--test/--no-test |
flag | Run gz test before sync |
--auto-add/--no-auto-add |
flag | Auto stage changed files with git add -A |
--push/--no-push |
flag | Push if branch is ahead |
--json |
flag | Output JSON summary |
What It Does¶
- Validates git repo + branch state.
- Plans sync actions (fetch, pull/rebase, push).
- Optionally stages/commits local changes.
- Runs lint/test guardrails when requested.
- Executes sync operations when
--applyis set.
The pull and push steps read ahead/behind after the ceremony's own
auto-commit, not from the plan computed before it. A dirty tree that is behind
the remote becomes diverged the moment that commit lands, so the ceremony
rebases rather than attempting a fast-forward that cannot succeed. The dry-run
plan projects the same post-commit shape, so the preview matches what --apply
runs (GHI #720).
For OBPI pipeline closeout in gzkit, this is the canonical guarded sync step:
- run
uv run gz git-sync --apply --lint --testafter attestation - then emit the final completed OBPI receipt/accounting
- then update brief/ADR reconciliation artifacts
This ordering prevents completion receipts from being anchored to an obviously unsynced repository state.
Governed-scope sweep guard¶
The ceremony commits under an auto-generated chore: … (gz git-sync) subject
carrying Task: TASK-gz-git-sync. That attribution is correct for what the
ceremony produces — generated mirrors, .gzkit/ state, the ledger — and wrong
for src/** / tests/** work, which
.gzkit/rules/tests.md § TASK-Driven Workflow
scopes a real Task: trailer to.
So before git add -A, sync reads the three sets that sweep would stage — the
index, tracked-but-unstaged changes, and untracked files — and refuses if any
path lands in src/ or tests/. Scope is exactly those two roots: guarding the
generated surfaces would disarm the verb rather than defend it. The guard fails
open on a git error, so an unreadable worktree never strands a sync.
Recovery is what the message says: commit the governed work under its own typed subject, then re-run sync.
$ uv run gz git-sync --apply
Git sync execution
Branch: main
Remote: origin
ahead=0 behind=0 diverged=False dirty=True
Actions:
- git add -A
- git fetch --prune origin
- git push origin main
Blockers:
- Refusing `git add -A`: the sweep would stage changes in trailer-governed
scope:
src/gzkit/commands/sync.py
tests/commands/test_sync_sweep_guard.py
...
Next step: commit the governed work under its own message — `git commit -m
'fix(<scope>): <summary> (GHI #N)'` with a `Task:` trailer, confirming it
succeeded — then re-run `gz git-sync --apply`.
Exit code 1; nothing is staged, committed, or pushed.