gabriel / muse public
shallow.py python
92 lines 3.4 KB
Raw
sha256:2eaa5d95f9d9383498e76947410a26e5a3ba23d182f339910c424cf88fad412b fix: try fetch/presign before fetch/mpack to avoid Cloudfla… Sonnet 4.6 patch 5 days ago
1 """Shallow graft management for Muse repositories.
2
3 A *shallow* repository is one whose local history is intentionally incomplete.
4 The ``.muse/shallow`` file lists the boundary commits: commits whose own
5 snapshots and objects are expected to be present locally, but whose parents
6 are not. The BFS walk in ``run_verify`` stops at these grafts — it does not
7 descend into history beyond the recorded boundary.
8
9 File format::
10
11 # one sha256:-prefixed commit ID per line
12 sha256:abc123...
13 sha256:def456...
14
15 Lines starting with ``#`` and blank lines are ignored. IDs are stored
16 sorted to keep diffs deterministic.
17
18 This mirrors git's ``.git/shallow`` convention and enables the same workflows:
19
20 - **Shallow clones**: pull only the last N commits; mark the boundary.
21 - **Partial pull**: receive new work without fetching full history.
22 - **Unshallow**: ``remove_shallow`` on all grafts to restore full history.
23
24 Integration with ``run_verify``
25 -------------------------------
26 The BFS walk reads the shallow set once at startup. When it would enqueue
27 a parent commit whose ID is in the shallow set, it increments
28 ``shallow_commits`` and does not enqueue that parent's own parents —
29 stopping the walk at the declared boundary.
30
31 Integration with ``muse pull``
32 ------------------------------
33 When a pull advances the local history, the shallow boundary should be
34 updated:
35
36 - Remove the old tip from the shallow set (it is now interior history).
37 - Add the new graft point if the pull was depth-limited.
38 - If the pull was unbounded (``--unshallow``), remove all grafts.
39 """
40
41 import pathlib
42
43 from muse.core.paths import shallow_path as _shallow_path
44
45 shallow_path = _shallow_path
46
47 def read_shallow(root: pathlib.Path) -> frozenset[str]:
48 """Return the set of shallow graft commit IDs.
49
50 Returns an empty frozenset when no ``.muse/shallow`` file exists or when
51 the file is empty. Comment lines (``#``) and blank lines are silently
52 skipped.
53 """
54 p = _shallow_path(root)
55 if not p.exists():
56 return frozenset()
57 ids: set[str] = set()
58 for line in p.read_text(encoding="utf-8").splitlines():
59 stripped = line.strip()
60 if stripped and not stripped.startswith("#"):
61 ids.add(stripped)
62 return frozenset(ids)
63
64 def write_shallow(root: pathlib.Path, commit_ids: set[str]) -> None:
65 """Atomically write the shallow graft file.
66
67 Sorts IDs before writing so the file is deterministic and diffs cleanly.
68 Creates ``.muse/`` if it does not exist. Writing an empty set produces
69 an empty file (``is_shallow`` returns ``False`` in that case).
70 """
71 p = _shallow_path(root)
72 p.parent.mkdir(parents=True, exist_ok=True)
73 content = "\n".join(sorted(commit_ids)) + "\n" if commit_ids else ""
74 p.write_text(content, encoding="utf-8")
75
76 def add_shallow(root: pathlib.Path, commit_id: str) -> None:
77 """Add *commit_id* to the shallow graft set. Idempotent."""
78 current = set(read_shallow(root))
79 current.add(commit_id)
80 write_shallow(root, current)
81
82 def remove_shallow(root: pathlib.Path, commit_id: str) -> None:
83 """Remove *commit_id* from the shallow graft set. No-op if absent."""
84 current = set(read_shallow(root))
85 current.discard(commit_id)
86 write_shallow(root, current)
87
88 def is_shallow(root: pathlib.Path) -> bool:
89 """Return ``True`` when ``.muse/shallow`` exists and contains at least
90 one commit ID.
91 """
92 return bool(read_shallow(root))
File History 1 commit
sha256:2eaa5d95f9d9383498e76947410a26e5a3ba23d182f339910c424cf88fad412b fix: try fetch/presign before fetch/mpack to avoid Cloudfla… Sonnet 4.6 patch 5 days ago