Document bootstrap batching design · Entire

Document bootstrap batching design

Sessions

a2d74df554b4View transcript

Changes

1

Bootstrap Batching Design

bootstrap currently streams one source pack into one target push. That is good for many initial syncs, but it is not enough for very large single-branch repositories where one initial pack is itself too large for comfortable target-side unpacking and indexing.

This note sketches a batching design for large bootstrap jobs.

Goal

Reduce per-push size and target-side receive-pack / index-pack pressure for very large initial syncs, while preserving the main benefit of bootstrap:

Non-Goals

V1 batching should not try to solve every large-migration problem.

Out of scope:

Why Per-Ref Batching Is Not Enough

Per-ref batching is easy:

That helps when there are many refs and each ref is moderate in size.

It does not help for repositories where a single branch is enormous. Linux master is the motivating example: even a single branch bootstrap can be too large for one target-side unpack/index step.

Preferred Model

Use branch checkpoint batching with temporary refs.

High-level idea:

  1. Choose a sequence of ancestor checkpoints for a source branch.
  2. Push them oldest to newest into a temporary target ref.
  3. Once the final tip is present, create the real target ref.
  4. Delete the temporary ref at the end.

This gives:

Command Shape

Possible CLI extension:

git-sync bootstrap \
  --batch-max-pack-bytes 1073741824 \
<source-url> \
<target-url>

Possible related flags:

The first version should only need --batch-max-pack-bytes.

Temporary Ref Strategy

For each target branch:

Flow:

  1. Create/update only the temp ref during intermediate batches.
  2. After the final tip batch succeeds:
    • create the real ref at the final tip
    • delete the temp ref

This keeps the target repository in a cleaner state:

If failure happens mid-run:

Checkpoint Selection

The most practical first heuristic is first-parent checkpointing.

For a branch tip:

  1. Walk first-parent ancestry backward.
  2. Sample candidate checkpoint commits.
  3. Starting from the oldest candidate, estimate each batch by doing a source fetch against the previous checkpoint as have.
  4. Pick the largest checkpoint whose pack stays under --batch-max-pack-bytes.
  5. Repeat until the branch tip is reached.

This is only a heuristic:

But it is much simpler than exact graph partitioning and good enough for a first implementation.

Batch Flow For One Branch

Given checkpoints:

The flow is:

  1. Fetch source pack for C1 with no have.
  2. Push it to temp ref refs/gitsync/bootstrap/heads/main.
  3. Fetch source pack for C2 with have=C1.
  4. Push update of temp ref to C2.
  5. Fetch source pack for C3 with have=C2.
  6. Push update of temp ref to C3.
  7. Fetch source pack for tip with have=C3.
  8. Push update of temp ref to tip.
  9. Create real target ref refs/heads/main at tip.
  10. Delete temp ref.

The final ref creation can be:

The first version should prefer the separate final ref creation because it is easier to reason about.

Tags

Tags should not be pushed during intermediate branch batches.

Recommended rule:

This avoids cases where a tag points at an object graph that is not yet fully present on target.

V1 batching should support:

Tag batching can be added later.

Restart and Recovery

Batching is only worth doing if failures are restartable.

Minimum restart model:

  1. Detect existing temp refs on target.
  2. Resolve their current hashes.
  3. Resume from the latest completed checkpoint instead of starting from zero.

If --keep-temp-refs-on-failure is false, cleanup can still happen on clean failures, but default restartability is more valuable than aggressive cleanup.

Safety Model

V1 batching should remain strict.

Allow only:

Fail if:

Implementation Shape

Suggested pieces:

The estimator should reuse the existing relay mechanics:

But it will need one new planning pass to probe likely batch sizes before actual execution.

Operator Output

Batching should be explicit in output.

Text output should include:

JSON should include:

Practical Risks

This is still likely worthwhile for very large initial migrations because it changes a single huge risky operation into several bounded ones.

Recommended Phases

Phase A:

Phase B:

Phase C:

Phase D: