mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-26 13:33:34 -04:00
fca3839049
- hash_dict (4,420 commit objects -> commit:NNNN / twin / orphan; 150,280 prefixes; 0 ambiguous; 0 collisions with 1,480 cited content hashes; scratch mailmap), scrub (12/12 self-test; HEAD sample 731 distinct tokens == git's own lookup), gate_scan (+ expected_offenders.txt fixture: the R39 negative control, PASS over 16.8 GB in 2 m 25 s; rom_blob_ids = content/signature hits U purge-path blobs not shared with any other path), run_filter (module API; --force only for the deleted tag), verify_rewrite (pairwise proof + no purge path survives + pruned set == derived purge-only set), build_commit_map (0 old hashes asserted; unchanged commits exempted), resolve_tokens, absent_scan (positive control on the current repo: FAIL 82,362), probe_github.sh (skips unchanged commits) - trial #1 found two defects the plan had not foreseen: the EMPTY blob in the strip list (--strip-blobs-with-ids then undid every "file emptied" change in history and pruned a restore commit) and the byte-identical Initial commit keeping its hash; both fixed with controls - trial #2: filter 269 s, exactly 1 pruned, verify 4,029 pairs / 0 failures, map 4,030 rows, absent_scan + gate PASS on the clone, 1,231 tokens resolved at a trial tip (residue 7: the pruned commit x3, orphans x4), aggressive repack 500 -> 80 MB - SETUP P33 C1 section + rows (R21); runbook §3/§5/§6/§10 measured; requirements-python.txt; CURRENT_PHASE -> NEXT = C2
77 lines
4.8 KiB
Python
77 lines
4.8 KiB
Python
#!/usr/bin/env python3
|
|
"""build_commit_map.py — the public ordinal → new-hash map, and the private old → new map (P33 C7).
|
|
|
|
tools/public_rewrite/build_commit_map.py [--new .run/public_rewrite/repo.git]
|
|
|
|
Writes docs/commit-map.tsv (PUBLIC): one row per commit of the OLD main in order — `ordinal new_hash author_date
|
|
committer_date subject` — with NO old hash anywhere (asserted: the scrub over the file's own bytes makes 0
|
|
replacements). The pruned purge-only commit keeps its row with `new_hash` = 40 zeros so the ordinals stay dense and
|
|
every `commit:NNNN` token in history has a row. Dates/subjects are read from the NEW commits (already scrubbed by the
|
|
rewrite); the pruned row's from the old commit, scrubbed here.
|
|
Writes .run/public_rewrite/old-to-new.tsv (PRIVATE, for probe_github.sh): `ordinal old_hash new_hash`.
|
|
"""
|
|
import argparse
|
|
import sys
|
|
|
|
sys.path.insert(0, str(__import__("pathlib").Path(__file__).resolve().parent))
|
|
import common as C # noqa: E402
|
|
import scrub # noqa: E402
|
|
|
|
|
|
def main(argv):
|
|
ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
|
|
ap.add_argument("--new", default=str(C.CLONE_DIR))
|
|
ap.add_argument("--old", default=str(C.REPO))
|
|
ap.add_argument("--out", default=str(C.COMMIT_MAP_PUBLIC), help="the public map path (a scratch path for a trial run)")
|
|
ap.add_argument("--private-out", default=str(C.OLD_TO_NEW_FILE))
|
|
a = ap.parse_args(argv)
|
|
out_pub, out_priv = __import__("pathlib").Path(a.out), __import__("pathlib").Path(a.private_out)
|
|
new_repo = __import__("pathlib").Path(a.new)
|
|
import verify_rewrite
|
|
cmap = verify_rewrite.commit_map(new_repo)
|
|
d = C.load_dict()
|
|
old_main = [h for h, e in sorted(d["commits"].items(), key=lambda kv: kv[1].get("ord", 0)) if e["kind"] == "main"]
|
|
if len(old_main) != d["main_count"]:
|
|
C.die(f"dictionary main count mismatch ({len(old_main)} vs {d['main_count']})")
|
|
s = scrub.Scrubber()
|
|
rows, priv = [], []
|
|
for h in old_main:
|
|
o = d["commits"][h]["ord"]
|
|
new = cmap.get(h)
|
|
if new is None:
|
|
C.die(f"old main commit ordinal {o} ({h[:9]}) is not in the commit-map — the clone did not hold the same main")
|
|
if new == C.ZEROS:
|
|
ad, cd, subj = C.git(["log", "-1", "--format=%aI%x00%cI%x00%s", h], a.old).rstrip("\n").split("\0")
|
|
subj = s.scrub_text(subj.encode()).decode("utf-8", "replace")
|
|
else:
|
|
ad, cd, subj = C.git(["log", "-1", "--format=%aI%x00%cI%x00%s", new], new_repo).rstrip("\n").split("\0")
|
|
rows.append(f"{o:04d}\t{new}\t{ad}\t{cd}\t{subj}")
|
|
priv.append(f"{o:04d}\t{h}\t{new}")
|
|
header = ("# docs/commit-map.tsv — the public history's commit map (P33 C7). Generated by tools/public_rewrite/build_commit_map.py; never edit.\n"
|
|
"# Before the public flip the history was rewritten (ROM-derived paths purged, personal addresses mapped, old commit hashes\n"
|
|
"# in every historical doc replaced by the inert token commit:NNNN). NNNN is the ordinal of the commit on main in the ORIGINAL\n"
|
|
"# order (1 = the first commit); this table maps it to the rewritten commit. A row of 40 zeros is the one commit that touched\n"
|
|
"# only purged paths and was pruned. Documents at the tip cite the new hashes directly (tools/public_rewrite/resolve_tokens.py).\n"
|
|
"ordinal\tnew_hash\tauthor_date\tcommitter_date\tsubject\n")
|
|
text = header + "\n".join(rows) + "\n"
|
|
# a commit the rewrite left byte-identical (old == new: e.g. the noreply-authored "Initial commit", which cites no
|
|
# hash and touches no purge path) legitimately keeps its hash — exempt those from the old-hash assertion
|
|
unchanged = {o for o, n in cmap.items() if o == n}
|
|
d2 = {"commits": {h: e for h, e in d["commits"].items() if h not in unchanged}, "ambiguous": d["ambiguous"],
|
|
"excluded": d["excluded"]}
|
|
s2 = scrub.Scrubber(d2)
|
|
out = s2.scrub_text(text.encode())
|
|
if s2.stats["replaced"] or s2.stats["emails"]:
|
|
C.die(f"the public map would carry {s2.stats['replaced']} old-hash tokens / {s2.stats['emails']} addresses — refusing")
|
|
(C.SCRATCH / "unchanged_commits.txt").write_text("\n".join(sorted(unchanged)) + ("\n" if unchanged else ""), encoding="utf-8")
|
|
out_pub.write_text(text, encoding="utf-8")
|
|
out_priv.write_text("ordinal\told_hash\tnew_hash\n" + "\n".join(priv) + "\n", encoding="utf-8")
|
|
zeros = sum(1 for r in rows if "\t" + C.ZEROS + "\t" in r)
|
|
print(f"build_commit_map: {len(rows)} rows -> {out_pub} ({zeros} pruned rows); private old-to-new -> {out_priv}; "
|
|
f"0 old-hash tokens in the public file (asserted; {len(unchanged)} commits unchanged by the rewrite keep their hash)")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main(sys.argv[1:]))
|