Skip to content

Patch() parser has no fixture for a hunkless rename or a mode-only change, so the design's "headers and no hunks" behaviour is unasserted #186

Description

@matt-edmondson

What's missing

The patch-verbs design commits to two parser behaviours that no test pins down:

Plan:

**Renames and mode changes.** Both produce a file entry with headers and no hunks. Nothing special is
needed beyond not assuming every file has them.
**Untracked files.** They never appear in a patch, because `git diff` does not show them. Staging one
is `Add`, and a caller building a staging view has to know that its file list comes from `Status` and
its hunks come from `Patch`, which are different sources that disagree about untracked content.
## Testing
Parser tests run against fixtures captured from a real git, following this repository's existing
practice of capturing output once and treating it as fixed rather than re-deriving it. Fixtures
cover: a modification with two hunks, a file with no trailing newline, a rename with no hunks, a
binary file, a combined conflict hunk, and content with CRLF line endings.

Renames and mode changes. Both produce a file entry with headers and no hunks. Nothing special is needed beyond not assuming every file has them.

Fixtures cover: a modification with two hunks, a file with no trailing newline, a rename with no hunks, a binary file, a combined conflict hunk, and content with CRLF line endings.

What exists today

  • GitIntegration.Test/Fixtures/ has patch-rename-modified.txt (a rename with hunks) and patch-quoted-rename.txt, but no pure (100% similarity) rename fixture and no old mode / new mode fixture.
  • GitPatchRoundTripTests.ReportsAStagedRenameAsDeleteAndAddUnlessRequestedAsync checks the kind and OriginalPath of a pure rename, but never asserts Hunks is empty, nor what Header keeps.
  • GitIntegration/Parsing/GitPatchParser.cs recognises rename from/rename to, new file mode and deleted file mode, but has no explicit handling or test for old mode / new mode header lines (a chmod +x with no content change).

Why it matters

A mode-only change and a pure rename are the two ordinary cases where a file entry has no @@ lines. If a later parser change starts assuming each file has a hunk (or swallows the next file's diff --git line as header), a staging UI built on Patch() would lose or mis-attribute the file, and nothing in the suite would fail.

Acceptance criteria

  • Fixtures captured from a real git: patch-rename-pure.txt (git mv with no edit, -M) and patch-mode-change.txt (chmod +x only), each followed by at least one further ordinary file in the same output.
  • Pure rename parses as Renamed, OriginalPath set, Hunks empty, Header retains the similarity index / rename from / rename to lines.
  • Mode-only change parses as a single Modified entry, Hunks empty, old mode / new mode kept in Header.
  • Neither entry is flagged IsBinary or conflicted, and the following file still parses with its hunks.

Dependencies

None. Related to #126 (rename headers in PatchFor), but not blocked by it.

Activity

  1. matt-edmondson commented on Oct 7, 2026

    @matt-edmondson
    ContributorAuthor

    Triage


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions