generated from coulomb/repo-seed
feat(adapters): GitShardAdapter history adopt + cross-substrate integration (WP-0012 T3)
Adopt git-native history (TSD §A.5): a VERSION-gated history(key) surfaces the commit list for a path (newest-first sha + subject) — declared by every git-IS-store shard, read-only or not. Integration proves the union/overlay/edit machinery works unchanged across folder + git substrates: resolve/chorus span both, edit through a git shard fast-forwards as a commit, apply-under-drift refuses on an external commit (sha drift) without clobbering, and a read-only git target keeps the overlay as a draft. SCOPE updated; WP-0012 done. 196 tests green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -16,6 +16,7 @@ from __future__ import annotations
|
||||
import os
|
||||
import subprocess
|
||||
from collections.abc import Iterable
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
from shard_wiki.adapters.contract import ShardAdapter
|
||||
@@ -40,7 +41,15 @@ from shard_wiki.model import (
|
||||
)
|
||||
from shard_wiki.provenance import Liveness, ProvenanceEnvelope, Staleness
|
||||
|
||||
__all__ = ["GitShardAdapter"]
|
||||
__all__ = ["GitShardAdapter", "PageRevision"]
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class PageRevision:
|
||||
"""One adopted git-native revision of a page: the commit sha and its subject line."""
|
||||
|
||||
sha: str
|
||||
message: str
|
||||
|
||||
_GIT_IDENTITY = {
|
||||
"GIT_AUTHOR_NAME": "shard-wiki",
|
||||
@@ -66,11 +75,12 @@ class GitShardAdapter(ShardAdapter):
|
||||
return self._shard_id
|
||||
|
||||
def profile(self) -> CapabilityProfile:
|
||||
# Write is a commit; VERSION is git-native history (adopt, §A.5). Read-only drops both.
|
||||
verbs = {Verb.READ}
|
||||
# VERSION is always available — a git-IS-store has git-native history to adopt (§A.5),
|
||||
# read-only or not. WRITE (= commit, PER_PAGE) is added only in writable mode.
|
||||
verbs = {Verb.READ, Verb.VERSION}
|
||||
granularity = WriteGranularity.NONE
|
||||
if self._writable:
|
||||
verbs |= {Verb.WRITE, Verb.VERSION}
|
||||
verbs |= {Verb.WRITE}
|
||||
granularity = WriteGranularity.PER_PAGE
|
||||
return CapabilityProfile(
|
||||
substrate=Substrate.GIT,
|
||||
@@ -133,6 +143,23 @@ class GitShardAdapter(ShardAdapter):
|
||||
sha = self._git("log", "-1", "--format=%H", "--", rel).decode().strip()
|
||||
return sha or None
|
||||
|
||||
def history(self, key: str) -> tuple[PageRevision, ...]:
|
||||
"""Adopt git-native history (§A.5): the commit list for ``key``'s path, newest-first.
|
||||
|
||||
VERSION-gated; raises ``KeyError`` for an unknown page. Each revision is a commit sha +
|
||||
subject — the native log surfaced through the contract, not re-implemented.
|
||||
"""
|
||||
if not self.profile().supports(Verb.VERSION):
|
||||
raise NotSupported(f"{type(self).__name__} does not support version")
|
||||
if not self._path_for(key).is_file():
|
||||
raise KeyError(key)
|
||||
out = self._git("log", "--format=%H%x00%s", "--", f"{key}.md").decode()
|
||||
revisions = []
|
||||
for line in out.splitlines():
|
||||
sha, _, message = line.partition("\x00")
|
||||
revisions.append(PageRevision(sha=sha, message=message))
|
||||
return tuple(revisions)
|
||||
|
||||
# -- git plumbing --------------------------------------------------------
|
||||
|
||||
def _path_for(self, key: str) -> Path:
|
||||
|
||||
Reference in New Issue
Block a user