Skip to content

fix(ui): match --only patterns with ./ prefix and absolute entries#128

Merged
umputun merged 2 commits intomasterfrom
fix/only-dot-prefix
Apr 19, 2026
Merged

fix(ui): match --only patterns with ./ prefix and absolute entries#128
umputun merged 2 commits intomasterfrom
fix/only-dot-prefix

Conversation

@umputun
Copy link
Copy Markdown
Owner

@umputun umputun commented Apr 19, 2026

-F/--only dropped matching files when the pattern started with ./. filterOnly only resolved against workDir for absolute patterns, so:

  • git mode: entry CLAUDE.md vs pattern ./CLAUDE.md - no match
  • no-VCS mode: FileReader returns absolute paths, entry /repo/CLAUDE.md vs pattern ./CLAUDE.md - no match

Normalize both entry and pattern to workDir-relative form before comparing, mirroring FallbackRenderer.pathMatches. Preserves existing exact/suffix fast path.

Fixes #127

filterOnly only resolved patterns against workDir when the pattern was
absolute, so `./CLAUDE.md` silently dropped matching files in both git
mode (repo-relative entries) and no-VCS mode (absolute entries from
FileReader). Normalize both entry and pattern to workDir-relative form
before comparing, mirroring FallbackRenderer.pathMatches.

Related to #127
Copilot AI review requested due to automatic review settings April 19, 2026 22:30
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes -F/--only path matching in the UI loader so patterns with ./ prefixes and absolute FileReader entries match consistently by normalizing both entries and patterns to workDir-relative paths (mirroring the fallback renderer logic). This addresses Issue #127 where revdiff -F ./CLAUDE.md could yield an empty file list.

Changes:

  • Refactors Model.filterOnly to use a new helper (entryMatchesOnly) that normalizes entries/patterns relative to workDir before matching.
  • Adds workDirRel helper to safely convert absolute/relative inputs into workDir-relative paths.
  • Adds test cases covering ./-prefixed patterns, absolute entries, and escaping .. patterns.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
app/ui/loaders.go Adds workDir-relative normalization for --only matching via new helper methods.
app/ui/loaders_test.go Adds regression tests for ./-prefixed --only patterns and absolute-entry matching.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread app/ui/loaders.go
Comment on lines 298 to 305
var filtered []diff.FileEntry
for _, e := range entries {
for _, pattern := range m.cfg.only {
if e.Path == pattern || strings.HasSuffix(e.Path, "/"+pattern) {
if m.entryMatchesOnly(e.Path, pattern) {
filtered = append(filtered, e)
break
}
// resolve absolute pattern relative to workDir for matching against repo-relative files
if m.cfg.workDir != "" && filepath.IsAbs(pattern) {
rel, err := filepath.Rel(m.cfg.workDir, pattern)
if err == nil && !strings.HasPrefix(rel, "..") && (e.Path == rel || strings.HasSuffix(e.Path, "/"+rel)) {
filtered = append(filtered, e)
break
}
}
}
Copy link

Copilot AI Apr 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

filterOnly calls entryMatchesOnly for every (entry, pattern) pair, and entryMatchesOnly recomputes workDirRel(entry) each time even though entry is constant across the inner loop. Consider precomputing the normalized entry once per entry (and possibly normalizing patterns once upfront) to avoid repeated filepath.Rel work on large file lists.

Copilot uses AI. Check for mistakes.
Comment thread app/ui/loaders.go Outdated
Comment on lines +291 to +293
// both entries and patterns are also normalized to workDir-relative form for matching,
// so "./CLAUDE.md" matches "CLAUDE.md" and an absolute entry from FileReader
// ("/repo/CLAUDE.md") matches a relative pattern ("CLAUDE.md").
Copy link

Copilot AI Apr 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The filterOnly doc comment says entries/patterns are normalized to workDir-relative form for matching, but the implementation only does that when cfg.workDir is non-empty (otherwise it falls back to exact/suffix only). Consider clarifying this in the comment so behavior is accurate when workDir is unset.

Suggested change
// both entries and patterns are also normalized to workDir-relative form for matching,
// so "./CLAUDE.md" matches "CLAUDE.md" and an absolute entry from FileReader
// ("/repo/CLAUDE.md") matches a relative pattern ("CLAUDE.md").
// when workDir is set, entries and patterns are also normalized to workDir-relative
// form for matching, so "./CLAUDE.md" matches "CLAUDE.md" and an absolute entry
// from FileReader ("/repo/CLAUDE.md") matches a relative pattern ("CLAUDE.md").
// when workDir is unset, matching falls back to exact-path or suffix checks only.

Copilot uses AI. Check for mistakes.
Comment thread app/ui/loaders.go
path = filepath.Join(m.cfg.workDir, path)
}
rel, err := filepath.Rel(m.cfg.workDir, path)
if err != nil || strings.HasPrefix(rel, "..") {
Copy link

Copilot AI Apr 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

workDirRel uses strings.HasPrefix(rel, "..") to detect paths outside workDir. This incorrectly treats valid in-repo paths like "..foo" (a filename starting with "..") as escaping. Prefer filepath.IsLocal(rel) (or rel == ".." || strings.HasPrefix(rel, ".."+string(filepath.Separator))) to accurately detect traversal outside the workDir.

Suggested change
if err != nil || strings.HasPrefix(rel, "..") {
if err != nil || !filepath.IsLocal(rel) {

Copilot uses AI. Check for mistakes.
workDir-relative normalization only applies when cfg.workDir is set;
when empty, matching falls back to exact/suffix only. Make that
explicit in the comment.
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages bot commented Apr 19, 2026

Deploying revdiff with  Cloudflare Pages  Cloudflare Pages

Latest commit: aacfc68
Status: ✅  Deploy successful!
Preview URL: https://654845bf.revdiff.pages.dev
Branch Preview URL: https://fix-only-dot-prefix.revdiff.pages.dev

View logs

@umputun umputun merged commit 2081592 into master Apr 19, 2026
5 checks passed
@umputun umputun deleted the fix/only-dot-prefix branch April 19, 2026 22:36
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.

-F/--only rejects relative paths with ./ prefix

2 participants