pub struct GitTreeMemWriter { /* private fields */ }Expand description
Git-tree-backed implementation of MemWriter. Holds the
gitdir path and target ref name; opens the gix::Repository
per call (matches the [crate::vcs::GixVcs] pattern, since
gix::Repository is Send but not Sync — its object-database
cache uses interior mutability via RefCell).
Mutations buffer in memory until Self::commit.
Implementations§
Source§impl GitTreeMemWriter
impl GitTreeMemWriter
Sourcepub fn new(gitdir: PathBuf, ref_name: String) -> Self
pub fn new(gitdir: PathBuf, ref_name: String) -> Self
Build a writer against the repository at gitdir targeting
ref_name. The ref need not exist yet — the first commit
creates it. ref_name is the per-branch mutex key; pass the
fully-qualified form (e.g. refs/heads/main) so writers
targeting the same branch under one gitdir share the same key.
Trait Implementations§
Source§impl MemBackend for GitTreeMemWriter
impl MemBackend for GitTreeMemWriter
Source§fn storage_present(&self) -> Result<bool, BackendError>
fn storage_present(&self) -> Result<bool, BackendError>
The per-mem branch ref exists. list_entities folds a missing
branch into an empty list (a fresh mem has no commits yet), so
this is the only way boot can tell “never created” from “empty”
and say missing_ref instead of empty.
Source§fn entity_exists(&self, rel_path: &Path) -> Result<bool, BackendError>
fn entity_exists(&self, rel_path: &Path) -> Result<bool, BackendError>
Existence probe with read_entity’s exact source-selection
semantics (pending buffer first, snapshotted parent
mid-transaction, live tip between transactions) — but stopping
at the tree entry, never reading the blob.
Source§fn list_entities(&self) -> Result<Vec<PathBuf>, BackendError>
fn list_entities(&self) -> Result<Vec<PathBuf>, BackendError>
Source§fn read_entity(&self, rel_path: &Path) -> Result<Option<Vec<u8>>, BackendError>
fn read_entity(&self, rel_path: &Path) -> Result<Option<Vec<u8>>, BackendError>
rel_path. Ok(None) for a missing path
(idempotent reads); Err for IO or backend-specific failures.Source§fn write_entity(
&self,
rel_path: &Path,
content: &[u8],
) -> Result<(), BackendError>
fn write_entity( &self, rel_path: &Path, content: &[u8], ) -> Result<(), BackendError>
Source§fn delete_entity(&self, rel_path: &Path) -> Result<(), BackendError>
fn delete_entity(&self, rel_path: &Path) -> Result<(), BackendError>
rel_path. Idempotent: no-op when the path is already
absent. Pending until Self::commit.Source§fn move_entity(&self, from: &Path, to: &Path) -> Result<(), BackendError>
fn move_entity(&self, from: &Path, to: &Path) -> Result<(), BackendError>
Source§fn discard_pending(&self) -> Result<(), BackendError>
fn discard_pending(&self) -> Result<(), BackendError>
batch_update stages each item’s write into the
pending set, and when a later item fails validation it calls
this to drop the already-staged writes rather than commit a
half-applied batch. Idempotent — discarding an empty buffer
is a no-op. Read moreSource§fn commit(
&self,
message: &str,
ctx: &CommitContext<'_>,
) -> Result<CommitId, BackendError>
fn commit( &self, message: &str, ctx: &CommitContext<'_>, ) -> Result<CommitId, BackendError>
CommitId; backends without history
return a synthetic id (UNIX-nanos + counter, hex) so callers
always get a non-empty cursor.Source§fn commit_with_expected_parent(
&self,
message: &str,
ctx: &CommitContext<'_>,
expected_parent: Option<&str>,
) -> Result<CommitId, BackendError>
fn commit_with_expected_parent( &self, message: &str, ctx: &CommitContext<'_>, expected_parent: Option<&str>, ) -> Result<CommitId, BackendError>
expected_parent is Some, the backend MUST refuse the
commit (Err(BackendError::ParentMismatch { ... })) if its
current head no longer matches the supplied ref — a sibling
writer advanced the on-disk state between the snapshot the
caller pinned and now. When expected_parent is None, the
call is equivalent to Self::commit. Read moreSource§fn append_provenance(&self, _record: &Provenance) -> Result<(), BackendError>
fn append_provenance(&self, _record: &Provenance) -> Result<(), BackendError>
Provenance record to the backend’s mutation log.
Persistence form differs per backend — JSONL line, commit
trailer, etc. — but the in-memory shape is identical.Source§fn read_provenance(
&self,
cursor: Option<&str>,
) -> Result<Vec<Provenance>, BackendError>
fn read_provenance( &self, cursor: Option<&str>, ) -> Result<Vec<Provenance>, BackendError>
cursor (opaque,
backend-defined: a commit SHA for git-branch, an RFC-3339
timestamp for folder, ignored for archive). None cursor
means “from the beginning”.Source§fn current_head(&self) -> Result<Option<String>, BackendError>
fn current_head(&self) -> Result<Option<String>, BackendError>
Engine instance, an
out-of-band git pull, etc.) advancing the on-disk state past
what the engine last read. Backends without history (folder,
archive) inherit the default impl returning Ok(None); the
engine treats None as “no drift signal available” and skips
drift detection for that mount. The git-branch backend
overrides to return the per-mem branch tip’s commit SHA hex;
the filesystem backend overrides to return the changelog’s
last-line timestamp cursor (folder mems with no changelog yet
keep None). Archive and in-memory backends stay on the
default. Read moreSource§fn read_mem_config(&self) -> Result<Option<Vec<u8>>, BackendError>
fn read_mem_config(&self) -> Result<Option<Vec<u8>>, BackendError>
.memstead/config.json payload, if any. Read moreSource§fn read_anchors_sidecar(&self) -> Result<Option<Vec<u8>>, BackendError>
fn read_anchors_sidecar(&self) -> Result<Option<Vec<u8>>, BackendError>
crate::anchor::ANCHOR_SIDECAR_PATH) bytes, if any. Read moreSource§fn write_anchors_sidecar(&self, bytes: &[u8]) -> Result<(), BackendError>
fn write_anchors_sidecar(&self, bytes: &[u8]) -> Result<(), BackendError>
Source§fn delete_artifacts(&self) -> Result<(), BackendError>
fn delete_artifacts(&self) -> Result<(), BackendError>
memstead_mem_create (entity-seed commit on the per-mem
branch + Self::write_mem_config on __MEMSTEAD). Called by
memstead_mem_delete orchestration when delete_files=true and
the delete rule matched, to give the backend a chance to
prune ref-store state the engine alone has the git authority
to touch. Read moreSource§fn write_mem_config(&self, bytes: &[u8]) -> Result<(), BackendError>
fn write_mem_config(&self, bytes: &[u8]) -> Result<(), BackendError>
.memstead/config.json payload. Symmetric
counterpart to Self::read_mem_config. Read moreSource§fn write_mem_config_with_note(
&self,
bytes: &[u8],
note: Option<&str>,
) -> Result<(), BackendError>
fn write_mem_config_with_note( &self, bytes: &[u8], note: Option<&str>, ) -> Result<(), BackendError>
Self::write_mem_config but records note (an optional
agent/operator-supplied provenance reason) on the resulting
commit body. The default delegates to the note-less form, so
backends without a commit (folder) simply ignore the note; the
git-branch backend overrides this to thread note into the
__MEMSTEAD-ref commit. Lets set_mem_version carry a --note
like the other commit-producing mem-lifecycle operations.Source§fn record_pipeline_edit(
&self,
kind: &str,
edits: &[(String, Option<Vec<u8>>)],
note: Option<&str>,
verb: &str,
) -> Result<(), BackendError>
fn record_pipeline_edit( &self, kind: &str, edits: &[(String, Option<Vec<u8>>)], note: Option<&str>, verb: &str, ) -> Result<(), BackendError>
.memstead/ on the workspace root — it has no
commit of its own — so backends with a commit timeline mirror the
edit into their provenance record; the commit is the audit trail,
the disk file stays the read path. Read moreSource§fn read_archive_provenance(&self) -> Result<Option<Vec<u8>>, BackendError>
fn read_archive_provenance(&self) -> Result<Option<Vec<u8>>, BackendError>
.memstead/provenance.json) the archive carries, if any. Read moreSource§impl MemWriter for GitTreeMemWriter
impl MemWriter for GitTreeMemWriter
Source§fn write_entity(
&self,
rel_path: &Path,
content: &[u8],
) -> Result<(), MemWriterError>
fn write_entity( &self, rel_path: &Path, content: &[u8], ) -> Result<(), MemWriterError>
Source§fn delete_entity(&self, rel_path: &Path) -> Result<(), MemWriterError>
fn delete_entity(&self, rel_path: &Path) -> Result<(), MemWriterError>
rel_path (mem-relative). Idempotent: no-op when the
path is already absent. Pending until Self::commit.Source§fn move_entity(&self, from: &Path, to: &Path) -> Result<(), MemWriterError>
fn move_entity(&self, from: &Path, to: &Path) -> Result<(), MemWriterError>
Source§fn commit(
&self,
message: &str,
ctx: &CommitContext<'_>,
) -> Result<CommitId, MemWriterError>
fn commit( &self, message: &str, ctx: &CommitContext<'_>, ) -> Result<CommitId, MemWriterError>
ctx.
Returns the resulting CommitId (opaque; the git-tree adapter
formats it as a hex object id).Auto Trait Implementations§
impl !Freeze for GitTreeMemWriter
impl RefUnwindSafe for GitTreeMemWriter
impl Send for GitTreeMemWriter
impl Sync for GitTreeMemWriter
impl Unpin for GitTreeMemWriter
impl UnsafeUnpin for GitTreeMemWriter
impl UnwindSafe for GitTreeMemWriter
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
impl<T> Fruit for T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more