4.2 KiB
4.2 KiB
CLAUDE.md — Project Context for AI Assistants
What This Project Is
A set of shell scripts for bidirectional git repository synchronization between
two networks (home ↔ enterprise) that have no direct network connection.
The transport medium is a shared file system, mounted at ~/fifiletrans on
both sides (path configurable via $SYNC_SHARE or as a CLI argument).
Network Context
- Home network: has a Gitea instance (local git hosting + mirror/backup)
- Office network: has a GitLab instance
- There is no direct sync between Gitea and GitLab — bundle files via the shared filesystem are the only transport between the two networks
Scripts
| Script | Role |
|---|---|
sync-push.sh |
Incremental export: bundles new commits → shared folder |
sync-pull.sh |
Import: picks a bundle from shared folder, fetches branches, integrates |
sync-init-export.sh |
One-time bootstrap: full bundle + copies scripts → shared folder |
sync-init-import.sh |
One-time bootstrap: clones from full bundle into a new directory |
gitea-setup.sh |
Registers a local repo (git or unversioned) with the home Gitea instance |
Design Decisions
git bundlechosen overgit format-patch: handles multi-branch and arbitrary commit ranges in a single file; no dependency on branch topology.- Incremental tracking via
git config sync.exported.<branch>(per branch, local git config). Avoids polluting branches/tags namespace. - Incoming commits fetched to
refs/sync/incoming/<branch>— not merged automatically. User inspects and chooses ff / merge / rebase / skip. - Semi-automated: scripts triggered manually; minimal prompts only where a decision is needed (integration strategy, bundle selection).
- Multi-branch: all scripts iterate all local branches. Checkpoints are independent per branch.
- Gitea auto-push is opt-in (
git config sync.gitea.autopush true), toggled per repo, and runs automatically at the end ofsync-push.shwhen enabled. - Initial bootstrap (
sync-init-export/import) handles the case where the receiving machine has no directory at all — creates the repo from scratch and leaves both sides in identical state with checkpoints pre-set.
Git Config Keys (all local, per repo)
| Key | Written by | Purpose |
|---|---|---|
sync.exported.<branch> |
sync-push.sh |
Last exported commit hash per branch |
sync.gitea.autopush |
gitea-setup.sh |
true/false auto-push after bundle export |
sync.gitea.remote |
gitea-setup.sh |
Gitea remote name (default: gitea) |
Reset one branch checkpoint: git config --unset sync.exported.<branch>
Reset all checkpoints: git config --remove-section sync.exported
Bundle Filename Convention
<repo-name>-from-<hostname>-<YYYYMMDD-HHMMSS>.bundle ← ongoing sync
<repo-name>-INIT-from-<hostname>-<YYYYMMDD-HHMMSS>.bundle ← initial bootstrap
Pull scripts filter by <repo-name> so multiple repos can share one folder.
External Dependencies
git(standard, all features used are in git ≥ 2.x)bash≥ 4 (for associative-array-free scripts; uses indexed arrays only)tea(Gitea CLI) — only required forgitea-setup.sh- Standard POSIX tools:
find,awk,cut,du,hostname,date
Platform
Home side runs on Linux / Raspberry Pi (aarch64). Scripts use no architecture-specific features and should work on any POSIX system.
When Modifying These Scripts
- Keep
set -euo pipefail— fail fast is intentional. - The "nothing new to export" pre-check in
sync-push.shmust run beforegit bundle create— git errors on an empty bundle. sync-pull.shmust not auto-merge without user confirmation.sync-init-import.shmust setsync.exported.<branch>checkpoints for all imported branches so the firstsync-pushfrom the new machine is incremental.gitea-setup.shparsestea login list --output csv; column order is:NAME, URL, SSH-URL, USER, ACTIVE. The active login hastruein column 5.- Test each script against both first-run (no checkpoints) and incremental scenarios.
- Test
gitea-setup.shagainst both: folder already a git repo, and raw unversioned folder.