- **[Setup Guide](docs/guide.md)** — Step-by-step: prerequisites, importing existing subrepos, CI workflows, file exclusion, and troubleshooting
- **[Configuration Reference](docs/config-reference.md)** — Full `.josh-sync.yml` field documentation
- **[Architecture Decision Records](docs/adr/)** — Design rationale and trade-offs
- **[Changelog](CHANGELOG.md)** — Version history
## Versioning
josh-sync follows [semver](https://semver.org/):
| Bump | Meaning | Action required |
|------|---------|-----------------|
| **Patch** (1.x.**y**) | Bug fixes only | Safe to upgrade |
| **Minor** (1.**y**.0) | New optional config fields, new commands, new action inputs | Safe to upgrade; new features are opt-in |
| **Major** (**y**.0.0) | Removed or renamed config fields, CLI flags, action inputs, env vars, or state format | Read the **Breaking Changes** section in the changelog before upgrading |
CI workflows pin to a floating major tag (e.g. `@v1`). A breaking change bumps the major version and moves the tag — `@v1` workflows keep working until you explicitly update to `@v2`.
- **Forward sync** (mono → subrepo): pushes directly if clean, creates conflict PR if not. Uses `--force-with-lease` for safety.
- **Reverse sync** (subrepo → mono): creates a PR by default. Add `--force` to bypass the PR and push directly to the mono branch (destructive).
- **Adoption**: existing active subrepos can be connected to josh-sync with a normal fast-forward merge commit, preserving old subrepo history and avoiding force-push.
- **File exclusion**: `exclude` patterns are embedded inline in the josh-proxy URL. Excluded files exist only in the monorepo.
- **Filter reconciliation**: Changing the exclude list auto-creates a merge commit that connects old and new histories — no force-push needed.
- **Loop prevention**: `Josh-Sync-Origin:` git trailer filters out bot commits.
- **State tracking**: orphan branch `josh-sync-state` stores JSON per target/branch.