Skip to content

Fix git grep -l replacing first hyphen with colon in filenames#2089

Open
cjpeterein wants to merge 2 commits intodandavison:mainfrom
cjpeterein:fix/grep-l
Open

Fix git grep -l replacing first hyphen with colon in filenames#2089
cjpeterein wants to merge 2 commits intodandavison:mainfrom
cjpeterein:fix/grep-l

Conversation

@cjpeterein
Copy link
Copy Markdown

Summary

Fix for issue #1674: git grep -l output incorrectly replaces the first hyphen in filenames with a colon (e.g., my-file.rs becomes my:file.rs).

  • Detect when git grep is running with filename-only output flags (-l, -L, --files-with-matches, --files-without-match)
  • Skip grep line parsing entirely for these modes, allowing filenames to pass through unchanged

Problem

When running git grep -l "pattern" | delta, filenames containing hyphens are corrupted:

# Expected output
my-file.rs

# Actual output before fix
my:file.rs

Root cause: The WithoutSeparatorCharacters regex in parse_grep_line() excludes hyphens from the file path character class. For input my-file.rs (with no line number or code content), it matches:

  • File path: my (stops at hyphen)
  • Separator: - (the hyphen from the filename)
  • Code: file.rs

When the separator is replaced with the default :, the filename becomes my:file.rs.

Solution

Detect filename-only output mode by checking for -l/-L/--files-with-matches/--files-without-match flags in the calling process command line. When detected, return None from parse_grep_line() so the line passes through unchanged.

Alternatives Considered

Option B: Improve regex to require content after separator

Modify the WithoutSeparatorCharacters regex to require actual code content after the separator, not just a file extension pattern.

Ruled out because:

  • The regex is already complex and fragile
  • The ignored test at line 909 (test_parse_grep_n_match_file_name_with_dashes_and_no_extension) demonstrates this is a known hard problem
  • Risk of breaking other edge cases
  • Doesn't address the semantic issue: -l output simply isn't grep output format

Option C: Validate parsed path exists on filesystem

After parsing, check if the extracted file path actually exists before accepting the parse result.

Ruled out because:

  • Performance impact from filesystem calls on every line
  • Doesn't work for grep output piped from remote sources or stdin
  • Doesn't work for files that have been deleted since the grep ran
  • Over-engineered solution for a simpler problem

Test Plan

  • New test: test_parse_grep_filename_only_output_with_hyphen - verifies filenames with hyphens return None when -l, -L, --files-with-matches, or --files-without-match flags are present
  • New test: test_parse_grep_regular_output_with_hyphen_still_works - verifies regular grep output with line numbers still parses correctly
  • All existing grep tests pass
  • Manual verification: git grep -l "pattern" | delta preserves hyphenated filenames

Fixes #1674

🤖 Generated with Claude Code

When git grep runs with -l/-L/--files-with-matches/--files-without-match,
output contains only filenames without line numbers or code. The grep
parser's WithoutSeparatorCharacters regex incorrectly matched hyphens
in filenames as separators, causing "my-file.rs" to become "my:file.rs".

Skip grep line parsing entirely when these filename-only flags are detected.

Fixes dandavison#1674

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Existing tests (test_parse_grep_match, test_parse_grep_n_match) already
cover parsing grep output with hyphenated filenames, so the additional
test_git_grep_n_still_parses_hyphenated_filenames was redundant.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

git grep -l replaces first - with a :

2 participants