Skip to content

Commit

Permalink
Avoid holding worktree lock for a long time while updating large repo…
Browse files Browse the repository at this point in the history
…s' git status (#12266)

Fixes #9575
Fixes #4294

### Problem

When a large git repository's `.git` folder changes (due to a `git
commit`, `git reset` etc), Zed needs to recompute the git status for
every file in that git repository. Part of computing the git status is
the *unstaged* part - the comparison between the content of the file and
the version in the git index. In a large git repository like `chromium`
or `linux`, this is inherently pretty slow.

Previously, we performed this git status all at once, and held a lock on
our `BackgroundScanner`'s state for the entire time. On my laptop, in
the `linux` repo, this would often take around 13 seconds.

When opening a file, Zed always refreshes the metadata for that file in
its in-memory snapshot of worktree. This is normally very fast, but if
another task is holding a lock on the `BackgroundScanner`, it blocks.

###  Solution

I've restructured how Zed handles Git statuses, so that when a git
repository is updated, we recompute files' git statuses in fixed-sized
batches. In between these batches, the `BackgroundScanner` is free to
perform other work, so that file operations coming from the main thread
will still be responsive.

Release Notes:

- Fixed a bug that caused long delays in opening files right after
performing a commit in very large git repositories.
  • Loading branch information
maxbrunsfeld authored May 25, 2024
1 parent 800c1ba commit f7a8696
Show file tree
Hide file tree
Showing 5 changed files with 384 additions and 450 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/project/src/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11014,7 +11014,7 @@ async fn search_ignored_entry(
}
} else if !fs_metadata.is_symlink {
if !query.file_matches(Some(&ignored_abs_path))
|| snapshot.is_path_excluded(ignored_entry.path.to_path_buf())
|| snapshot.is_path_excluded(&ignored_entry.path)
{
continue;
}
Expand Down
1 change: 1 addition & 0 deletions crates/worktree/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ util.workspace = true
[dev-dependencies]
clock = {workspace = true, features = ["test-support"]}
collections = { workspace = true, features = ["test-support"] }
env_logger.workspace = true
git2.workspace = true
gpui = {workspace = true, features = ["test-support"]}
http.workspace = true
Expand Down
Loading

0 comments on commit f7a8696

Please sign in to comment.