rtk-ai/rtk · error
hg diff must parse
Error message
hg diff must parse
What it means
Test panic from `condense_unified_diff_strict(fixture).expect("hg diff must parse")` in src/cmds/git/diff_cmd.rs:6054. condense_unified_diff_strict returns Result and the test asserts the real-world `hg diff` fixture (tests/fixtures/diff/hg_diff_raw.txt) parses into condensed [file] entries. A panic means the Mercurial diff condenser failed to latch on the fixture and returned an error (or a raw passthrough signal) instead of structured output — a regression in the diff parsing state machine.
Solutions
- Run `cargo test hg_diff_echo_carries_one_revision -- --nocapture` to see the parser error/raw output
- Compare the fixture against the header-detection regexes/state transitions that changed in the recent commit
- Restore latch behavior for `diff -r <rev> <path>` echoes and re-run the full diff test module
Example fix
// before (header matcher only accepts git-style two-path headers)
if line.starts_with("diff --git ") { ... }
// after (also accept hg echo with optional single -r)
if line.starts_with("diff --git ") || line.starts_with("diff -r ") || line.starts_with("diff ") { ... } Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check in tests/CI before asserting
let fixture = include_str!("../../../tests/fixtures/diff/hg_diff_raw.txt");
assert!(fixture.contains("diff -r "), "fixture must contain hg echo header"); Type guard
fn parsed_or_none(r: Result<String, ParseError>) -> Option<String> { r.ok() } Try / catch
let out = match condense_unified_diff_strict(fixture) {
Ok(o) => o,
Err(e) => panic!("hg diff must parse: {e}\nfixture head: {:?}", &fixture[..200]),
}; Prevention
- Keep fixture-based tests for both one-`-r` and two-`-r` hg echoes
- Run the full diff_cmd test module on any parser refactor
- Never tighten header detection without re-running hg fixtures
- Treat Err from condense_unified_diff_strict as a parser regression, not data noise
When it happens
Trigger: Running `cargo test` after changes to condense_unified_diff_strict or its hg handling; the fixture's `diff -r <rev>` echo, a/ b/ prefixes, quoted/tabbed filenames, or binary fact are no longer recognized.
Common situations: Refactoring the unified-diff parser, renaming file-header detection, or tightening the revision-echo latch so hg's single `-r` echo no longer closes/validates the diff region.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- hg log -p must parse
- must parse
- hg export must parse
- intact series must parse
- invalid ctest result prefix regex
AI-assisted analysis of rtk-ai/rtk@0924356b4c (2026-09-19).
Data as JSON: /api/errors/246fdfa52436ae8a.
Report an issue: GitHub.
Appendix: source
Thrown at src/cmds/git/diff_cmd.rs:6054
assert!(out.contains("[file] say \"hi\".txt (+5 -0)"), "got:\n{out}");
assert!(out.contains("[file] tab\there.txt (+5 -0)"), "got:\n{out}");
// A name holding a newline keeps git's own quoted spelling, with
// the prefix stripped inside the quotes: one `[file]` line per
// file, lossless, and spelled as `diff --cc` spelled it.
assert!(
out.contains("[file] \"new\\nline.txt\" (+5 -0)"),
"got:\n{out}"
);
assert_eq!(out.matches("[file] ").count(), 11, "got:\n{out}");
}
#[test]
fn hg_diff_echo_carries_one_revision() {
// Real `hg diff` (not export): `diff -r <rev> <path>` with a single
// `-r`, names with `a/`/`b/` prefixes, a tab and a `"` in names,
// and hg's binary fact.
let fixture = include_str!("../../../tests/fixtures/diff/hg_diff_raw.txt");
let out = condense_unified_diff_strict(fixture).expect("hg diff must parse");
for label in [
"[file] a and b.txt (+1 -1)",
"[file] b/blob.bin (binary)",
"[file] b/inb.txt (+1 -1)",
"[file] back\\slash.txt (+1 -1)",
"[file] café.txt (+1 -1)",
"[file] colon: x.txt (+1 -1)",
"[file] it's.txt (+1 -1)",
"[file] say \"hi\".txt (+1 -1)",
"[file] say \"hi\".txt.bin (binary)",
"[file] tab\there.txt (+1 -1)",
"[file] tab\there.txt.bin (binary)",
"[file] trail .txt (+1 -1)",
] {
assert!(out.contains(label), "missing {label:?}:\n{out}");
}
// `hg log -p`: a `changeset:` prologue at column 0 before every
// changeset, then the two-`-r` echo; used to go raw on the latch.View on GitHub (pinned to 0924356b4c)