search: Fix ignored file search in nested Git directories - #60772
Merged
ChristopherBiscardi merged 1 commit intoJul 12, 2026
Merged
Conversation
Keep parent ignore rules when rebuilding a nested repository's ignore stack.
This hides root-ignored files again after excluded-file search is turned off,
without breaking global ignore handling.
For example:
```ascii
project/
├── .git/
├── .gitignore # log/
├── app/
│ └── a.txt # hello
└── log/
├── .git/ # nested repository marker
└── b.txt # hello
```
Both `a.txt` and `b.txt` have string `hello`.
Initially, searching for `hello` returns only `a.txt`.
Enabling `Also search files ignored by configuration`
rescans `log/` and returns both files.
Before this change, disabling the option still
returned both files because the rescan dropped the parent
`.gitignore` and marked `b.txt` as included.
vitallium
force-pushed
the
vs/fix-ignored-nested-git-search
branch
from
July 10, 2026 18:11
b9ce056 to
9a5f224
Compare
pixel365
pushed a commit
to pixel365/zed
that referenced
this pull request
Jul 23, 2026
…ed-industries#61492) Closes TRA-162 When an entry's ignore stack is rebuilt from scratch (opening a file, file system events, a search that includes ignored files), `ignore_stack_for_abs_path` only consulted the `.git/info/exclude` rules of the nearest ancestor containing `.git`. For a path inside a nested repository, that nearest ancestor is the nested repository itself, so the outer repository's exclude rules were silently dropped: entries that were correctly ignored after the initial scan would flip to unignored the moment they were loaded or changed on disk, and from then on project search would surface them. This is the same class of bug that zed-industries#60772 fixed for ancestor `.gitignore` files — this change extends the fix to `info/exclude` by collecting the exclude rules of every containing repository (outermost first, mirroring how ancestor gitignores are stacked) instead of just the innermost one. Added a regression test that models the affected layout: a bare clone and a linked worktree of it kept inside the repository, hidden via anchored patterns in the outer repository's `.git/info/exclude`. Release Notes: - Fixed project search returning results from inside nested repositories that are excluded by the containing repository's `.git/info/exclude` file.
zed-zippy Bot
added a commit
that referenced
this pull request
Jul 23, 2026
…61492) (cherry-pick to preview) (#61506) Cherry-pick of #61492 to preview ---- Closes TRA-162 When an entry's ignore stack is rebuilt from scratch (opening a file, file system events, a search that includes ignored files), `ignore_stack_for_abs_path` only consulted the `.git/info/exclude` rules of the nearest ancestor containing `.git`. For a path inside a nested repository, that nearest ancestor is the nested repository itself, so the outer repository's exclude rules were silently dropped: entries that were correctly ignored after the initial scan would flip to unignored the moment they were loaded or changed on disk, and from then on project search would surface them. This is the same class of bug that #60772 fixed for ancestor `.gitignore` files — this change extends the fix to `info/exclude` by collecting the exclude rules of every containing repository (outermost first, mirroring how ancestor gitignores are stacked) instead of just the innermost one. Added a regression test that models the affected layout: a bare clone and a linked worktree of it kept inside the repository, hidden via anchored patterns in the outer repository's `.git/info/exclude`. Release Notes: - Fixed project search returning results from inside nested repositories that are excluded by the containing repository's `.git/info/exclude` file. Co-authored-by: Eric Holk <eric@zed.dev>
arbourd
added a commit
to arbourd/zed
that referenced
this pull request
Jul 26, 2026
Fixes zed-industries#61687 Prior to zed-industries#60772, an abs_path outside the repo_root would cause a panic. That PR changed it to return the abs_path itself, preventing the panic, but allowing all parents of repo_root to be subject to the global ignore. This is not what git itself does. This change returns false when the abs_path is outside the repo_root.
5 tasks
arbourd
added a commit
to arbourd/zed
that referenced
this pull request
Jul 26, 2026
Fixes zed-industries#61687 Prior to zed-industries#60772, an abs_path outside the repo_root would cause a panic. That PR changed it to return the abs_path itself, preventing the panic, but allowing all parents of repo_root to be subject to the global ignore. This is not what git itself does. This change returns false when the abs_path is outside the repo_root.
dinocosta
added a commit
to justjavac/zed
that referenced
this pull request
Jul 29, 2026
# Objective Fixes zed-industries#61687 Prior to zed-industries#60772, an `abs_path` outside the `repo_root` would cause a panic. That PR changed it to return the `abs_path` itself, preventing the panic, but allowing all parents of `repo_root` to be subject to the global ignore. This is not what git itself does. ## Solution - This change returns `false` when the `abs_path` is outside the `root_repo`, preventing the panic but also not returning the `abs_path` ## Testing - One in-memory test - Manual test by building Zed and confirming the project pane changes (pictured below) ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase ### Before, with the bug <img width="1430" height="814" alt="Screenshot 2026-07-26 at 11 44 11 AM" src="https://github.com/user-attachments/assets/66e3bb95-4f45-4fd9-a1e4-e7f253f092eb" /> ### After the fix <img width="1568" height="1042" alt="Screenshot 2026-07-26 at 12 34 58 PM" src="https://github.com/user-attachments/assets/588eb01d-830a-4c22-93c0-667742de90b6" /> Release Notes: - Fixed the project panel's global gitignore incorrectly matching parent directories of a repository --------- Co-authored-by: dino <dinojoaocosta@gmail.com>
AtlantisPleb
pushed a commit
to OpenAgentsInc/omega
that referenced
this pull request
Jul 30, 2026
# Objective Fixes zed-industries#61687 Prior to zed-industries#60772, an `abs_path` outside the `repo_root` would cause a panic. That PR changed it to return the `abs_path` itself, preventing the panic, but allowing all parents of `repo_root` to be subject to the global ignore. This is not what git itself does. ## Solution - This change returns `false` when the `abs_path` is outside the `root_repo`, preventing the panic but also not returning the `abs_path` ## Testing - One in-memory test - Manual test by building Zed and confirming the project pane changes (pictured below) ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase ### Before, with the bug <img width="1430" height="814" alt="Screenshot 2026-07-26 at 11 44 11 AM" src="https://github.com/user-attachments/assets/66e3bb95-4f45-4fd9-a1e4-e7f253f092eb" /> ### After the fix <img width="1568" height="1042" alt="Screenshot 2026-07-26 at 12 34 58 PM" src="https://github.com/user-attachments/assets/588eb01d-830a-4c22-93c0-667742de90b6" /> Release Notes: - Fixed the project panel's global gitignore incorrectly matching parent directories of a repository --------- Co-authored-by: dino <dinojoaocosta@gmail.com> (cherry picked from commit c2db0f1)
This was referenced Jul 31, 2026
jolutz
pushed a commit
to jolutz/zed
that referenced
this pull request
Aug 8, 2026
…ries#60772) # Objective - Fix ignored file search in nested Git directories (even just empty `.git` directories, not real git repositories) - Fixes zed-industries#52328 ## Solution Keep parent ignore rules when rebuilding a nested repository's ignore stack. This hides root-ignored files again after excluded-file search is turned off, without breaking global ignore handling. For example: ```ascii project/ ├── .git/ ├── .gitignore # log/ ├── app/ │ └── a.txt # hello └── log/ ├── .git/ # nested repository marker └── b.txt # hello ``` Both `a.txt` and `b.txt` have string `hello`. Initially, searching for `hello` returns only `a.txt`. Enabling `Also search files ignored by configuration` rescans `log/` and returns both files. Before this change, disabling the option still returned both files because the rescan dropped the parent `.gitignore` and marked `b.txt` as included. ## Testing - Did you test these changes? If so, how? To test changes in this pull request create a simple project with the following dir structure: ``` .git .gitignore a/a.txt b/b.txt b/.git # this is an empty directory ``` Add `b` folder as an ignore entry to the `.gitignore` file: `b/` - Are there any parts that need more testing? No - How can other people (reviewers) test your changes? Is there anything specific they need to know? Use the test scenario above - If relevant, what platforms did you test these changes on, and are there any important ones you can't test? macOS ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase By using the structure above here is how it works before changes here: https://github.com/user-attachments/assets/2028123e-388e-4390-b131-ddf4642ab5f3 Notice that `hello` string from file `b.txt` is listed in search results regardless of the option `Include excluded files` And here is after: https://github.com/user-attachments/assets/99c627a2-e16a-4fdd-979b-2e0bacbd827d Notice that `hello` string from file `b.txt` is **not** listed in search results when the option `Include excluded files` is disabled. Release Notes: - Fixed ignored file search in nested Git directories
jolutz
pushed a commit
to jolutz/zed
that referenced
this pull request
Aug 8, 2026
…ed-industries#61492) (cherry-pick to preview) (zed-industries#61506) Cherry-pick of zed-industries#61492 to preview ---- Closes TRA-162 When an entry's ignore stack is rebuilt from scratch (opening a file, file system events, a search that includes ignored files), `ignore_stack_for_abs_path` only consulted the `.git/info/exclude` rules of the nearest ancestor containing `.git`. For a path inside a nested repository, that nearest ancestor is the nested repository itself, so the outer repository's exclude rules were silently dropped: entries that were correctly ignored after the initial scan would flip to unignored the moment they were loaded or changed on disk, and from then on project search would surface them. This is the same class of bug that zed-industries#60772 fixed for ancestor `.gitignore` files — this change extends the fix to `info/exclude` by collecting the exclude rules of every containing repository (outermost first, mirroring how ancestor gitignores are stacked) instead of just the innermost one. Added a regression test that models the affected layout: a bare clone and a linked worktree of it kept inside the repository, hidden via anchored patterns in the outer repository's `.git/info/exclude`. Release Notes: - Fixed project search returning results from inside nested repositories that are excluded by the containing repository's `.git/info/exclude` file. Co-authored-by: Eric Holk <eric@zed.dev>
jolutz
pushed a commit
to jolutz/zed
that referenced
this pull request
Aug 8, 2026
…ed-industries#61492) Closes TRA-162 When an entry's ignore stack is rebuilt from scratch (opening a file, file system events, a search that includes ignored files), `ignore_stack_for_abs_path` only consulted the `.git/info/exclude` rules of the nearest ancestor containing `.git`. For a path inside a nested repository, that nearest ancestor is the nested repository itself, so the outer repository's exclude rules were silently dropped: entries that were correctly ignored after the initial scan would flip to unignored the moment they were loaded or changed on disk, and from then on project search would surface them. This is the same class of bug that zed-industries#60772 fixed for ancestor `.gitignore` files — this change extends the fix to `info/exclude` by collecting the exclude rules of every containing repository (outermost first, mirroring how ancestor gitignores are stacked) instead of just the innermost one. Added a regression test that models the affected layout: a bare clone and a linked worktree of it kept inside the repository, hidden via anchored patterns in the outer repository's `.git/info/exclude`. Release Notes: - Fixed project search returning results from inside nested repositories that are excluded by the containing repository's `.git/info/exclude` file.
jolutz
pushed a commit
to jolutz/zed
that referenced
this pull request
Aug 8, 2026
# Objective Fixes zed-industries#61687 Prior to zed-industries#60772, an `abs_path` outside the `repo_root` would cause a panic. That PR changed it to return the `abs_path` itself, preventing the panic, but allowing all parents of `repo_root` to be subject to the global ignore. This is not what git itself does. ## Solution - This change returns `false` when the `abs_path` is outside the `root_repo`, preventing the panic but also not returning the `abs_path` ## Testing - One in-memory test - Manual test by building Zed and confirming the project pane changes (pictured below) ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase ### Before, with the bug <img width="1430" height="814" alt="Screenshot 2026-07-26 at 11 44 11 AM" src="https://github.com/user-attachments/assets/66e3bb95-4f45-4fd9-a1e4-e7f253f092eb" /> ### After the fix <img width="1568" height="1042" alt="Screenshot 2026-07-26 at 12 34 58 PM" src="https://github.com/user-attachments/assets/588eb01d-830a-4c22-93c0-667742de90b6" /> Release Notes: - Fixed the project panel's global gitignore incorrectly matching parent directories of a repository --------- Co-authored-by: dino <dinojoaocosta@gmail.com>
zed-zippy Bot
added a commit
that referenced
this pull request
Aug 11, 2026
… (cherry-pick to preview) (#62484) Cherry-pick of #62325 to preview ---- Since #60772, a worktree's ignore rules are also applied to the directories above its root. Because of this, an `info/exclude` pattern naming one of those parent directories marks it as ignored, and with it the whole worktree below. Stop the walk at the repository containing the worktree root. Also skip exclude rules for paths outside the work directory they are anchored at, as `.gitignore` and global gitignore rules already do. Release Notes: - Fixed a worktree being reported as entirely ignored when its repository's `info/exclude` named one of the worktree's parent directories Co-authored-by: Henrique Ferreiro <hferreiro@igalia.com>
playdohface
pushed a commit
to playdohface/zed
that referenced
this pull request
Aug 29, 2026
…ries#60772) # Objective - Fix ignored file search in nested Git directories (even just empty `.git` directories, not real git repositories) - Fixes zed-industries#52328 ## Solution Keep parent ignore rules when rebuilding a nested repository's ignore stack. This hides root-ignored files again after excluded-file search is turned off, without breaking global ignore handling. For example: ```ascii project/ ├── .git/ ├── .gitignore # log/ ├── app/ │ └── a.txt # hello └── log/ ├── .git/ # nested repository marker └── b.txt # hello ``` Both `a.txt` and `b.txt` have string `hello`. Initially, searching for `hello` returns only `a.txt`. Enabling `Also search files ignored by configuration` rescans `log/` and returns both files. Before this change, disabling the option still returned both files because the rescan dropped the parent `.gitignore` and marked `b.txt` as included. ## Testing - Did you test these changes? If so, how? To test changes in this pull request create a simple project with the following dir structure: ``` .git .gitignore a/a.txt b/b.txt b/.git # this is an empty directory ``` Add `b` folder as an ignore entry to the `.gitignore` file: `b/` - Are there any parts that need more testing? No - How can other people (reviewers) test your changes? Is there anything specific they need to know? Use the test scenario above - If relevant, what platforms did you test these changes on, and are there any important ones you can't test? macOS ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase By using the structure above here is how it works before changes here: https://github.com/user-attachments/assets/2028123e-388e-4390-b131-ddf4642ab5f3 Notice that `hello` string from file `b.txt` is listed in search results regardless of the option `Include excluded files` And here is after: https://github.com/user-attachments/assets/99c627a2-e16a-4fdd-979b-2e0bacbd827d Notice that `hello` string from file `b.txt` is **not** listed in search results when the option `Include excluded files` is disabled. Release Notes: - Fixed ignored file search in nested Git directories
playdohface
pushed a commit
to playdohface/zed
that referenced
this pull request
Aug 29, 2026
…ed-industries#61492) Closes TRA-162 When an entry's ignore stack is rebuilt from scratch (opening a file, file system events, a search that includes ignored files), `ignore_stack_for_abs_path` only consulted the `.git/info/exclude` rules of the nearest ancestor containing `.git`. For a path inside a nested repository, that nearest ancestor is the nested repository itself, so the outer repository's exclude rules were silently dropped: entries that were correctly ignored after the initial scan would flip to unignored the moment they were loaded or changed on disk, and from then on project search would surface them. This is the same class of bug that zed-industries#60772 fixed for ancestor `.gitignore` files — this change extends the fix to `info/exclude` by collecting the exclude rules of every containing repository (outermost first, mirroring how ancestor gitignores are stacked) instead of just the innermost one. Added a regression test that models the affected layout: a bare clone and a linked worktree of it kept inside the repository, hidden via anchored patterns in the outer repository's `.git/info/exclude`. Release Notes: - Fixed project search returning results from inside nested repositories that are excluded by the containing repository's `.git/info/exclude` file.
playdohface
pushed a commit
to playdohface/zed
that referenced
this pull request
Aug 29, 2026
# Objective Fixes zed-industries#61687 Prior to zed-industries#60772, an `abs_path` outside the `repo_root` would cause a panic. That PR changed it to return the `abs_path` itself, preventing the panic, but allowing all parents of `repo_root` to be subject to the global ignore. This is not what git itself does. ## Solution - This change returns `false` when the `abs_path` is outside the `root_repo`, preventing the panic but also not returning the `abs_path` ## Testing - One in-memory test - Manual test by building Zed and confirming the project pane changes (pictured below) ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase ### Before, with the bug <img width="1430" height="814" alt="Screenshot 2026-07-26 at 11 44 11 AM" src="https://github.com/user-attachments/assets/66e3bb95-4f45-4fd9-a1e4-e7f253f092eb" /> ### After the fix <img width="1568" height="1042" alt="Screenshot 2026-07-26 at 12 34 58 PM" src="https://github.com/user-attachments/assets/588eb01d-830a-4c22-93c0-667742de90b6" /> Release Notes: - Fixed the project panel's global gitignore incorrectly matching parent directories of a repository --------- Co-authored-by: dino <dinojoaocosta@gmail.com>
playdohface
pushed a commit
to playdohface/zed
that referenced
this pull request
Aug 29, 2026
…ndustries#62325) Since zed-industries#60772, a worktree's ignore rules are also applied to the directories above its root. Because of this, an `info/exclude` pattern naming one of those parent directories marks it as ignored, and with it the whole worktree below. Stop the walk at the repository containing the worktree root. Also skip exclude rules for paths outside the work directory they are anchored at, as `.gitignore` and global gitignore rules already do. Release Notes: - Fixed a worktree being reported as entirely ignored when its repository's `info/exclude` named one of the worktree's parent directories
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Objective
.gitdirectories, not real git repositories)Solution
Keep parent ignore rules when rebuilding a nested repository's ignore stack. This hides root-ignored files again after excluded-file search is turned off, without breaking global ignore handling.
For example:
Both
a.txtandb.txthave stringhello.Initially, searching for
helloreturns onlya.txt. EnablingAlso search files ignored by configurationrescanslog/and returns both files.Before this change, disabling the option still
returned both files because the rescan dropped the parent
.gitignoreand markedb.txtas included.Testing
Did you test these changes? If so, how?
To test changes in this pull request create a simple project with the following dir structure:
Add
bfolder as an ignore entry to the.gitignorefile:b/Are there any parts that need more testing?
No
How can other people (reviewers) test your changes? Is there anything specific they need to know?
Use the test scenario above
If relevant, what platforms did you test these changes on, and are there any important ones you can't test?
macOS
Self-Review Checklist:
Showcase
By using the structure above here is how it works before changes here:
CleanShot.2026-07-10.at.20.01.39.mp4
Notice that
hellostring from fileb.txtis listed in search results regardless of the optionInclude excluded filesAnd here is after:
CleanShot.2026-07-10.at.20.08.09.mp4
Notice that
hellostring from fileb.txtis not listed in search results when the optionInclude excluded filesis disabled.Release Notes: