{"record":{"id":"f032ea0249f60b96","repo":"rtk-ai/rtk","slug":"hg-log-p-must-parse","errorCode":null,"errorMessage":"hg log -p must parse","messagePattern":"hg log -p must parse","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmds/git/diff_cmd.rs","lineNumber":6074,"sourceCode":"            \"[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.\n        let log = include_str!(\"../../../tests/fixtures/diff/hg_log_p_raw.txt\");\n        let out = condense_unified_diff_strict(log).expect(\"hg log -p must parse\");\n        assert!(out.contains(\"[file] bin.dat (binary)\"), \"got:\\n{out}\");\n        assert!(out.contains(\"[file] f.txt (+1 -1)\"), \"got:\\n{out}\");\n        assert!(out.contains(\"[file] new.txt (+1 -0)\"), \"got:\\n{out}\");\n        assert!(out.contains(\"[file] old.txt (+0 -1)\"), \"got:\\n{out}\");\n        assert!(!out.contains(\"summary\"), \"hg prologue leaked:\\n{out}\");\n        // A binary-only changeset whose message has a marked, non-prose-\n        // shaped line: hg's echo closes the region AND counts as reaching\n        // its body, so rule 8's shape check does not send it raw.\n        let bin = include_str!(\"../../../tests/fixtures/diff/hg_export_binary_only_raw.txt\");\n        let out = condense_unified_diff_strict(bin).expect(\"must parse\");\n        assert_eq!(out, \"[file] b.dat (binary)\");\n    }\n\n    #[test]\n    fn gnu_identical_and_differ_facts_are_entries() {\n        // Real `diff -rus` / `diff -rq`: `Files X and Y are identical` and\n        // `Files X and Y differ` share the `Binary files` shape.\n        let rus = include_str!(\"../../../tests/fixtures/diff/diff_rus_raw.txt\");","sourceCodeStart":6056,"sourceCodeEnd":6092,"githubUrl":"https://github.com/rtk-ai/rtk/blob/0924356b4caba4989607227b7c8824d3d8098719/src/cmds/git/diff_cmd.rs#L6056-L6092","documentation":"Test panic from `condense_unified_diff_strict(log).expect(\"hg log -p must parse\")` in src/cmds/git/diff_cmd.rs:6074. The test feeds tests/fixtures/diff/hg_log_p_raw.txt — `hg log -p` output with a `changeset:` prologue before every changeset and a two-`-r` echo — and asserts it condenses to [file] entries with no prologue leakage. A panic means the condenser rejected the whole log (returned Err) instead of parsing it, historically because the changeset prologue broke the region latch and sent output raw.","triggerScenarios":"`cargo test` runs after parser changes; the `changeset:` prologue-at-column-0 handling or the two-`-r` echo latch regresses.","commonSituations":"Rewriting the region latch to require a `diff` header immediately, without skipping interleaved hg changeset metadata lines.","solutions":["Run the failing test with --nocapture and inspect the Err or raw payload","Verify the prologue-skipping logic handles repeated `changeset:` blocks, not just the first","Re-check that the two-`-r` echo closes the region and validates the body","Add/keep fixture-based tests so both one-`-r` and two-`-r` echoes stay covered"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"let log = include_str!(\"../../../tests/fixtures/diff/hg_log_p_raw.txt\");\nassert!(log.contains(\"changeset:\"), \"fixture must contain hg prologue\");","typeGuard":"fn parsed_or_none(r: Result<String, ParseError>) -> Option<String> { r.ok() }","tryCatchPattern":"let out = condense_unified_diff_strict(log)\n    .unwrap_or_else(|e| panic!(\"hg log -p must parse: {e}\"));","preventionTips":["Keep tests for repeated `changeset:` prologues, not just the first block","Cover both single and double `-r` echo latches in fixtures","Run hg fixtures after any latch/state-machine change"],"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"}