Skip to content

feat(sync): wire git-bundle mode so peer rehydrate keeps working git history - #481

Merged
Jesssullivan merged 3 commits into
mainfrom
codex/git-bundle-dev-env-parity
Jun 3, 2026
Merged

feat(sync): wire git-bundle mode so peer rehydrate keeps working git history#481
Jesssullivan merged 3 commits into
mainfrom
codex/git-bundle-dev-env-parity

Conversation

@Jesssullivan

@Jesssullivan Jesssullivan commented May 31, 2026

Copy link
Copy Markdown
Owner

What

Makes TCFS preserve working git history when a repo is rehydrated on a peer host, closing the structural dev-env parity gap where a rehydrated repo had working-tree files but no usable .git history.

This wires the previously dead git_safety.rs bundle path behind the existing git_sync_mode = "bundle" policy:

  • Sync: collect_files captures each safe enrolled repo's .git as a single .git-tcfs-bundle object via git bundle create --all, and bundle mode skips raw .git/* internals.
  • Rehydrate: CLI pull detects .git-tcfs-bundle and restores .git metadata in place using restore_git_bundle_into, so the peer gets real branches, tags, objects, and HEAD.
  • Safety: repos with active git operations are skipped for that sync cycle.

Recovery bug fixed

A fresh git init leaves HEAD on a checked-out branch, and git refuses +refs/*:refs/* into that current branch. The restore path now parks HEAD on a temporary unborn branch before mirror-fetching bundle refs, then restores HEAD to the bundle's default branch.

Validation

  • cargo build -p tcfs-cli passed during local validation.
  • crates/tcfs-sync/tests/git_bundle_roundtrip.rs passes: bundle object synced, raw .git/* excluded, peer pulls objects, .git restored, both commits visible in git log, git status clean except the synced bundle artifact, HEAD on main.
  • GitHub checks are green: Build + Lint + Test, fleet_live, Flake Check, Nix Build, Linux/macOS builds, FileProvider staticlib, iOS typecheck, cargo-deny, Secret Scan.

Follow-ups intentionally deferred

  • .git-tcfs-bundle remains as a synced artifact after restore. Deleting it locally would currently propagate deletion to peers, so cleanup/gitignore policy should be a separate decision.
  • git bundle create --all can be expensive for very large repos; add change-detection before using bundle mode on stress targets like linux-xr.

Branch on git_sync_mode="bundle" in collect_files: capture each enrolled
repo's .git as a single `git bundle --all` (.git-tcfs-bundle) synced as a
normal object, while collect_files_inner skips the raw .git/* internals.
On rehydrate, restore_git_bundles_under reconstructs .git in place via
git init + mirror-fetch + HEAD restore, so `git log` / `git status` /
`git fetch` work on the peer without clobbering already-synced files.

Park HEAD on a throwaway unborn branch before the mirror fetch: a fresh
`git init` leaves HEAD on refs/heads/main and git refuses
`+refs/*:refs/*` into the checked-out branch, which previously made
restore a no-op.

Adds git_bundle_roundtrip integration test proving a 2-commit repo
round-trips with full history and a clean working tree on the peer.
Wire the bundle-restore path into cmd_pull_with_operator so a pulled
.git-tcfs-bundle reconstructs the repo's .git in place (off-runtime via
spawn_blocking). Completes the dev-env-parity loop: a peer that
rehydrates a bundle-synced repo gets working git history, not a hollow
.git. The bundle artifact is left in place (it is a synced object;
local deletion would propagate to peers).
@Jesssullivan
Jesssullivan marked this pull request as ready for review June 3, 2026 19:19
@Jesssullivan
Jesssullivan merged commit 08752b8 into main Jun 3, 2026
10 checks passed
@Jesssullivan
Jesssullivan deleted the codex/git-bundle-dev-env-parity branch June 3, 2026 19:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant