zip -x: Exclude Files by Pattern
zip -x removes files matching the given patterns from what would otherwise be archived.
Build outputs often contain things you do not want shipped, like .git, node_modules, or test fixtures. -x filters them out at archive time.
What it does
zip -x takes one or more patterns and excludes any matching path from the archive. Patterns use shell-style wildcards interpreted by zip itself, so you typically quote them to stop the shell from expanding them first. -x comes after the input list.
Common usage
zip -r release.zip . -x '*.git*'
# exclude node_modules and test files
zip -r app.zip . -x '*/node_modules/*' -x '*.test.js'
# exclude a whole directory tree
zip -r site.zip . -x 'coverage/*'Options
| Flag | What it does |
|---|---|
| -x <pattern> | Exclude paths matching the pattern |
| -i <pattern> | Include only paths matching the pattern |
| -r | Recurse into directories |
| * | Wildcard matching any characters including / |
| ? | Wildcard matching a single character |
In CI
Quote the patterns so zip, not the shell, does the matching: -x '*/node_modules/*' behaves consistently regardless of the working directory contents. Remember zip wildcards match across slashes, so *.git* also catches paths deeper in the tree.
Common errors in CI
An unquoted pattern like -x *.log is expanded by the shell first, so if no .log file exists in the current directory the literal *.log reaches zip and may not match nested files as intended; quote it. "zip warning: name not matched" on the include side means the listed input does not exist. If nothing is excluded, the pattern likely lacks the leading */ needed to match nested paths.