Skip to content

Keep a dangling link at cp -n's destination; count lines under grep -cU - #522

Merged
tobert merged 3 commits into
mainfrom
fix/cp-n-grep-cu
Oct 8, 2026
Merged

tobert merged 3 commits into
mainfrom
fix/cp-n-grep-cu

Conversation

@tobert

@tobert tobert commented Oct 5, 2026

Copy link
Copy Markdown
Owner

cp -n asked backend.exists whether the destination was taken. exists follows links, so a dangling symlink at the destination read as absent and cp wrote through it, creating the link's target. A single file and a file inside cp -rn both did it. mv -n and cp -n on a link source already used lstat. Both sites now do too.

grep -c printed match_count, the number of match records. Under -U a record can span lines, so a 3-line match printed 1 and grep -cU '\s' on 34 lines printed 1. RenderResult now carries matched_lines, the lines the records cover (newlines in the trimmed text, plus one), and -c prints that, for one file, stdin, and several files. match_count still drives --max-count and the exit status, so -m counts records. The -U tests from #517 had pinned the old count; they now expect the line count.

Each fix has tests that failed before it. Both come from the fix backlog recorded after the 0.18 reviews; this is the data-safety item and the miscount in a feature #517 just made work on every path. The CHANGELOG hunk will conflict with #521 until that merges.

🤖 Generated with Claude Code

tobert and others added 3 commits October 5, 2026 17:51
cp -n asked backend.exists whether the destination was taken. exists
follows links, so a dangling symlink at the destination read as absent
and cp wrote through it, creating the link's target. A single file and
a file inside cp -rn both did it. mv -n and cp -n on a link source
already used lstat. Both sites now do too.

grep -c printed match_count, the number of match records. Under -U a
record can span lines, so a 3-line match printed 1 and `grep -cU '\s'`
on 34 lines printed 1. RenderResult now carries matched_lines, the
lines the records cover (newlines in the trimmed text, plus one), and
-c prints that, for one file, stdin, and several files. match_count
still drives --max-count and the exit status, so -m counts records.
The -U tests from the previous change had pinned the old count; they
now expect the line count.

Each fix has tests that failed before it.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…d match on one line

Cases from the kaibo review of the previous commit; each passes. The
directory-link test reads back through the link path because MemoryFs
does not resolve a link in the middle of a path.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@tobert
tobert merged commit 78c6de8 into main Oct 8, 2026
3 checks passed
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.

1 participant