Skip to content

fix(git): porcelain v2 -z rename origin paths can be miscounted as status entries #39

Description

@lemtoc

As of v0.3.0 (c73dc6c).

Summary

parse_porcelain_v2_z (src/segments/git.rs:420) treats every NUL-separated record independently. In --porcelain=v2 -z output, a rename/copy entry (2 <XY> ...<path>) is followed by the origin path as its own NUL-terminated record. That bare path is then fed through parse_record, and if it happens to start with 1 , 2 , u , or ? , it is counted as an additional status entry.

Reproduction

git mv '? note.txt' renamed.txt   # a tracked file whose name starts with "? "

git status --porcelain=v2 -z emits 2 R. ... renamed.txt\0? note.txt\0; Nova counts untracked += 1 for the origin-path record, so the prompt shows a ? indicator in a repo with no untracked files.

Cause

The parser has no state for "the previous record was a 2 entry, so the next record is a path, not an entry". Pathological file names are rare, which is why this has not been visible, but the parse is structurally wrong for the documented format (git-status(1), "Porcelain Format Version 2": "the pathnames are separated by a NUL" for rename entries under -z).

Proposed fix

  • In the record loop, after parsing a record that starts with 2 , skip the following record unconditionally.
  • Add unit tests with -z rename output where the origin path starts with ? , 1 , and u .

Low severity (cosmetic miscount, requires unusual file names), but it is a two-line fix in a parser that is otherwise carefully tested.


🤖 Generated with Claude Code — Claude Fable 5

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low priority or proposalarea:segmentsComponent: segmentsbugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions