diff --git a/crates/git/src/repository.rs b/crates/git/src/repository.rs index d67086d20e2ea3e5b38b1fdb4c0bcb52dc9b4126..e868fb22343fd43d88c5432f11e7bf1f6e6ab728 100644 --- a/crates/git/src/repository.rs +++ b/crates/git/src/repository.rs @@ -943,6 +943,7 @@ impl RealGitRepository { self.any_git_binary_path.clone(), self.working_directory() .with_context(|| "Can't run git commands without a working directory")?, + self.path(), self.executor.clone(), self.is_trusted(), )) @@ -997,6 +998,7 @@ pub async fn get_git_committer(cx: &AsyncApp) -> GitCommitter { let git = GitBinary::new( git_binary_path.unwrap_or(PathBuf::from("git")), paths::home_dir().clone(), + paths::home_dir().join(".git"), cx.background_executor().clone(), true, ); @@ -2154,6 +2156,7 @@ impl GitRepository for RealGitRepository { cx: AsyncApp, ) -> BoxFuture<'_, Result> { let working_directory = self.working_directory(); + let git_directory = self.path(); let executor = cx.background_executor().clone(); let git_binary_path = self.system_git_binary_path.clone(); let is_trusted = self.is_trusted(); @@ -2165,6 +2168,7 @@ impl GitRepository for RealGitRepository { let git = GitBinary::new( git_binary_path, working_directory, + git_directory, executor.clone(), is_trusted, ); @@ -2196,6 +2200,7 @@ impl GitRepository for RealGitRepository { cx: AsyncApp, ) -> BoxFuture<'_, Result> { let working_directory = self.working_directory(); + let git_directory = self.path(); let executor = cx.background_executor().clone(); let git_binary_path = self.system_git_binary_path.clone(); let is_trusted = self.is_trusted(); @@ -2207,6 +2212,7 @@ impl GitRepository for RealGitRepository { let git = GitBinary::new( git_binary_path, working_directory, + git_directory, executor.clone(), is_trusted, ); @@ -2236,6 +2242,7 @@ impl GitRepository for RealGitRepository { cx: AsyncApp, ) -> BoxFuture<'_, Result> { let working_directory = self.working_directory(); + let git_directory = self.path(); let remote_name = format!("{}", fetch_options); let git_binary_path = self.system_git_binary_path.clone(); let executor = cx.background_executor().clone(); @@ -2248,6 +2255,7 @@ impl GitRepository for RealGitRepository { let git = GitBinary::new( git_binary_path, working_directory, + git_directory, executor.clone(), is_trusted, ); @@ -2900,6 +2908,7 @@ async fn exclude_files(git: &GitBinary) -> Result { pub(crate) struct GitBinary { git_binary_path: PathBuf, working_directory: PathBuf, + git_directory: PathBuf, executor: BackgroundExecutor, index_file_path: Option, envs: HashMap, @@ -2910,12 +2919,14 @@ impl GitBinary { pub(crate) fn new( git_binary_path: PathBuf, working_directory: PathBuf, + git_directory: PathBuf, executor: BackgroundExecutor, is_trusted: bool, ) -> Self { Self { git_binary_path, working_directory, + git_directory, executor, index_file_path: None, envs: HashMap::default(), @@ -2961,12 +2972,9 @@ impl GitBinary { // Copy the default index file so that Git doesn't have to rebuild the // whole index from scratch. This might fail if this is an empty repository. - smol::fs::copy( - self.working_directory.join(".git").join("index"), - &index_file_path, - ) - .await - .ok(); + smol::fs::copy(self.git_directory.join("index"), &index_file_path) + .await + .ok(); self.index_file_path = Some(index_file_path.clone()); let result = f(self).await; @@ -2980,19 +2988,13 @@ impl GitBinary { } pub async fn with_exclude_overrides(&self) -> Result { - let path = self - .working_directory - .join(".git") - .join("info") - .join("exclude"); + let path = self.git_directory.join("info").join("exclude"); GitExcludeOverride::new(path).await } fn path_for_index_id(&self, id: Uuid) -> PathBuf { - self.working_directory - .join(".git") - .join(format!("index-{}.tmp", id)) + self.git_directory.join(format!("index-{}.tmp", id)) } pub async fn run(&self, args: &[S]) -> Result @@ -3317,6 +3319,7 @@ mod tests { let git = GitBinary::new( PathBuf::from("git"), dir.path().to_path_buf(), + dir.path().join(".git"), cx.executor(), false, ); @@ -3330,6 +3333,7 @@ mod tests { let git = GitBinary::new( PathBuf::from("git"), dir.path().to_path_buf(), + dir.path().join(".git"), cx.executor(), false, ); @@ -3349,6 +3353,7 @@ mod tests { let git = GitBinary::new( PathBuf::from("git"), dir.path().to_path_buf(), + dir.path().join(".git"), cx.executor(), false, ); @@ -3374,6 +3379,7 @@ mod tests { let git = GitBinary::new( PathBuf::from("git"), dir.path().to_path_buf(), + dir.path().join(".git"), cx.executor(), true, ); @@ -3392,6 +3398,7 @@ mod tests { let git = GitBinary::new( PathBuf::from("git"), dir.path().to_path_buf(), + dir.path().join(".git"), cx.executor(), true, ); @@ -3406,6 +3413,27 @@ mod tests { ); } + #[gpui::test] + async fn test_path_for_index_id_uses_real_git_directory(cx: &mut TestAppContext) { + cx.executor().allow_parking(); + let working_directory = PathBuf::from("/code/worktree"); + let git_directory = PathBuf::from("/code/repo/.git/modules/worktree"); + let git = GitBinary::new( + PathBuf::from("git"), + working_directory, + git_directory.clone(), + cx.executor(), + false, + ); + + let path = git.path_for_index_id(Uuid::nil()); + + assert_eq!( + path, + git_directory.join(format!("index-{}.tmp", Uuid::nil())) + ); + } + #[gpui::test] async fn test_checkpoint_basic(cx: &mut TestAppContext) { disable_git_global_config(); @@ -4090,13 +4118,20 @@ mod tests { /// Force a Git garbage collection on the repository. fn gc(&self) -> BoxFuture<'_, Result<()>> { let working_directory = self.working_directory(); + let git_directory = self.path(); let git_binary_path = self.any_git_binary_path.clone(); let executor = self.executor.clone(); self.executor .spawn(async move { let git_binary_path = git_binary_path.clone(); let working_directory = working_directory?; - let git = GitBinary::new(git_binary_path, working_directory, executor, true); + let git = GitBinary::new( + git_binary_path, + working_directory, + git_directory, + executor, + true, + ); git.run(&["gc", "--prune"]).await?; Ok(()) })