Implementation:Iterative Dvc Pathspec Math
| Knowledge Sources | |
|---|---|
| Domains | Path_Operations, Pattern_Matching |
| Last Updated | 2026-02-10 10:00 GMT |
Overview
dvc/pathspec_math.py (95 lines) provides utilities for manipulating and merging gitignore-style path specification patterns. It includes the PatternInfo named tuple, the change_rule() function for rebasing individual patterns to a new directory, and the merge_patterns() function for combining two pattern sets with different base directories.
from dvc.pathspec_math import merge_patterns, change_rule, PatternInfo
Source File
| Property | Value |
|---|---|
| File | dvc/pathspec_math.py
|
| Lines | 95 |
| Exports | PatternInfo, change_rule, merge_patterns
|
Named Tuple: PatternInfo
class PatternInfo(NamedTuple):
patterns: str
file_info: str
A named tuple that pairs a pattern string with its source file information. The __str__ method returns the file_info if available, otherwise returns :{patterns}.
| Field | Type | Description |
|---|---|---|
patterns |
str |
The gitignore-style pattern rule |
file_info |
str |
Source file that defines this pattern (for debugging/tracing) |
Function: change_rule
def change_rule(rule: str, rel: str) -> str
Rebases a single gitignore pattern to be relative to a new parent directory. This follows the semantics documented in the gitignore specification.
Processing Steps
- Strip whitespace from the rule
- Comment check: If the rule starts with
#, return it unchanged - Negation check (
_not_ignore): If the rule starts with!, strip it and track the negation flag - Match level check (
_match_all_level): Determine if the pattern matches at all directory levels or is anchored:- If the rule (excluding trailing content) contains a
/and does not start with**/, it is anchored (matches specific level only) - If the rule starts with
**/, strip it and mark as match-all-level
- If the rule (excluding trailing content) contains a
- Escape removal (
_remove_slash): Strip leading backslash escapes - Reconstruct: Prefix with
/{rel}/**/{rule}for match-all patterns, or/{rel}/{rule}for anchored patterns - Negation prefix: Prepend
!if the original rule was negated - Normalize using
pathspec.util.normalize_file
Internal Helper Functions
| Function | Description |
|---|---|
_not_ignore(rule) |
Returns a tuple (is_negated, stripped_rule); strips leading !
|
_is_comment(rule) |
Returns True if the rule starts with #
|
_remove_slash(rule) |
Strips a leading backslash escape character |
_match_all_level(rule) |
Returns (matches_all_levels, processed_rule); handles **/ prefix and slash detection
|
Function: _change_dirname (private)
def _change_dirname(dirname, pattern_list, new_dirname)
Rebases an entire list of PatternInfo objects from dirname to new_dirname. If the directories are the same, returns the list unchanged. Raises ValueError if new_dirname is not a parent of dirname (i.e., if the relative path starts with ..).
Function: merge_patterns
def merge_patterns(flavour, pattern_a, prefix_a, pattern_b, prefix_b)
Merges two sets of path specification patterns that have different base directories.
Algorithm
- If either pattern list is empty, return the other with its prefix
- Compute the longest common parent directory using
flavour.commonpath([prefix_a, prefix_b]) - Rebase both pattern lists to the common parent directory via
_change_dirname - Concatenate the rebased patterns, placing the one with the shorter original prefix first (preserving precedence)
- Return the merged pattern list and the common parent directory
Parameters
| Parameter | Description |
|---|---|
flavour |
Path flavour providing commonpath() (e.g., PurePosixPath)
|
pattern_a |
First list of PatternInfo objects
|
prefix_a |
Base directory for first pattern list |
pattern_b |
Second list of PatternInfo objects
|
prefix_b |
Base directory for second pattern list |
Return Value
Returns a tuple of (merged_patterns, common_base_directory).
Key Dependencies
| Module | Usage |
|---|---|
pathspec.util.normalize_file |
Normalizes file path patterns to a canonical form |
dvc.utils.relpath |
Computes relative paths between directories |
See Also
- Implementation:Fs_Dvc_Path -- Path abstraction for DVC filesystems