Skip to content

feat: fetch and clone from git bundle files #2633

Description

The need

Git bundles are the standard way to transfer repository data offline — they package refs + pack data into a single file. Regular git supports git fetch <bundle> and git clone <bundle> to pull objects and refs from them. Gitoxide currently has no equivalent.

This is relevant to the gix towards 1.0 roadmap (clone & fetch are core), and to C-integrate-gitoxide efforts where tools like eza/zed need offline-capable cloning.

Proposed API

A new GitBundle parser in gix-pack that reads the # v2 git bundle format, plus two methods on Repository:

// Fetch objects + refs from a bundle into an existing repo
let outcome = repo.fetch_from_bundle(path, &mut progress, &interrupt, opts)?;

// Create a new repo from a bundle
let repo = Repository::clone_from_bundle(dest, kind, path, &mut progress, &interrupt, None)?;

Design decisions

  • Mirrors git behavior: no special --bundle flag — the CLI auto-detects .bundle files when passed as the remote argument
  • Streaming: pack data streams directly from disk through gix's parallel pack processor, O(1) memory
  • Incremental bundles: prerequisite refs are parsed and exposed (validation is left to the caller for now)
  • Zero existing code touched: entirely additive, gated behind existing feature flags

Scope

What's included:

  • Parse # v2 git bundle header format (refs, prerequisites, pack data)
  • fetch_from_bundle() and clone_from_bundle() on Repository
  • CLI auto-detection in clone and fetch commands
  • is_bundle() helper for bundle file detection

What's intentionally deferred:

  • Bundle creation (git bundle create equivalent)
  • Bundle URI protocol (network bundle retrieval)
  • Prerequisite auto-validation during fetch
  • git bundle verify equivalent

Prior art

  • Git's bundle.c — the reference implementation
  • gix-pack already has Bundle::write_to_directory() for pack processing — this reuses it

Testing

  • 26 unit tests for the parser (full, incremental, empty, CRLF, prerequisites, edge cases)
  • 12 integration tests including an 89MB real-world shallow nixpkgs bundle (full and incremental, fetch and clone, bare and non-bare)
  • All 360 existing integration tests pass unchanged

Disclosure

This proposal was developed with AI assistance. A working implementation exists on a feature branch and can be submitted as a PR if the approach looks right.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions