gitgrip 1.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- gitgrip-1.5.0.dist-info/METADATA +13 -0
- gitgrip-1.5.0.dist-info/RECORD +80 -0
- gitgrip-1.5.0.dist-info/WHEEL +5 -0
- gitgrip-1.5.0.dist-info/entry_points.txt +2 -0
- gitgrip-1.5.0.dist-info/top_level.txt +2 -0
- gr2/__init__.py +0 -0
- gr2/overlay/__init__.py +6 -0
- gr2/overlay/activate.py +196 -0
- gr2/overlay/agent_manifest.py +138 -0
- gr2/overlay/cli.py +181 -0
- gr2/overlay/cross_repo.py +124 -0
- gr2/overlay/drivers.py +113 -0
- gr2/overlay/introspection.py +155 -0
- gr2/overlay/language_drivers.py +115 -0
- gr2/overlay/objects.py +412 -0
- gr2/overlay/perf.py +251 -0
- gr2/overlay/refs.py +36 -0
- gr2/overlay/trust.py +150 -0
- gr2/overlay/types.py +69 -0
- gr2/overlay/units.py +313 -0
- gr2/overlay/workspace_spec.py +59 -0
- gr2/prototypes/__init__.py +0 -0
- gr2/prototypes/cache_materialization_probe.py +190 -0
- gr2/prototypes/concurrent_event_stress.py +199 -0
- gr2/prototypes/concurrent_lease_stress.py +240 -0
- gr2/prototypes/concurrent_workspace_cap_stress.py +231 -0
- gr2/prototypes/contribution_protocol.py +665 -0
- gr2/prototypes/cross_mode_lane_stress.py +986 -0
- gr2/prototypes/jsonl_store.py +158 -0
- gr2/prototypes/lane_workspace_prototype.py +2088 -0
- gr2/prototypes/layout_model_probe.py +139 -0
- gr2/prototypes/propagation_daemon.py +546 -0
- gr2/prototypes/propagation_state_machine.py +1478 -0
- gr2/prototypes/python_exec_playground.py +194 -0
- gr2/prototypes/python_hook_runtime_playground.py +240 -0
- gr2/prototypes/python_migration_playground.py +144 -0
- gr2/prototypes/python_review_checkout_playground.py +242 -0
- gr2/prototypes/python_spec_apply_playground.py +282 -0
- gr2/prototypes/real_git_lane_materialization.py +248 -0
- gr2/prototypes/real_git_playground.py +334 -0
- gr2/prototypes/recall_lane_history.py +274 -0
- gr2/prototypes/repo_maintenance_prototype.py +659 -0
- gr2/prototypes/repo_transport_probe.py +147 -0
- gr2/python_cli/__init__.py +2 -0
- gr2/python_cli/__main__.py +6 -0
- gr2/python_cli/add.py +51 -0
- gr2/python_cli/app.py +2516 -0
- gr2/python_cli/branch.py +67 -0
- gr2/python_cli/channel_bridge.py +131 -0
- gr2/python_cli/clone_exec.py +1019 -0
- gr2/python_cli/commit.py +199 -0
- gr2/python_cli/config.py +291 -0
- gr2/python_cli/env_exec.py +419 -0
- gr2/python_cli/events.py +529 -0
- gr2/python_cli/execops.py +372 -0
- gr2/python_cli/failures.py +98 -0
- gr2/python_cli/file_exec.py +256 -0
- gr2/python_cli/gitops.py +226 -0
- gr2/python_cli/grip.py +1337 -0
- gr2/python_cli/grip_cli.py +493 -0
- gr2/python_cli/hooks.py +450 -0
- gr2/python_cli/launch_exec.py +786 -0
- gr2/python_cli/merge_verification.py +274 -0
- gr2/python_cli/migration.py +985 -0
- gr2/python_cli/open_gr_review.py +699 -0
- gr2/python_cli/platform.py +441 -0
- gr2/python_cli/pr.py +487 -0
- gr2/python_cli/project_review.py +314 -0
- gr2/python_cli/prune.py +365 -0
- gr2/python_cli/push.py +172 -0
- gr2/python_cli/review.py +462 -0
- gr2/python_cli/review_ephemeral.py +143 -0
- gr2/python_cli/review_run.py +621 -0
- gr2/python_cli/spec_apply.py +1285 -0
- gr2/python_cli/staging_cleanup.py +205 -0
- gr2/python_cli/syncops.py +920 -0
- gr2/python_cli/target.py +100 -0
- gr2/python_cli/workspace_snapshot.py +105 -0
- gr2/schemas/gr2-materialization-plan-v1.schema.json +191 -0
- gr2_overlay/__init__.py +37 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"""Review-ephemeral lane materialization: blobless + sparse, from the persistent
|
|
2
|
+
per-host review mirror, NEVER through ``materialize_lane_clone``.
|
|
3
|
+
|
|
4
|
+
A review lane is read-only and ephemeral -- nobody commits into it and it is
|
|
5
|
+
``rm -rf``'d when the review closes. Sections 8.1 (complete history) and 8.2 (no
|
|
6
|
+
external object sharing) that ``materialize_lane_clone`` enforces exist to protect
|
|
7
|
+
a MUTABLE work lane's independent state; a review lane does not need them, and a
|
|
8
|
+
blobless clone keeps the whole commit+tree graph, so patch-id, diff, and
|
|
9
|
+
merge-base all work (measured: identical base..head patch-id vs a full clone).
|
|
10
|
+
Blobless is the only ``.git`` reducer (shallow is out -- a base..head review must
|
|
11
|
+
reach an arbitrary base); sparse is the working-tree reducer, using EXACTLY
|
|
12
|
+
``review-clone.sh``'s two rules so the two tools cannot disagree:
|
|
13
|
+
|
|
14
|
+
1. the profile is ignore-syntax and comes from, in order: the in-repo
|
|
15
|
+
``.review-exclude`` at the reviewed ref (read from the bare mirror), else the
|
|
16
|
+
gripspace fallback ``<profile_dir>/<repo>.exclude`` (``SYNAPT_REVIEW_PROFILE_DIR``,
|
|
17
|
+
the same env ``review-clone.sh`` honors), else none (whole tree, still blobless);
|
|
18
|
+
2. every path ``base..head`` touches is appended AFTER the profile as an explicit
|
|
19
|
+
``/path`` include, so a review can never be missing a file it is about (later
|
|
20
|
+
patterns win in ``--no-cone`` sparse-checkout).
|
|
21
|
+
|
|
22
|
+
This lane KIND never enters the work-lane clone seam, so it cannot weaken 8.1/8.2.
|
|
23
|
+
"""
|
|
24
|
+
from __future__ import annotations
|
|
25
|
+
|
|
26
|
+
import os
|
|
27
|
+
import subprocess
|
|
28
|
+
from pathlib import Path
|
|
29
|
+
|
|
30
|
+
REVIEW_EPHEMERAL_KIND = "review-ephemeral"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class ReviewEphemeralError(Exception):
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _git(cwd: Path, *args: str) -> subprocess.CompletedProcess[str]:
|
|
38
|
+
return subprocess.run(["git", *args], cwd=cwd, text=True, capture_output=True, check=False)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def review_profile_dir() -> Path | None:
|
|
42
|
+
"""The gripspace-level sparse-profile fallback dir, honoring the same
|
|
43
|
+
``SYNAPT_REVIEW_PROFILE_DIR`` override review-clone.sh honors. gr2 is
|
|
44
|
+
repo-layout-agnostic, so with the env unset there is NO gripspace fallback and
|
|
45
|
+
only an in-repo ``.review-exclude`` applies (which is versioned with the repo
|
|
46
|
+
and always found)."""
|
|
47
|
+
value = os.environ.get("SYNAPT_REVIEW_PROFILE_DIR")
|
|
48
|
+
return Path(value) if value else None
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def resolve_sparse_profile(mirror: Path, ref: str, repo_name: str) -> tuple[str, str]:
|
|
52
|
+
"""Resolve the sparse profile for ``ref`` by review-clone.sh's precedence.
|
|
53
|
+
|
|
54
|
+
Returns ``(profile_content, source_label)``; empty content means no profile
|
|
55
|
+
(whole tree, still blobless)."""
|
|
56
|
+
shown = _git(mirror, "show", f"{ref}:.review-exclude")
|
|
57
|
+
if shown.returncode == 0 and shown.stdout.strip():
|
|
58
|
+
return shown.stdout, f"in-repo .review-exclude @ {ref}"
|
|
59
|
+
pdir = review_profile_dir()
|
|
60
|
+
if pdir is not None:
|
|
61
|
+
fallback = pdir / f"{repo_name}.exclude"
|
|
62
|
+
if fallback.is_file():
|
|
63
|
+
return fallback.read_text(), f"fallback {fallback}"
|
|
64
|
+
return "", "none"
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _pattern_lines(profile_content: str, touched_paths: list[str]) -> list[str]:
|
|
68
|
+
"""Profile lines (comments/blanks stripped) first, then each touched path as an
|
|
69
|
+
explicit ``/path`` include -- review-clone.sh's exact ordering."""
|
|
70
|
+
lines: list[str] = []
|
|
71
|
+
for raw in profile_content.splitlines():
|
|
72
|
+
line = raw.strip()
|
|
73
|
+
if not line or line.startswith("#"):
|
|
74
|
+
continue
|
|
75
|
+
lines.append(line)
|
|
76
|
+
for p in touched_paths:
|
|
77
|
+
p = p.strip()
|
|
78
|
+
if p:
|
|
79
|
+
lines.append("/" + p.lstrip("/"))
|
|
80
|
+
return lines
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def touched_paths(mirror: Path, base: str, head: str) -> list[str]:
|
|
84
|
+
"""The paths ``base..head`` touches (the range-union source). Read from the
|
|
85
|
+
bare mirror, which holds the complete commit+tree graph."""
|
|
86
|
+
proc = _git(mirror, "diff", "--name-only", base, head)
|
|
87
|
+
if proc.returncode != 0:
|
|
88
|
+
raise ReviewEphemeralError(
|
|
89
|
+
f"cannot compute base..head touched paths ({base[:8]}..{head[:8]}) in {mirror}: "
|
|
90
|
+
f"{proc.stderr.strip()}"
|
|
91
|
+
)
|
|
92
|
+
return [p for p in proc.stdout.splitlines() if p.strip()]
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def materialize_review_ephemeral(
|
|
96
|
+
*,
|
|
97
|
+
mirror: Path,
|
|
98
|
+
dest: Path,
|
|
99
|
+
head: str,
|
|
100
|
+
base: str,
|
|
101
|
+
repo_name: str,
|
|
102
|
+
echo=lambda _l: None,
|
|
103
|
+
) -> dict[str, str]:
|
|
104
|
+
"""Materialize a review lane as a BLOBLESS + SPARSE clone from the mirror.
|
|
105
|
+
|
|
106
|
+
Returns provenance: the profile source, the pattern count, and the resulting
|
|
107
|
+
HEAD. Refuses if the checked-out HEAD is not the requested head."""
|
|
108
|
+
mirror = Path(mirror)
|
|
109
|
+
dest = Path(dest)
|
|
110
|
+
if dest.exists():
|
|
111
|
+
raise ReviewEphemeralError(f"review-ephemeral destination already exists: {dest}")
|
|
112
|
+
|
|
113
|
+
profile_content, profile_source = resolve_sparse_profile(mirror, head, repo_name)
|
|
114
|
+
patterns = _pattern_lines(profile_content, touched_paths(mirror, base, head))
|
|
115
|
+
|
|
116
|
+
dest.parent.mkdir(parents=True, exist_ok=True)
|
|
117
|
+
cloned = subprocess.run(
|
|
118
|
+
["git", "clone", "--quiet", "--no-checkout", "--filter=blob:none",
|
|
119
|
+
f"file://{mirror}", str(dest)],
|
|
120
|
+
text=True, capture_output=True, check=False,
|
|
121
|
+
)
|
|
122
|
+
if cloned.returncode != 0:
|
|
123
|
+
raise ReviewEphemeralError(f"blobless clone from {mirror} failed: {cloned.stderr.strip()}")
|
|
124
|
+
|
|
125
|
+
# Sparse only when there is a profile AND patterns; a bare range-union with no
|
|
126
|
+
# profile would narrow to just the changed files, hiding their context, so a
|
|
127
|
+
# profile-less repo stays whole-tree (blobless), matching review-clone.sh.
|
|
128
|
+
if profile_content.strip() and patterns:
|
|
129
|
+
applied = subprocess.run(
|
|
130
|
+
["git", "-C", str(dest), "sparse-checkout", "set", "--no-cone", "--stdin"],
|
|
131
|
+
input="\n".join(patterns) + "\n", text=True, capture_output=True, check=False,
|
|
132
|
+
)
|
|
133
|
+
if applied.returncode != 0:
|
|
134
|
+
raise ReviewEphemeralError(f"sparse-checkout set failed in {dest}: {applied.stderr.strip()}")
|
|
135
|
+
|
|
136
|
+
checked = _git(dest, "checkout", "--quiet", head)
|
|
137
|
+
if checked.returncode != 0:
|
|
138
|
+
raise ReviewEphemeralError(f"cannot check out review head {head} in {dest}: {checked.stderr.strip()}")
|
|
139
|
+
got = _git(dest, "rev-parse", "HEAD").stdout.strip()
|
|
140
|
+
if got != head:
|
|
141
|
+
raise ReviewEphemeralError(f"review-ephemeral lane is at {got}, not the requested head {head}")
|
|
142
|
+
|
|
143
|
+
return {"profile_source": profile_source, "patterns": str(len(patterns)), "head": got}
|