Directly parse .git when it's a file instead of using libgit2 (#27885)

Avoids building a whole git2 repository object at the worktree layer
just to watch some additional paths.

- [x] Tidy up names of the various paths
- [x] Tests for worktrees and submodules

Release Notes:

- N/A
This commit is contained in:
Cole Miller 2025-04-11 20:35:14 -04:00 committed by GitHub
parent 429d4580cf
commit 055df30757
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 401 additions and 160 deletions

View file

@ -21,11 +21,12 @@ pub struct FakeGitRepository {
pub(crate) fs: Arc<FakeFs>,
pub(crate) executor: BackgroundExecutor,
pub(crate) dot_git_path: PathBuf,
pub(crate) repository_dir_path: PathBuf,
pub(crate) common_dir_path: PathBuf,
}
#[derive(Debug, Clone)]
pub struct FakeGitRepositoryState {
pub path: PathBuf,
pub event_emitter: smol::channel::Sender<PathBuf>,
pub unmerged_paths: HashMap<RepoPath, UnmergedStatus>,
pub head_contents: HashMap<RepoPath, String>,
@ -37,9 +38,8 @@ pub struct FakeGitRepositoryState {
}
impl FakeGitRepositoryState {
pub fn new(path: PathBuf, event_emitter: smol::channel::Sender<PathBuf>) -> Self {
pub fn new(event_emitter: smol::channel::Sender<PathBuf>) -> Self {
FakeGitRepositoryState {
path,
event_emitter,
head_contents: Default::default(),
index_contents: Default::default(),
@ -53,15 +53,6 @@ impl FakeGitRepositoryState {
}
impl FakeGitRepository {
fn with_state<F, T>(&self, f: F) -> T
where
F: FnOnce(&mut FakeGitRepositoryState) -> T,
{
self.fs
.with_git_state(&self.dot_git_path, false, f)
.unwrap()
}
fn with_state_async<F, T>(&self, write: bool, f: F) -> BoxFuture<'static, Result<T>>
where
F: 'static + Send + FnOnce(&mut FakeGitRepositoryState) -> Result<T>,
@ -172,11 +163,11 @@ impl GitRepository for FakeGitRepository {
}
fn path(&self) -> PathBuf {
self.with_state(|state| state.path.clone())
self.repository_dir_path.clone()
}
fn main_repository_path(&self) -> PathBuf {
self.path()
self.common_dir_path.clone()
}
fn merge_message(&self) -> BoxFuture<Option<String>> {
@ -207,8 +198,9 @@ impl GitRepository for FakeGitRepository {
.files()
.iter()
.filter_map(|path| {
// TODO better simulate git status output in the case of submodules and worktrees
let repo_path = path.strip_prefix(workdir_path).ok()?;
let mut is_ignored = false;
let mut is_ignored = repo_path.starts_with(".git");
for ignore in &ignores {
match ignore.matched_path_or_any_parents(path, false) {
ignore::Match::None => {}