Skip to content

Commit fc121cc

Browse files
committed
docs: add phase A handoff resume for A8 completion
Snapshot of Phase A state at end of A6 (b5c44b0) with A8 in-progress inventory: completed work in unified/tree/patch/ diff/index, verified crosswise matrix, remaining A8 closure steps, and queued A9/A11/A13 scope. Carries general checklist and next-agent prompt.
1 parent 4529a5b commit fc121cc

1 file changed

Lines changed: 172 additions & 0 deletions

File tree

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
# Phase A Handoff: State, Remaining Work, and Instructions for the Next Agent
2+
3+
Last updated: end of the A6 commit (`b5c44b02ef`); A8 work in progress in the working tree.
4+
5+
## Repo ground rules (from AGENTS.md)
6+
7+
- Run **all** cargo commands from `crates/` (`cd crates`). The root `Cargo.toml`
8+
is a stale leftover; running cargo from the repo root is wrong.
9+
- C git is the spec; `t/` is the oracle; byte-identical stdout/stderr/exit
10+
codes are the acceptance test.
11+
- An **external watcher** (watch-and-commit / a formatting hook) rewrites
12+
files in this workspace (you will see "file has been modified since last
13+
read"). Re-read before editing; after writing, verify the bytes landed
14+
(plain `git diff`).
15+
**Escape gotcha:** this environment historically mangled `\n` escapes in
16+
Python heredocs. When editing Rust string/char literals, prefer `sed`/
17+
byte-level Python (e.g. `bytes([92,110])`) or write the whole file with a
18+
single `write` tool call, then confirm with `git diff` before building.
19+
- Each item commits separately with `<git_commits>` conventions.
20+
21+
## Completed and committed (all with crosswise suites in `xtask::suites()`, scoreboard updated)
22+
23+
| Item | Commit | Notes |
24+
|---|---|---|
25+
| A2 repo discovery / env threading | `6fe5d152e4` (+watcher commits) | RepoContext everywhere, `--git-dir` etc. |
26+
| A1 sha1dc | `97bf4a36e3` | SHAttered detection, hash-object parity |
27+
| A3 cat-file batch | `f190e10c49` | `%(atom)`, `--batch-all-objects`, `-z`, rev:path |
28+
| A4 abbreviation resolution | `1c53275cd8` | `git_revision::Resolver`, peels, ambiguity text |
29+
| A5 rev-parse | `c27d6c5f52` | ranges, symbolic, shape flags, sq, env vars |
30+
| A12 local timezone | `151b04a961` | TZif reader, DST-correct idents, calendar months |
31+
| A10 count-objects | `e3145f6846` | garbage semantics, -H, usage errors |
32+
| A7 pretty engine | `14e0ac4337` | git-pretty crate; log driven by it |
33+
| A6 rev-list/log options | `b5c44b02ef` | rev_info walker; topo/date order, filters, ranges, --objects, path limits |
34+
35+
`cargo test --workspace`: **55 test binaries, all green** (before the A8
36+
work-tree edits; re-verify after finishing A8).
37+
38+
## IN PROGRESS: A8 diff engine completion (uncommitted working tree)
39+
40+
Target file: `docs/plan/phase-a/08-diff-options.md`. Much is implemented and
41+
byte-identical vs system git on the /tmp fixture matrix, listed below.
42+
43+
### What is already done in the working tree (verify, don't redo)
44+
45+
- `git-diff/src/unified.rs`: `render_unified_ctx` with `-U<n>`, the
46+
`\ No newline at end of file` marker, section-context in `@@` headers
47+
(last kept line before the hunk, e.g. `@@ -2 +2 @@ a`), and zero-count
48+
hunk ranges (`@@ -3,0 +4 @@`). Unit tests present.
49+
- `git-diff/src/tree.rs`: `Change` gained `old_path`, `new_path`, `score`;
50+
`MAX_SCORE = 60000`.
51+
- `git-command/src/patch.rs`: rewrote the renderers — `render_stat`
52+
(exact C `show_stats`: 80-col width, scale_linear, Bin handling,
53+
number_width=3 for binaries), `render_shortstat`, `render_numstat`
54+
(binary rows as `-\t-\tpath`), `render_name_line`, `render_raw`
55+
(abbreviated 7-char oids, `dirty` new-side as `0000000`), `render_summary`,
56+
`render_change_patch_ctx` (rename blocks, binary footers, mode-change
57+
lines, `-U`). `BlobSource` bridges odb + synthetic blobs. `mode6`
58+
zero-pads modes to 6 digits (`40000`→`040000`) and renders absent modes
59+
as `000000`.
60+
- `git-command/src/diff.rs`: rewrote with option parsing (`--stat`,
61+
`--shortstat`, `--numstat`, `--name-only`, `--name-status`, `--raw`,
62+
`--summary`, `--patch-with-stat`, `-U<n>`, `-s`, `--cached/--staged`,
63+
`-M/--find-renames[=n]`, `--no-renames`, `--diff-filter=`,
64+
`--exit-code/--quiet`, `--no-index`), sources (worktree synthetic tree
65+
built from `git-index` + stat-match reuse of index oids; index tree from
66+
flat entries; HEAD/tree resolution via `resolve_arg`), delta blobs kept
67+
in an `extra` map, rename detection (exact pass + line-similarity pass),
68+
and path limiting.
69+
- `git-index`: added `Default` impl for `Index`.
70+
- Crosswise suite `crates/git-command/tests/phaseA08_crosswise.rs`
71+
(fixture with no-EOL modify, exact rename, binary, staged add/delete).
72+
**Verified byte-identical on the matrix below** (run before registering):
73+
`diff HEAD`, `--stat`, `--numstat`, `--shortstat`, `--name-only`,
74+
`--name-status`, `--raw`, `--summary`, `--cached`, `--no-renames`,
75+
`--find-renames=90`, `-U0`, `-U1`, `-U3`, `HEAD -- f.txt`, `HEAD -- bin.dat`,
76+
`--diff-filter=M`, `--diff-filter=R`, `--exit-code`, plain `diff`,
77+
`--patch-with-stat`. `diff HEAD -U0` hunk headers byte-identical.
78+
79+
### What must STILL be done to close A8 (in dependency order)
80+
81+
1. **Finish `diff-tree --exit-code`** (`crates/git-command/src/diff_tree.rs`):
82+
recognize `--exit-code`/`--quiet`; after emitting changes, return
83+
`CommandError::silent(1)` when changes exist and 0 otherwise (like
84+
`diff.rs::finish`). Also port `diff-tree` raw rendering to use the new
85+
`patch::render_raw` (abbreviated 7-char oids per system git) — confirm
86+
with `git diff-tree HEAD~1 HEAD` in a dirty repo. Do NOT break the
87+
existing `phase5_crosswise.rs` expectations (it compares raw lines
88+
with FULL 40-char oids on its fixture — check whether that suite expects
89+
full or abbreviated; if it expects full, keep `diff-tree` raw full and
90+
only add `--exit-code`).
91+
2. **Register the A8 suite** in `xtask/src/main.rs::suites()` as
92+
`phaseA08-crosswise` and re-run `cargo run -p xtask -- scoreboard`
93+
(from `crates/`). Run `cargo test --workspace` — ensure 55+ suites green.
94+
3. **Remove debug leftovers** in the working tree before committing:
95+
- `crates/git-command/examples/dbgdiff.rs` (and the dir if empty)
96+
- `crates/git-index/examples/dbg.rs` (and the dir if empty)
97+
- any `DIFF_DEBUG` eprintln blocks in `git-command/src/diff.rs`
98+
4. **Commit A8** (conventional message describing what it enables), update
99+
`docs/plan/phase-a/PROGRESS.md` (mark A8 DONE with implemented scope),
100+
add the deferred list (word-diff, --color, --patience/--histogram
101+
algorithms, --dirstat, whitespace family, --relative, -S/-G pickaxe,
102+
rename/copy heuristic is similarity-approximation not C's
103+
diffcore-rename algorithm, stat width hard-coded 80 like non-tty C).
104+
5. **Known A8 deviations to record in FOLLOWUPS**: exact rename scoring
105+
differs from diffcore-rename for edited renames; `--diff-filter`
106+
lowercase = exclude implemented; `status` field for `T` (mode change)
107+
classification.
108+
109+
## REMAINING PHASE A ITEMS (do next, same rigor)
110+
111+
### A9 — userdiff hunk headers (`docs/plan/phase-a/09-userdiff-hunk-headers.md`)
112+
113+
Hunk headers: the `@@ ... @@` suffix now uses the last context line (done in
114+
A8). Extend with the builtin userdiff drivers (C `userdiff.c`): known
115+
paths/extensions get function-name regexes (e.g. `*.c` uses
116+
`^[A-Za-z_].*[^:)]*$`) that select the nearest preceding matching line from
117+
the OLD side instead of "last context line". Gates: crosswise suite with a
118+
fixture of `.c`/`.py`/`.md` files; `t/t4018-*.sh` concepts (funcname
119+
patterns live in `userdiff.c`). Keep default (no driver) behavior
120+
byte-identical to today.
121+
122+
### A11 — `.gitignore` + attributes engine (`docs/plan/phase-a/11-gitignore-attributes.md`)
123+
124+
New crate (suggest `git-ignore` or put in `git-core`):
125+
- `.gitignore` parsing per C `dir.c` `parse_ignore_file` (patterns,
126+
unanchored vs anchored, `!` negation, trailing `/` dir-only, `**`).
127+
- `git-check-ignore`-style match (walk dirs bottom-up, LAST matching
128+
pattern wins, negation) and `git status --ignored` groundwork.
129+
- `.gitattributes` minimal subset: `-diff`, `binary`,
130+
`diff=<driver>`/`diff=<funcname>` piping into A9.
131+
- Gates: crosswise suites vs `git check-ignore` on crafted trees.
132+
133+
### A13 — pack delta compression on write (`docs/plan/phase-a/13-pack-delta-compression.md`)
134+
135+
`git pack-objects` currently writes non-deltified packs (recorded
136+
deviations). Implement delta candidate selection (window), `delta.c`
137+
delta encoding (`create_delta` semantics), OFS/REF delta entries, and
138+
`git verify-pack`/`git index-pack` compatibility (C git must verify our
139+
packs). Crosswise: `git pack-objects <obj-list>` from our binary vs C,
140+
then `git verify-pack -v` both. Big item; split commit by (a) delta
141+
encoder CRATE, (b) pack writer integration, (c) crosswise suite.
142+
143+
## General do-this-every-time checklist
144+
145+
1. Read the item's plan doc in `docs/plan/phase-a/` first; it names gates.
146+
2. Probe system git (`/usr/bin/git`) behavior before coding; write the
147+
crosswise test first when possible (style: `crates/git-command/tests/
148+
phaseA0X_crosswise.rs`).
149+
3. After each change: `cd crates && cargo build --workspace` (0 errors),
150+
`cargo test --workspace` (all green), the item's new crosswise test,
151+
`cargo run -p xtask -- scoreboard` (writes baseline; fails on regression).
152+
4. `git add -A` + commit per item; update `docs/plan/phase-a/PROGRESS.md`
153+
and `docs/plan/FOLLOWUPS.md` (`**DONE (AX)**` style entries already used).
154+
5. Never edit `crates/scoreboard.json` by hand; never run
155+
`watch-and-commit.sh`; do not commit from the repo root (use `crates/`).
156+
157+
## Suggested next-agent prompt (copy/paste)
158+
159+
"Work through the Phase A remaining items of the pure-Rust git port at
160+
/Users/ali/dev/rust/git.rs, A8-finish first then A9, A11, A13 in that
161+
order. Read docs/plan/phase-a/README + the per-item docs (08, 09, 11, 13),
162+
and docs/plan/phase-a/HANDOFF.md for exact state. A8: finish diff-tree
163+
--exit-code, register phaseA08-crosswise in xtask::suites(), delete the
164+
debug example files, run cargo test --workspace and the scoreboard from
165+
crates/, commit A8 and mark PROGRESS.md; then implement A9 (userdiff hunk
166+
headers over A8's hunk-context), A11 (.gitignore + attributes with
167+
check-ignore crosswise parity), A13 (delta encoding in pack-objects
168+
verified by C git) — each with its own crosswise suite registered in
169+
xtask, gates green (cargo test --workspace + scoreboard no-regression),
170+
committed separately, and PROGRESS.md/FOLLOWUPS.md updated. Follow the
171+
handoff's escape gotcha (prefer byte-level Python/sed for \n edits) and
172+
the per-commit checklist."

0 commit comments

Comments
 (0)