Update docs, changelog, examples, and add ADRs for v1.2
- Add v1.1.0 and v1.2.0 changelog entries - Add exclude field to config reference and example config - Add ADRs documenting all major design decisions - Fix step numbering in reverse_sync() - Fix action.yml to copy VERSION file - Add dist/ and .env to .gitignore - Use refs/tags/ format for Nix flake tag refs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
33
docs/adr/003-force-with-lease-forward.md
Normal file
33
docs/adr/003-force-with-lease-forward.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# ADR-003: Force-with-Lease for Forward Sync
|
||||
|
||||
**Status:** Accepted
|
||||
**Date:** 2026-01
|
||||
|
||||
## Context
|
||||
|
||||
Forward sync pushes monorepo changes to the subrepo. If someone pushes directly to the subrepo between when josh-sync reads its HEAD and when josh-sync pushes, a naive `git push` would overwrite their work. A `git push --force` would be worse — it would silently destroy concurrent changes.
|
||||
|
||||
## Decision
|
||||
|
||||
Use `git push --force-with-lease=refs/heads/<branch>:<expected-sha>` for all forward sync pushes. The expected SHA is recorded at the start of the sync operation (the "lease").
|
||||
|
||||
### How it works
|
||||
|
||||
1. Record subrepo HEAD SHA before any operations: `subrepo_sha=$(subrepo_ls_remote "$branch")`
|
||||
2. Perform merge of monorepo changes onto subrepo state
|
||||
3. Push with explicit lease: `--force-with-lease=refs/heads/main:<subrepo_sha>`
|
||||
4. If the subrepo HEAD changed since step 1, git rejects the push
|
||||
5. Josh-sync reports `lease-rejected` and retries on the next run
|
||||
|
||||
## Consequences
|
||||
|
||||
**Positive:**
|
||||
- Never overwrites concurrent changes — git atomically checks the expected SHA
|
||||
- Explicit SHA lease (not just "current tracking ref") prevents stale-ref bugs
|
||||
- Failed leases are retried on the next sync run — no data loss, just delay
|
||||
- Works correctly with josh-proxy's SHA mapping
|
||||
|
||||
**Negative:**
|
||||
- Lease-rejected means the sync run did work that gets discarded (clone, merge, etc.)
|
||||
- Persistent lease failures indicate a concurrent push pattern that needs investigation
|
||||
- Requires the `--force-with-lease` flag with explicit SHA — the shorthand form (`--force-with-lease` without `=`) is unsafe because it uses the local tracking ref, which may be stale
|
||||
Reference in New Issue
Block a user