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:
42
docs/adr/001-josh-proxy-for-sync.md
Normal file
42
docs/adr/001-josh-proxy-for-sync.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# ADR-001: Josh-proxy for Bidirectional Sync
|
||||
|
||||
**Status:** Accepted
|
||||
**Date:** 2026-01
|
||||
|
||||
## Context
|
||||
|
||||
We need bidirectional sync between a monorepo and N external subrepos. Each subrepo corresponds to a subfolder in the monorepo. Developers on both sides should see a clean, complete git history — not synthetic commits or squashed blobs.
|
||||
|
||||
### Alternatives considered
|
||||
|
||||
1. **git subtree**: Built into git. `git subtree split` extracts a subfolder into a standalone repo. However, subtree split rewrites history on every run (O(n) on total commits), creating new SHAs each time. Bidirectional sync requires manual `subtree merge` with conflict-prone history grafting. No transport-layer filtering — all content must be fetched.
|
||||
|
||||
2. **git submodule**: Tracks external repos via `.gitmodules` pointer commits. Does not provide content-level integration — monorepo commits don't contain subrepo files directly. Developers must run `git submodule update`. Bidirectional sync is not a supported workflow.
|
||||
|
||||
3. **Custom diff-and-patch scripts**: Compute diffs between monorepo subfolder and subrepo, apply patches in both directions. Fragile with renames, binary files, and merge conflicts. Loses authorship and commit granularity.
|
||||
|
||||
4. **josh-proxy**: A git proxy that computes filtered views of repositories in real-time. Clients `git clone` through josh and receive a repo containing only the specified subfolder, with history rewritten to match. Josh maintains a persistent SHA mapping, so the same monorepo commit always produces the same filtered SHA. Bidirectional: pushing back through josh maps filtered commits to monorepo commits.
|
||||
|
||||
## Decision
|
||||
|
||||
Use josh-proxy as the transport layer for all sync operations.
|
||||
|
||||
## Consequences
|
||||
|
||||
**Positive:**
|
||||
- Clean git history in both directions — no synthetic commits
|
||||
- Deterministic SHA mapping — same monorepo state always produces same filtered SHA
|
||||
- Bidirectional by design — push through josh maps back to monorepo
|
||||
- Transport-layer filtering — content exclusion happens at clone/push time, not via generated files
|
||||
- Supports any git hosting platform (Gitea, GitHub, GitLab) since it's a proxy
|
||||
|
||||
**Negative:**
|
||||
- Requires running a josh-proxy instance (operational overhead)
|
||||
- Josh-proxy is a Rust project with a smaller community than git-native tools
|
||||
- Proxy must have network access to the monorepo's git server
|
||||
- Josh's SHA mapping is opaque — debugging requires understanding josh internals
|
||||
- First-parent traversal behavior must be respected in merge commits (see ADR-008)
|
||||
|
||||
**Risks:**
|
||||
- Josh-proxy downtime blocks all sync operations
|
||||
- Josh-proxy bugs could corrupt history mapping (mitigated by force-with-lease on forward, always-PR on reverse)
|
||||
Reference in New Issue
Block a user