pub struct GitProjection<'a> {
pub heddle_repo: &'a Repository,
pub git_repo_path: Option<PathBuf>,
pub mapping: SyncMapping,
pub commit_message_overrides: HashMap<StateId, String>,
pub commit_parent_overrides: HashMap<StateId, Vec<ObjectId>>,
/* private fields */
}Expand description
Legacy-named implementation for explicit Git Projection and Bridge Mirror operations.
Fields§
§heddle_repo: &'a Repository§git_repo_path: Option<PathBuf>§mapping: SyncMapping§commit_message_overrides: HashMap<StateId, String>§commit_parent_overrides: HashMap<StateId, Vec<ObjectId>>Implementations§
Source§impl<'a> GitProjection<'a>
impl<'a> GitProjection<'a>
Sourcepub fn new(heddle_repo: &'a HeddleRepository) -> Self
pub fn new(heddle_repo: &'a HeddleRepository) -> Self
Create a Git Projection helper for a Heddle repository.
Sourcepub fn init_mirror(&mut self) -> GitProjectionResult<()>
pub fn init_mirror(&mut self) -> GitProjectionResult<()>
Initialize the Bridge Mirror in the .heddle/git directory.
Sourcepub fn init_mirror_with_guard(&mut self) -> GitProjectionResult<MirrorInitGuard>
pub fn init_mirror_with_guard(&mut self) -> GitProjectionResult<MirrorInitGuard>
Variant of init_mirror that returns a MirrorInitGuard so
callers performing a multi-step bring-up (init + first export)
can roll back the partially-created mirror if a later step
fails. Call guard.commit() once the mirror is known-good.
Sourcepub fn mirror_path(&self) -> PathBuf
pub fn mirror_path(&self) -> PathBuf
Get the path to the legacy Bridge Mirror directory.
Sourcepub fn is_initialized(&self) -> bool
pub fn is_initialized(&self) -> bool
Check if a legacy Bridge Mirror is initialized.
Sourcepub fn open_git_repo(&self) -> GitProjectionResult<SleyRepository>
pub fn open_git_repo(&self) -> GitProjectionResult<SleyRepository>
Open the Git repository (mirror or regular).
Sourcepub fn sort_states_topologically(
&self,
states: &[StateId],
) -> GitProjectionResult<Vec<StateId>>
pub fn sort_states_topologically( &self, states: &[StateId], ) -> GitProjectionResult<Vec<StateId>>
Sort states topologically (parents before children).
Sourcepub fn export(&mut self) -> GitProjectionResult<ExportStats>
pub fn export(&mut self) -> GitProjectionResult<ExportStats>
Export all Heddle states to Git commits.
pub fn set_commit_message_override( &mut self, state_id: StateId, message: String, )
pub fn set_commit_parent_override( &mut self, state_id: StateId, parents: Vec<ObjectId>, )
Sourcepub fn linearize_unmapped_tip_to_checkout(&mut self)
pub fn linearize_unmapped_tip_to_checkout(&mut self)
Export an otherwise-unmapped tip on top of the checkout branch’s current Git commit. Multi-peer land enables this for every peer after the first so the batch advances one linear Git branch.
pub fn with_mapping_rollback<T>( &mut self, operation: impl FnOnce(&mut Self) -> GitProjectionResult<T>, ) -> GitProjectionResult<T>
Sourcepub fn push(&mut self, remote_name: &str) -> GitProjectionResult<Vec<String>>
pub fn push(&mut self, remote_name: &str) -> GitProjectionResult<Vec<String>>
Push to a Git remote. Returns the full names of the refs written
at the destination this invocation (see Self::push_with_scope_force).
Sourcepub fn push_with_scope(
&mut self,
remote_name: &str,
scope: GitPushScope,
) -> GitProjectionResult<Vec<String>>
pub fn push_with_scope( &mut self, remote_name: &str, scope: GitPushScope, ) -> GitProjectionResult<Vec<String>>
Push to a Git remote with an explicit ref scope. Returns the full names of the refs written at the destination this invocation.
Sourcepub fn push_with_scope_force(
&mut self,
remote_name: &str,
scope: GitPushScope,
force: bool,
) -> GitProjectionResult<Vec<String>>
pub fn push_with_scope_force( &mut self, remote_name: &str, scope: GitPushScope, force: bool, ) -> GitProjectionResult<Vec<String>>
Push to a Git remote with an explicit ref scope and optional non-fast-forward ref movement.
Returns the full names (e.g. refs/heads/<thread>,
refs/notes/heddle, refs/tags/<tag>) of the refs WRITTEN at the
destination this invocation — creations, fast-forwards, and forced
rewinds — sorted for deterministic output. A no-op push returns an
empty list. Retraction deletes are not included.
Sourcepub fn export_to_path(
&mut self,
target_path: &Path,
) -> GitProjectionResult<ExportStats>
pub fn export_to_path( &mut self, target_path: &Path, ) -> GitProjectionResult<ExportStats>
Export current Heddle state into the internal mirror, then write it out
as a bare git repository at target_path. Auto-initializes
target_path as a bare repo if it does not already exist.
Sourcepub fn fetch(&mut self, remote_name: &str) -> GitProjectionResult<()>
pub fn fetch(&mut self, remote_name: &str) -> GitProjectionResult<()>
Fetch Git refs and objects into the internal mirror without moving Heddle thread refs or the current worktree.
Sourcepub fn hydrate_checkout_heddle_notes_without_mirror(root: &Path) -> bool
pub fn hydrate_checkout_heddle_notes_without_mirror(root: &Path) -> bool
Best-effort adoption preflight for the ingest-backed path.
Plain Git clones do not fetch refs/notes/heddle by default, but
Heddle-pushed overlay remotes use that ref to preserve Git commit
-> Heddle state identity. Ingest reads directly from the checkout, so
it only needs refs/notes/heddle hydrated in the checkout’s own object
database before GitSource opens the repository.
Sourcepub fn pull(&mut self, remote_name: &str) -> GitProjectionResult<GitPullOutcome>
pub fn pull(&mut self, remote_name: &str) -> GitProjectionResult<GitPullOutcome>
Pull from a Git remote.
pub fn seed_git_checkpoint_mappings_from_checkout( &mut self, mirror_repo: &SleyRepository, ) -> GitProjectionResult<()>
pub fn stage_ingest_source_in_mirror( &mut self, source: &Path, refs: &[String], ) -> GitProjectionResult<()>
Sourcepub fn write_through_current_checkout(
&mut self,
) -> GitProjectionResult<WriteThroughOutcome>
pub fn write_through_current_checkout( &mut self, ) -> GitProjectionResult<WriteThroughOutcome>
Make the checkout’s real .git view agree with the current Heddle
thread: copy exported objects from the internal mirror, advance the
matching Git branch, attach HEAD, and rebuild the Git index from the
exported commit tree.
pub fn write_through_current_checkout_with_message( &mut self, state_id: StateId, message: String, ) -> GitProjectionResult<WriteThroughOutcome>
Sourcepub fn update_intent_to_add(
&self,
state_id: &StateId,
) -> GitProjectionResult<()>
pub fn update_intent_to_add( &self, state_id: &StateId, ) -> GitProjectionResult<()>
Mark files that Heddle has captured but that Git still sees as
untracked as intent-to-add in the colocated checkout’s index,
so a colocated developer’s git status shows AM new_file
(“Heddle knows about it; no Git blob committed yet”) instead of
?? new_file (“untracked — Git knows nothing”). The placeholder
entry uses the empty-blob oid and a zeroed stat, so Git always
reports the working-tree content as modified-against-index.
Ported from jujutsu’s update_intent_to_add (lib/src/git.rs),
which diffs old_tree vs new_tree and flags paths present in
the new tree but absent from the old one. Here new_tree is the
just-captured Heddle state’s tree and old_tree is whatever the
checkout’s index already tracks — paths already in the index are
not ??, so they are left untouched (no spurious marking of
tracked or unchanged files).
Call frequency mirrors jj: this fires at a Heddle parent/state
change (capture), not on every command. A later checkpoint
rebuilds the index from the committed tree via
Self::write_through_current_checkout, replacing these
placeholder entries with real ones — so the index is never
churned by read-only invocations.
Sourcepub fn write_through_thread_checkout(
&mut self,
thread: &str,
) -> GitProjectionResult<WriteThroughOutcome>
pub fn write_through_thread_checkout( &mut self, thread: &str, ) -> GitProjectionResult<WriteThroughOutcome>
Make the checkout’s real .git view agree with a specific Heddle
thread. thread switch uses this after writing Heddle HEAD because
resolving “current” through Git-overlay discovery can still see the
branch that was active before the switch.
pub fn write_current_checkout_from_existing_mirror( &mut self, ) -> GitProjectionResult<WriteThroughOutcome>
Source§impl<'a> GitProjection<'a>
impl<'a> GitProjection<'a>
pub fn mapping_path(&self) -> PathBuf
pub fn mapping_tmp_path(&self) -> PathBuf
pub fn write_mapping_tmp_to_disk(&self) -> GitProjectionResult<PathBuf>
pub fn commit_mapping_tmp_to_disk(&self) -> GitProjectionResult<()>
pub fn save_mapping_to_disk(&self) -> GitProjectionResult<()>
Sourcepub fn build_existing_mapping(
&mut self,
git_repo_path: Option<&Path>,
) -> GitProjectionResult<()>
pub fn build_existing_mapping( &mut self, git_repo_path: Option<&Path>, ) -> GitProjectionResult<()>
Build the export identity mapping from portable metadata and the served
bridge cache. refs/notes/heddle is authoritative because it travels
with Git history; git-projection-mapping.json is the local served/export cache
after visibility filtering. Ingest identity lives separately at
.heddle/ingest/sha_map.sqlite and is intentionally not folded in here.
pub fn seed_ingest_identity_mappings_from_repo( &mut self, repo: &SleyRepository, ) -> GitProjectionResult<()>
pub fn prune_unreachable_mapping_entries( &mut self, ) -> GitProjectionResult<usize>
Sourcepub fn consolidate_mirror(&self) -> GitProjectionResult<usize>
pub fn consolidate_mirror(&self) -> GitProjectionResult<usize>
Consolidate the legacy Bridge Mirror (.heddle/git) — the bare Sley repo used
by explicit Git projection import/export/sync paths — by packing every
on-disk object into a single pack and dropping the now-redundant loose
copies.
The mirror accumulates one loose object per minted/imported commit, tree,
and blob (thousands on a real clone). Loose-object reads dominate legacy Bridge Mirror import/export
and reconstruction paths. Active Git-overlay status
and checkpoint paths use the checkout’s real .git repository, not this
mirror. heddle maintenance gc already consolidates Heddle’s native
store; this brings the legacy Bridge Mirror to parity.
Correctness: this uses [repack_all_objects], which gathers EVERY object
on disk (every loose object and every pack), not the reachability closure
of any ref set. That matters because the mirror holds more than the
current checkout — every thread’s refs/heads/*, markers, refs/notes/heddle,
and the served-frontier record — AND because some lossy/non-UTF8 imports’
verbatim bytes live ONLY in the mirror and cannot be re-minted from heddle
state (see git_export.rs commit_is_byte_faithful). Packing everything
on disk preserves all of them and is content-addressed, so OIDs are
byte-for-byte unchanged. The prune only drops loose objects whose canonical
copy is now in the new pack, so it is lossless and fsck stays clean.
Idempotent: a second run finds nothing new loose and is a no-op.
Returns the number of loose objects consolidated into the pack (and thus
removed from disk). Ok(0) when the mirror has no objects to pack.
Source§impl GitProjection<'_>
impl GitProjection<'_>
Sourcepub fn reconstruction_repo(&mut self) -> GitProjectionResult<SleyRepository>
pub fn reconstruction_repo(&mut self) -> GitProjectionResult<SleyRepository>
Open (initializing if necessary) a writable sley repo suitable for reconstruction’s tree-OID resolution. Any writable odb works — git trees are content-addressed — so the bridge’s own mirror is reused.
Sourcepub fn reconstruct_commit_bytes(
&self,
repo: &SleyRepository,
state: &State,
) -> GitProjectionResult<Vec<u8>>
pub fn reconstruct_commit_bytes( &self, repo: &SleyRepository, state: &State, ) -> GitProjectionResult<Vec<u8>>
Reconstruct the byte-exact commit content for state against repo (see
reconstruct_commit_bytes), using the bridge’s import-built mapping for
parent OIDs.
Sourcepub fn reconstruct_and_write_commit(
&self,
repo: &SleyRepository,
state: &State,
) -> GitProjectionResult<ObjectId>
pub fn reconstruct_and_write_commit( &self, repo: &SleyRepository, state: &State, ) -> GitProjectionResult<ObjectId>
Reconstruct state’s commit object from Heddle state and WRITE it into
repo’s object database, returning its git OID (see write_commit_object).
The export’s commit-minting step (#567): the object is regenerated from
state, so it lands at the original SHA without the mirror needing to hold
the verbatim bytes.
Sourcepub fn reconstruct_commit_for_git_sha(
&self,
repo: &SleyRepository,
sha: &str,
) -> GitProjectionResult<Option<Vec<u8>>>
pub fn reconstruct_commit_for_git_sha( &self, repo: &SleyRepository, sha: &str, ) -> GitProjectionResult<Option<Vec<u8>>>
Reconstruct the commit currently mapped to the git object sha (40-hex),
or None if no Heddle state maps to it. Convenience for callers keyed by
the original git OID — e.g. the #566 conformance gate, which compares the
reconstruction of each original commit against its captured golden bytes.
Sourcepub fn reconstruct_and_write_commit_for_git_sha(
&self,
repo: &SleyRepository,
sha: &str,
) -> GitProjectionResult<Option<ObjectId>>
pub fn reconstruct_and_write_commit_for_git_sha( &self, repo: &SleyRepository, sha: &str, ) -> GitProjectionResult<Option<ObjectId>>
Reconstruct the commit mapped to git object sha and WRITE it into repo,
returning the written OID (or None if no Heddle state maps to sha).
Combines Self::reconstruct_commit_for_git_sha with the odb write so the
#567 export-from-state path is exercisable against an arbitrary repo —
notably a FRESH one that never received the verbatim imported bytes, which
is how the export gate proves the object is regenerated from state, not
copied from the mirror.
Source§impl<'a> GitProjection<'a>
impl<'a> GitProjection<'a>
Sourcepub fn build_commit_message(state: &State) -> String
pub fn build_commit_message(state: &State) -> String
Build a Git commit message from a Heddle state.
Phase B (post-2026-05) onward: this is just the state’s intent text,
verbatim. Heddle metadata (change_id, agent, confidence, status) is
carried out-of-band via refs/notes/heddle so that exported commit
SHAs match the SHAs of imported commits — a prerequisite for any
bidirectional sync where heddle and an upstream git host (e.g.
GitHub) need to agree on which commits already exist.
Build a commit message that includes the W2 footer (R6).
Footer layout (always emitted, last block of the message):
<body>
Heddle-State: <hex change-id>
Heddle-URL: <hosted_url>/state/<id> (omitted when no hosted URL)
Heddle-Annotations-Omitted: <count>The footer is the durable record — every reader on every host gets
it regardless of remote configuration. Richer per-scope metadata
rides on the opt-in git note (see super::git_notes).