Skip to content

feat(pr diff): add --exclude flag to filter files from diff output#12655

Merged
babakks merged 6 commits intocli:trunkfrom
yuvrajangadsingh:feature/pr-diff-exclude
Mar 9, 2026
Merged

feat(pr diff): add --exclude flag to filter files from diff output#12655
babakks merged 6 commits intocli:trunkfrom
yuvrajangadsingh:feature/pr-diff-exclude

Conversation

@yuvrajangadsingh
Copy link
Contributor

Adds a --exclude (-e) flag to gh pr diff that lets you filter out files matching glob patterns from the diff output.

Example usage:

# Exclude all YAML files
gh pr diff --exclude '*.yml'

# Exclude multiple patterns
gh pr diff --exclude '*.yml' --exclude 'vendor/*'

# Works with --name-only too
gh pr diff --name-only --exclude '*.generated.*'

Patterns are matched against both the full file path and the basename, so --exclude '*.yml' will match dir/file.yml.

Uses Go's filepath.Match for glob support — no new dependencies.

Closes #8739

@yuvrajangadsingh yuvrajangadsingh marked this pull request as ready for review February 17, 2026 07:12
@yuvrajangadsingh yuvrajangadsingh requested a review from a team as a code owner February 17, 2026 07:12
@cliAutomation cliAutomation added the external pull request originating outside of the CLI core team label Feb 17, 2026
@yuvrajangadsingh yuvrajangadsingh force-pushed the feature/pr-diff-exclude branch 2 times, most recently from 186d5d5 to bc15e7d Compare February 20, 2026 08:13
@yuvrajangadsingh
Copy link
Contributor Author

@BagToad @babakks hey, just wanted to check if this is something the team would be interested in — adds an --exclude flag to gh pr diff so you can filter out noisy files (like lockfiles, snapshots, generated code). pretty common ask based on the issues i've seen. let me know if there's anything to adjust!

@yuvrajangadsingh yuvrajangadsingh force-pushed the feature/pr-diff-exclude branch 2 times, most recently from aa530d3 to e147705 Compare February 24, 2026 07:09
@yuvrajangadsingh
Copy link
Contributor Author

gentle bump on this one — would love to get some eyes on it when someone has a chance. happy to make changes if anything needs adjusting.

@yuvrajangadsingh yuvrajangadsingh force-pushed the feature/pr-diff-exclude branch from e147705 to be8446c Compare March 1, 2026 10:05
Copy link
Member

@BagToad BagToad left a comment

Choose a reason for hiding this comment

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

Nice implementation — the exclude logic is clean and well-tested.

One change needed: the diff header regex is duplicated. changedFilesNames (line ~310) already has an inline regex that's nearly identical to your new diffHeaderRegexp:

// existing (changedFilesNames):
pattern := regexp.MustCompile(`(?:^|\n)diff\s--git.*\s(["']?)b/(.*)`)

// new (extractFileName):
var diffHeaderRegexp = regexp.MustCompile(`diff\s--git.*\s(["']?)b/(.*)`)

Could you share the compiled regex between both and ideally refactor changedFilesNames to use your splitDiffSections/extractFileName helpers? That would reduce duplication and make the code easier to maintain.

If this is too painful, let me know — it's kind of a nit so I'm happy to tackle it in a follow-up if needed instead.

@BagToad
Copy link
Member

BagToad commented Mar 4, 2026

Also note, we need to fix the linter checks.

@yuvrajangadsingh yuvrajangadsingh force-pushed the feature/pr-diff-exclude branch from be8446c to fc3b9ef Compare March 4, 2026 21:49
@yuvrajangadsingh
Copy link
Contributor Author

@BagToad fixed both — shared the compiled diffHeaderRegexp between changedFilesNames and extractFileName (removed the inline duplicate), and fixed the gofmt spacing. rebased on trunk too.

@yuvrajangadsingh yuvrajangadsingh requested a review from BagToad March 4, 2026 21:53
@yuvrajangadsingh yuvrajangadsingh force-pushed the feature/pr-diff-exclude branch from fc3b9ef to 40ac081 Compare March 5, 2026 15:30
Copy link
Member

@babakks babakks left a comment

Choose a reason for hiding this comment

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

Thanks for the PR, @yuvrajangadsingh! 🙏

Just commented some thoughts, but the main one is the last (about using path instead of filepath).

Comment on lines 288 to +306
// This is kind of a gnarly regex. We're looking lines of the format:
// diff --git a/9114-triage b/9114-triage
// diff --git "a/hello-\360\237\230\200-world" "b/hello-\360\237\230\200-world"
//
// From these lines we would look to extract:
// 9114-triage
// "hello-\360\237\230\200-world"
//
// Note that the b/ is removed but in the second case the preceeding quote remains.
// This is important for how git handles filenames that would be quoted with core.quotePath.
// https://git-scm.com/docs/git-config#Documentation/git-config.txt-corequotePath
//
// Thus we capture the quote if it exists, and everything that follows the b/
// We then concatenate those two capture groups together which for the examples above would be:
// `` + 9114-triage
// `"`` + hello-\360\237\230\200-world"
//
// Where I'm using the `` to indicate a string to avoid confusion with the " character.
pattern := regexp.MustCompile(`(?:^|\n)diff\s--git.*\s(["]?)b/(.*)`)
matches := pattern.FindAllStringSubmatch(string(diff), -1)
matches := diffHeaderRegexp.FindAllStringSubmatch(string(diff), -1)
Copy link
Member

Choose a reason for hiding this comment

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

thought: we should really think about using a reliable third-party for this stuff. 🤷

Copy link
Member

Choose a reason for hiding this comment

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

💯 agree. Felt this pain with gh agent as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

agreed, would be nice to have. out of scope for this PR though

Copy link
Member

@BagToad BagToad left a comment

Choose a reason for hiding this comment

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

Please re-request review when @babakks comments addressed 🙏 thank you

@yuvrajangadsingh
Copy link
Contributor Author

@babakks @BagToad addressed all feedback in 43c845e:

  • added usage examples to --help
  • switched filepath.Match to path.Match for OS-consistent behavior
  • renamed patterns to excludePatterns
  • simplified splitDiffSections with strings.Split

ready for another look when you get a chance.

@yuvrajangadsingh yuvrajangadsingh requested a review from BagToad March 6, 2026 08:11
@yuvrajangadsingh yuvrajangadsingh force-pushed the feature/pr-diff-exclude branch from 16fd9ad to f2ac428 Compare March 6, 2026 08:13
Add a new --exclude (-e) flag to gh pr diff that allows users to exclude
files matching glob patterns from the diff output. This is useful for
filtering out auto-generated files, vendor directories, or other noise
when reviewing pull requests.

Supports standard glob patterns and can be specified multiple times.
Patterns match against both the full path and basename.

Closes cli#8739
- add usage examples to --help output
- use path.Match instead of filepath.Match for OS-consistent behavior
- rename patterns to excludePatterns for clarity
- simplify splitDiffSections using strings.Split
Copy link
Member

@babakks babakks left a comment

Choose a reason for hiding this comment

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

Just a nitpick, @yuvrajangadsingh.

@yuvrajangadsingh yuvrajangadsingh requested a review from babakks March 9, 2026 14:06
Copy link
Member

@babakks babakks left a comment

Choose a reason for hiding this comment

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

LGTM! Thanks for your time and effort, @yuvrajangadsingh! 🙏 🚀

Tested on Linux and Windows, and works like a charm.

@babakks babakks merged commit 4ae2743 into cli:trunk Mar 9, 2026
11 checks passed
tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Mar 24, 2026
This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [cli/cli](https://github.com/cli/cli) | minor | `v2.87.3` → `v2.88.1` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>cli/cli (cli/cli)</summary>

### [`v2.88.1`](https://github.com/cli/cli/releases/tag/v2.88.1): GitHub CLI 2.88.1

[Compare Source](cli/cli@v2.88.0...v2.88.1)

#### Fix `pr` commands failing with `read:project` scope error

v2.88.0 introduced a regression where `pr` commands would fail with the error:

```
error: your authentication token is missing required scopes [read:project]
To request it, run:  gh auth refresh -s read:project
```

Previously, missing read:project scope was gracefully handled, and project data was silently skipped. A change inadvertently broke the error matching that enabled this graceful degradation. v2.88.1 reverts these changes so that `pr` commands work correctly without requiring the `read:project` scope.

#### What's Changed

- Migrate Windows code signing from client secret to OIDC by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;12911](cli/cli#12911)
- Revert "refactor: deduplicate scope error handling between api/client.go and project queries" by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;12914](cli/cli#12914)
- Revert "fix: clarify scope error while creating issues for projects" by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;12915](cli/cli#12915)

**Full Changelog**: <cli/cli@v2.88.0...v2.88.1>

### [`v2.88.0`](https://github.com/cli/cli/releases/tag/v2.88.0): GitHub CLI 2.88.0

[Compare Source](cli/cli@v2.87.3...v2.88.0)

#### :copilot: Request Copilot Code Review from `gh`

<img width="80%" height="80%" alt="image" src="proxy.php?url=https%3A%2F%2Fgithub.com%2F%3Ca+href%3D"https://github.com/user-attachments/assets/c9b86700-5934-44b6-9210-227495a18d8e">https://github.com/user-attachments/assets/c9b86700-5934-44b6-9210-227495a18d8e" />

`gh pr create` and `gh pr edit` now support [Copilot Code Review](https://docs.github.com/en/copilot/using-github-copilot/code-review/using-copilot-code-review) as a reviewer. Request a review with `--add-reviewer @&#8203;copilot`, or select Copilot interactively from the searchable reviewer prompt.

Create a pull request and request review from Copilot:

```
gh pr create --reviewer @&#8203;copilot
```

Edit a pull request and request review from Copilot:

```
gh pr edit --add-reviewer @&#8203;copilot
```

#### Close issues as duplicates with `gh issue close --duplicate-of`

You can now close issues as duplicates and link to a duplicate issue directly from the CLI. The new `--duplicate-of` flag accepts an issue number or URL and marks the closed issue as a duplicate of the referenced one. You can also use `--reason duplicate` to set the close reason without linking a specific issue.

```

# Close as duplicate, linking to the original issue
gh issue close 123 --duplicate-of 456

# Close with duplicate reason only
gh issue close 123 --reason duplicate
```

#### JSON support for `gh agent-task`

`gh agent-task list` and `gh agent-task view` now support `--json`, `--jq`, and `--template` flags, consistent with other `gh` commands.

```
gh agent-task list --json id,name,state
gh agent-task view <id> --json state --jq '.state'
```

#### What's Changed

##### ✨ Features

- `gh pr create`: login-based reviewer requests and search-based interactive selection by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;12627](cli/cli#12627)
- `gh pr view` and `gh issue view`: show friendly display names for all actors by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;12854](cli/cli#12854)
- `gh issue close`: add `--duplicate-of` flag and duplicate reason by [@&#8203;tksohishi](https://github.com/tksohishi) in [#&#8203;12811](cli/cli#12811)
- `gh pr diff`: add `--exclude` flag to filter files from diff output by [@&#8203;yuvrajangadsingh](https://github.com/yuvrajangadsingh) in [#&#8203;12655](cli/cli#12655)
- `gh pr view/list`: add `changeType` field to files JSON output by [@&#8203;yuvrajangadsingh](https://github.com/yuvrajangadsingh) in [#&#8203;12657](cli/cli#12657)
- `gh repo clone`: add `--no-upstream` flag by [@&#8203;4RH1T3CT0R7](https://github.com/4RH1T3CT0R7) in [#&#8203;12686](cli/cli#12686)
- `gh repo edit`: add `--squash-merge-commit-message` flag by [@&#8203;yuvrajangadsingh](https://github.com/yuvrajangadsingh) in [#&#8203;12846](cli/cli#12846)
- `gh browse`: add `--blame` flag by [@&#8203;masonmcelvain](https://github.com/masonmcelvain) in [#&#8203;11486](cli/cli#11486)
- `gh agent-task list`: add `--json` support by [@&#8203;maxbeizer](https://github.com/maxbeizer) in [#&#8203;12806](cli/cli#12806)
- `gh agent-task view`: add `--json` support by [@&#8203;maxbeizer](https://github.com/maxbeizer) in [#&#8203;12807](cli/cli#12807)
- `gh copilot`: set `COPILOT_GH` env var when launching Copilot CLI by [@&#8203;devm33](https://github.com/devm33) in [#&#8203;12821](cli/cli#12821)

##### 🐛 Fixes

- Fix `gh project item-edit` error when editing Draft Issue with only one (`--title`/`--body`) flag by [@&#8203;ManManavadaria](https://github.com/ManManavadaria) in [#&#8203;12787](cli/cli#12787)
- Fix extension install error message showing raw struct instead of `owner/repo` by [@&#8203;Copilot](https://github.com/Copilot) in [#&#8203;12836](cli/cli#12836)
- Fix incorrect integer conversion from int to uint16 in port forwarder by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;12831](cli/cli#12831)
- Fix invalid ANSI SGR escape code in JSON and diff colorization by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;12720](cli/cli#12720)
- Fix assignees `databaseId` always being `0` in `--json` output by [@&#8203;srt32](https://github.com/srt32) in [#&#8203;12783](cli/cli#12783)
- Fix error when `--remote` flag used with repo argument by [@&#8203;majiayu000](https://github.com/majiayu000) in [#&#8203;12375](cli/cli#12375)
- Fix redundant API call in `gh issue view --comments` by [@&#8203;VishnuVV27](https://github.com/VishnuVV27) in [#&#8203;12652](cli/cli#12652)
- Clarify scope error while creating issues for projects by [@&#8203;elijahthis](https://github.com/elijahthis) in [#&#8203;12596](cli/cli#12596)
- Reject pull request-only search qualifiers in `gh issue list` by [@&#8203;LouisLau-art](https://github.com/LouisLau-art) in [#&#8203;12623](cli/cli#12623)
- Prevent `.git/config` corruption on repeated `issue develop --name` invocation by [@&#8203;gunadhya](https://github.com/gunadhya) in [#&#8203;12651](cli/cli#12651)
- Use pre-compiled regexp for matching Content-Type by [@&#8203;itchyny](https://github.com/itchyny) in [#&#8203;12781](cli/cli#12781)
- Isolate generated licenses per platform (os/arch) by [@&#8203;babakks](https://github.com/babakks) in [#&#8203;12774](cli/cli#12774)

##### 📚 Docs & Chores

- Add examples to `gh issue close` help text by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;12830](cli/cli#12830)
- Customizable install `prefix` in Makefile by [@&#8203;scarf005](https://github.com/scarf005) in [#&#8203;11714](cli/cli#11714)
- Deduplicate scope error handling between `api/client.go` and project queries by [@&#8203;yuvrajangadsingh](https://github.com/yuvrajangadsingh) in [#&#8203;12845](cli/cli#12845)
- Remove unnecessary `StateReason` and `StateReasonDuplicate` feature detection by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;12838](cli/cli#12838)
- Update Go version requirement to 1.26+ by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;12864](cli/cli#12864)
- Add monthly pitch surfacing workflow by [@&#8203;tidy-dev](https://github.com/tidy-dev) in [#&#8203;12894](cli/cli#12894)

##### :dependabot: Dependencies

- Bump Go from 1.25.7 to 1.26.1 by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;12860](cli/cli#12860)
- chore(deps): bump golang.org/x/sync from 0.19.0 to 0.20.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;12886](cli/cli#12886)
- chore(deps): bump google.golang.org/grpc from 1.79.1 to 1.79.2 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;12851](cli/cli#12851)
- chore(deps): bump github.com/docker/cli from 29.0.3+incompatible to 29.2.0+incompatible by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;12842](cli/cli#12842)
- chore(deps): bump google.golang.org/grpc from 1.78.0 to 1.79.1 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;12759](cli/cli#12759)
- chore(deps): bump goreleaser/goreleaser-action from 6.4.0 to 7.0.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;12760](cli/cli#12760)
- chore(deps): bump actions/upload-artifact from 6 to 7 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;12797](cli/cli#12797)
- chore(deps): bump actions/download-artifact from 7 to 8 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;12796](cli/cli#12796)
- chore(deps): bump actions/attest-build-provenance from 3.2.0 to 4.1.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;12795](cli/cli#12795)
- chore(deps): bump github.com/gabriel-vasile/mimetype from 1.4.11 to 1.4.13 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;12615](cli/cli#12615)

#### New Contributors

- [@&#8203;srt32](https://github.com/srt32) made their first contribution in [#&#8203;12783](cli/cli#12783)
- [@&#8203;itchyny](https://github.com/itchyny) made their first contribution in [#&#8203;12781](cli/cli#12781)
- [@&#8203;VishnuVV27](https://github.com/VishnuVV27) made their first contribution in [#&#8203;12652](cli/cli#12652)
- [@&#8203;elijahthis](https://github.com/elijahthis) made their first contribution in [#&#8203;12596](cli/cli#12596)
- [@&#8203;ManManavadaria](https://github.com/ManManavadaria) made their first contribution in [#&#8203;12787](cli/cli#12787)
- [@&#8203;maxbeizer](https://github.com/maxbeizer) made their first contribution in [#&#8203;12806](cli/cli#12806)
- [@&#8203;LouisLau-art](https://github.com/LouisLau-art) made their first contribution in [#&#8203;12623](cli/cli#12623)
- [@&#8203;4RH1T3CT0R7](https://github.com/4RH1T3CT0R7) made their first contribution in [#&#8203;12686](cli/cli#12686)
- [@&#8203;yuvrajangadsingh](https://github.com/yuvrajangadsingh) made their first contribution in [#&#8203;12657](cli/cli#12657)
- [@&#8203;masonmcelvain](https://github.com/masonmcelvain) made their first contribution in [#&#8203;11486](cli/cli#11486)
- [@&#8203;scarf005](https://github.com/scarf005) made their first contribution in [#&#8203;11714](cli/cli#11714)
- [@&#8203;tksohishi](https://github.com/tksohishi) made their first contribution in [#&#8203;12811](cli/cli#12811)
- [@&#8203;tidy-dev](https://github.com/tidy-dev) made their first contribution in [#&#8203;12894](cli/cli#12894)

**Full Changelog**: <cli/cli@v2.87.3...v2.88.0>

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My42MS43IiwidXBkYXRlZEluVmVyIjoiNDMuNjQuMyIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiUmVub3ZhdGUgQm90IiwiYXV0b21hdGlvbjpib3QtYXV0aG9yZWQiLCJkZXBlbmRlbmN5LXR5cGU6Om1pbm9yIl19-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

external pull request originating outside of the CLI core team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add File Exclusion Option to gh pr diff Command

4 participants