Conversation
Agent-Logs-Url: https://github.com/dotnet/arcade-services/sessions/b07ed876-01b6-495a-937a-5cda736f059b Co-authored-by: premun <7013027+premun@users.noreply.github.com>
--path filter to darc vmr diff
There was a problem hiding this comment.
Pull request overview
Adds a --path filter to darc vmr diff to allow scoping diffs to one or more subpaths, improving usability when working with large repos/VMRs.
Changes:
- Introduced
--path(multi-valued) option ondarc vmr diff. - Full diff mode: prepends user-provided pathspecs to the existing exclusion filter list and normalizes path separators.
- Name-only mode: post-filters computed differences by path prefix and normalizes path separators; updated docs with examples.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/Microsoft.DotNet.Darc/Darc/Options/VirtualMonoRepo/VmrDiffOptions.cs |
Adds the --path CLI option for scoping diffs. |
src/Microsoft.DotNet.Darc/Darc/Operations/VirtualMonoRepo/VmrDiffOperation.cs |
Applies --path filtering in both full diff and name-only diff modes. |
docs/Darc.md |
Documents --path usage and provides examples. |
| IReadOnlyCollection<string> exclusionFilters = await GetDiffFilters(vmr.Remote, vmr.Ref, mapping); | ||
| return await GenerateDiff(tmpRepo, tmpVmr, vmr.Ref, exclusionFilters); | ||
| IReadOnlyCollection<string> allFilters = _options.Paths.Any() | ||
| ? [.. _options.Paths.Select(p => p.Replace('\\', '/')), .. exclusionFilters] | ||
| : exclusionFilters; | ||
| return await GenerateDiff(tmpRepo, tmpVmr, vmr.Ref, allFilters); |
There was a problem hiding this comment.
--path normalization differs between full diff and name-only modes. Here only backslashes are replaced, but leading '/', './', or '' aren’t trimmed like they are in FileTreeDiffAsync, which can make --path /src/foo behave differently depending on --name-only. Consider centralizing path normalization (trim leading separators/"./", replace '\' with '/', and ignore/throw on empty/whitespace entries) and using it in both modes before building allFilters.
| fileDifferences = fileDifferences | ||
| .Where(kv => normalizedPaths.Any(p => kv.Key.StartsWith(p, StringComparison.OrdinalIgnoreCase))) |
There was a problem hiding this comment.
The name-only --path filter uses StartsWith, which can over-match sibling paths (e.g., --path src/lib would also include src/libraries). If the intention is to treat --path as a directory/file boundary (like git pathspecs), consider matching either exact path or prefix followed by '/' (and normalize any trailing slashes). Also consider whether OrdinalIgnoreCase is desired on case-sensitive platforms; using an OS-dependent comparison would better mirror git behavior.
| fileDifferences = fileDifferences | |
| .Where(kv => normalizedPaths.Any(p => kv.Key.StartsWith(p, StringComparison.OrdinalIgnoreCase))) | |
| var pathComparison = OperatingSystem.IsWindows() | |
| ? StringComparison.OrdinalIgnoreCase | |
| : StringComparison.Ordinal; | |
| bool PathMatchesFilter(string filePath, string filterPath) | |
| { | |
| // Both filePath and filterPath are expected to be normalized to use '/' and start with '/' | |
| if (filePath.Equals(filterPath, pathComparison)) | |
| { | |
| return true; | |
| } | |
| if (!filterPath.EndsWith("/", StringComparison.Ordinal)) | |
| { | |
| filterPath += "/"; | |
| } | |
| return filePath.StartsWith(filterPath, pathComparison); | |
| } | |
| fileDifferences = fileDifferences | |
| .Where(kv => normalizedPaths.Any(p => PathMatchesFilter(kv.Key, p))) |
| var normalizedPaths = _options.Paths | ||
| .Select(p => "/" + p.TrimStart('/', '\\').Replace('\\', '/')) | ||
| .ToList(); | ||
| fileDifferences = fileDifferences |
There was a problem hiding this comment.
so we essentially do a full diff and filter it?
Prob doesn't really matter but in theory we could not search the files that are not on the provided paths too
There was a problem hiding this comment.
Right. Yeah, that would make it run much faster. @copilot can you make this change?
darc vmr diffalways diffed the entire repository with no way to scope it to specific paths.Usage
#5572