{"record":{"id":"246fdfa52436ae8a","repo":"rtk-ai/rtk","slug":"hg-diff-must-parse","errorCode":null,"errorMessage":"hg diff must parse","messagePattern":"hg diff must parse","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmds/git/diff_cmd.rs","lineNumber":6054,"sourceCode":"        assert!(out.contains(\"[file] say \\\"hi\\\".txt (+5 -0)\"), \"got:\\n{out}\");\n        assert!(out.contains(\"[file] tab\\there.txt (+5 -0)\"), \"got:\\n{out}\");\n        // A name holding a newline keeps git's own quoted spelling, with\n        // the prefix stripped inside the quotes: one `[file]` line per\n        // file, lossless, and spelled as `diff --cc` spelled it.\n        assert!(\n            out.contains(\"[file] \\\"new\\\\nline.txt\\\" (+5 -0)\"),\n            \"got:\\n{out}\"\n        );\n        assert_eq!(out.matches(\"[file] \").count(), 11, \"got:\\n{out}\");\n    }\n\n    #[test]\n    fn hg_diff_echo_carries_one_revision() {\n        // Real `hg diff` (not export): `diff -r <rev> <path>` with a single\n        // `-r`, names with `a/`/`b/` prefixes, a tab and a `\"` in names,\n        // and hg's binary fact.\n        let fixture = include_str!(\"../../../tests/fixtures/diff/hg_diff_raw.txt\");\n        let out = condense_unified_diff_strict(fixture).expect(\"hg diff must parse\");\n        for label in [\n            \"[file] a and b.txt (+1 -1)\",\n            \"[file] b/blob.bin (binary)\",\n            \"[file] b/inb.txt (+1 -1)\",\n            \"[file] back\\\\slash.txt (+1 -1)\",\n            \"[file] café.txt (+1 -1)\",\n            \"[file] colon: x.txt (+1 -1)\",\n            \"[file] it's.txt (+1 -1)\",\n            \"[file] say \\\"hi\\\".txt (+1 -1)\",\n            \"[file] say \\\"hi\\\".txt.bin (binary)\",\n            \"[file] tab\\there.txt (+1 -1)\",\n            \"[file] tab\\there.txt.bin (binary)\",\n            \"[file] trail .txt (+1 -1)\",\n        ] {\n            assert!(out.contains(label), \"missing {label:?}:\\n{out}\");\n        }\n        // `hg log -p`: a `changeset:` prologue at column 0 before every\n        // changeset, then the two-`-r` echo; used to go raw on the latch.","sourceCodeStart":6036,"sourceCodeEnd":6072,"githubUrl":"https://github.com/rtk-ai/rtk/blob/0924356b4caba4989607227b7c8824d3d8098719/src/cmds/git/diff_cmd.rs#L6036-L6072","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before (header matcher only accepts git-style two-path headers)\nif line.starts_with(\"diff --git \") { ... }\n// after (also accept hg echo with optional single -r)\nif line.starts_with(\"diff --git \") || line.starts_with(\"diff -r \") || line.starts_with(\"diff \") { ... }","handlingStrategy":"try-catch","validationCode":"// pre-check in tests/CI before asserting\nlet fixture = include_str!(\"../../../tests/fixtures/diff/hg_diff_raw.txt\");\nassert!(fixture.contains(\"diff -r \"), \"fixture must contain hg echo header\");","typeGuard":"fn parsed_or_none(r: Result<String, ParseError>) -> Option<String> { r.ok() }","tryCatchPattern":"let out = match condense_unified_diff_strict(fixture) {\n    Ok(o) => o,\n    Err(e) => panic!(\"hg diff must parse: {e}\\nfixture head: {:?}\", &fixture[..200]),\n};","preventionTips":["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"],"tags":["rust","tests","hg","diff-parsing","panic"],"backgroundTag":"internal-invariant-violation","analyzedSha":"0924356b4caba4989607227b7c8824d3d8098719","analyzedAt":"2026-09-19T19:25:29.612Z","contentChangedAt":"2026-09-19T19:25:29.612Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}