Skip to main content

GitProjection

Struct GitProjection 

Source
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>

Source

pub fn new(heddle_repo: &'a HeddleRepository) -> Self

Create a Git Projection helper for a Heddle repository.

Source

pub fn init_mirror(&mut self) -> GitProjectionResult<()>

Initialize the Bridge Mirror in the .heddle/git directory.

Source

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.

Source

pub fn mirror_path(&self) -> PathBuf

Get the path to the legacy Bridge Mirror directory.

Source

pub fn is_initialized(&self) -> bool

Check if a legacy Bridge Mirror is initialized.

Source

pub fn open_git_repo(&self) -> GitProjectionResult<SleyRepository>

Open the Git repository (mirror or regular).

Source

pub fn sort_states_topologically( &self, states: &[StateId], ) -> GitProjectionResult<Vec<StateId>>

Sort states topologically (parents before children).

Source

pub fn export(&mut self) -> GitProjectionResult<ExportStats>

Export all Heddle states to Git commits.

Source

pub fn set_commit_message_override( &mut self, state_id: StateId, message: String, )

Source

pub fn set_commit_parent_override( &mut self, state_id: StateId, parents: Vec<ObjectId>, )

Source

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.

Source

pub fn with_mapping_rollback<T>( &mut self, operation: impl FnOnce(&mut Self) -> GitProjectionResult<T>, ) -> GitProjectionResult<T>

Source

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).

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn pull(&mut self, remote_name: &str) -> GitProjectionResult<GitPullOutcome>

Pull from a Git remote.

Source

pub fn seed_git_checkpoint_mappings_from_checkout( &mut self, mirror_repo: &SleyRepository, ) -> GitProjectionResult<()>

Source

pub fn stage_ingest_source_in_mirror( &mut self, source: &Path, refs: &[String], ) -> GitProjectionResult<()>

Source

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.

Source

pub fn write_through_current_checkout_with_message( &mut self, state_id: StateId, message: String, ) -> GitProjectionResult<WriteThroughOutcome>

Source

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.

Source

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.

Source

pub fn write_current_checkout_from_existing_mirror( &mut self, ) -> GitProjectionResult<WriteThroughOutcome>

Source§

impl<'a> GitProjection<'a>

Source

pub fn mapping_path(&self) -> PathBuf

Source

pub fn mapping_tmp_path(&self) -> PathBuf

Source

pub fn write_mapping_tmp_to_disk(&self) -> GitProjectionResult<PathBuf>

Source

pub fn commit_mapping_tmp_to_disk(&self) -> GitProjectionResult<()>

Source

pub fn save_mapping_to_disk(&self) -> GitProjectionResult<()>

Source

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.

Source

pub fn seed_ingest_identity_mappings_from_repo( &mut self, repo: &SleyRepository, ) -> GitProjectionResult<()>

Source

pub fn prune_unreachable_mapping_entries( &mut self, ) -> GitProjectionResult<usize>

Source

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<'_>

Source

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.

Source

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.

Source

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.

Source

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.

Source

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>

Source

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).

Auto Trait Implementations§

§

impl<'a> !RefUnwindSafe for GitProjection<'a>

§

impl<'a> !UnwindSafe for GitProjection<'a>

§

impl<'a> Freeze for GitProjection<'a>

§

impl<'a> Send for GitProjection<'a>

§

impl<'a> Sync for GitProjection<'a>

§

impl<'a> Unpin for GitProjection<'a>

§

impl<'a> UnsafeUnpin for GitProjection<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more