Glob Reference
Globs define file patterns for filtering.
Syntax
Section titled “Syntax”glob(include, exclude)Pattern Characters
Section titled “Pattern Characters”| Pattern | Matches |
|---|---|
* | Any characters except / |
** | Any characters including / |
? | Single character |
[abc] | Character class |
[!abc] | Negated character class |
Examples
Section titled “Examples”Include Only
Section titled “Include Only”glob(["src/**", "docs/**"])Include and Exclude
Section titled “Include and Exclude”glob( include = ["**"], exclude = ["**/internal/**"],)By Extension
Section titled “By Extension”glob(["**/*.py", "**/*.pyi"])By Directory
Section titled “By Directory”glob(["src/**"])glob(["src/*"]) # One level onlyExclude Multiple
Section titled “Exclude Multiple”glob( include = ["**"], exclude = [ "**/test/**", "**/*_test.go", "**/testdata/**", ],)Usage Contexts
Section titled “Usage Contexts”origin_files
Section titled “origin_files”origin_files = glob(["src/**"])destination_files
Section titled “destination_files”destination_files = glob( include = ["**"], exclude = ["README.md"],)Transformation paths
Section titled “Transformation paths”core.replace( before = "old", after = "new", paths = glob(["**/*.md"]),)core.remove
Section titled “core.remove”core.remove(glob(["**/*.bak"]))Advanced Patterns
Section titled “Advanced Patterns”Match Root Files Only
Section titled “Match Root Files Only”glob(["*.md"]) # Only root-level .md filesglob(["**/*.md"]) # All .md files recursivelyMatch Specific Depth
Section titled “Match Specific Depth”glob(["src/*/*.py"]) # Python files exactly 1 level under src/glob(["src/**/*.py"]) # Python files at any depth under src/Multiple Extensions
Section titled “Multiple Extensions”glob(["**/*.{js,ts,jsx,tsx}"]) # NOT supported - use list insteadglob(["**/*.js", "**/*.ts", "**/*.jsx", "**/*.tsx"]) # CorrectHidden Files
Section titled “Hidden Files”glob(["**/.*"]) # All hidden files (starting with .)glob(["**/.github/**"]) # .github directory contentsCommon Pitfalls
Section titled “Common Pitfalls”Pitfall: Missing ** for Recursive Match
Section titled “Pitfall: Missing ** for Recursive Match”# WRONG: Only matches src/file.py, not src/sub/file.pyglob(["src/*.py"])
# CORRECT: Matches all .py files under src/glob(["src/**/*.py"])Pitfall: Exclude Order Matters
Section titled “Pitfall: Exclude Order Matters”Excludes are processed after includes. An excluded path cannot be re-included.
glob( include = ["**"], exclude = ["internal/**"],)# internal/important.txt is EXCLUDED even if you wanted itPitfall: Trailing Slashes
Section titled “Pitfall: Trailing Slashes”Glob patterns should NOT have trailing slashes:
# WRONGglob(["src/"])
# CORRECTglob(["src/**"])Performance Tips
Section titled “Performance Tips”Copybara calculates “roots” from your glob patterns to determine which directories to query from the repository. More specific patterns = fewer files traversed.
Use Specific Paths Over Wildcards
Section titled “Use Specific Paths Over Wildcards”# SLOWER: Scans entire repo, then filtersglob( include = ["**"], exclude = ["vendor/**", "node_modules/**", "dist/**"],)
# FASTER: Only queries src/ and docs/ directoriesglob(["src/**", "docs/**"])Understand Root Calculation
Section titled “Understand Root Calculation”Copybara extracts the static prefix before any wildcard to determine query roots:
| Pattern | Computed Root |
|---|---|
src/**/*.py | src |
foo/bar.txt | foo |
**/*.java | “ (root) |
{foo,bar}/** | “ (root) |
Patterns with wildcards at the start (like **/*.java) force a full repo scan.
Compose Globs with Operators
Section titled “Compose Globs with Operators”Use + and - operators to build complex patterns efficiently:
base = glob(["src/**"])tests = glob(["src/**/*_test.py", "src/**/test_*.py"])
# All source files except testsorigin_files = base - testsAvoid Deeply Nested Excludes
Section titled “Avoid Deeply Nested Excludes”Each level of glob nesting adds processing overhead:
# Simple and fastglob(include = ["src/**"], exclude = ["src/internal/**"])
# More complex - avoid if not needed(glob(["src/**"]) - glob(["src/internal/**"])) + glob(["docs/**"])