@@ -21,7 +21,6 @@ use text::LineEnding;
use std::collections::HashSet;
use std::ffi::{OsStr, OsString};
-use std::sync::atomic::AtomicBool;
use std::process::ExitStatus;
use std::str::FromStr;
@@ -934,9 +933,6 @@ pub trait GitRepository: Send + Sync {
) -> BoxFuture<'_, Result<()>>;
fn commit_data_reader(&self) -> Result<CommitDataReader>;
-
- fn set_trusted(&self, trusted: bool);
- fn is_trusted(&self) -> bool;
}
pub enum DiffType {
@@ -963,7 +959,6 @@ pub struct RealGitRepository {
pub any_git_binary_path: PathBuf,
any_git_binary_help_output: Arc<Mutex<Option<SharedString>>>,
executor: BackgroundExecutor,
- is_trusted: Arc<AtomicBool>,
}
impl RealGitRepository {
@@ -982,7 +977,6 @@ impl RealGitRepository {
any_git_binary_path,
executor,
any_git_binary_help_output: Arc::new(Mutex::new(None)),
- is_trusted: Arc::new(AtomicBool::new(false)),
})
}
@@ -994,24 +988,20 @@ impl RealGitRepository {
.map(Path::to_path_buf)
}
- fn git_binary(&self) -> Result<GitBinary> {
- Ok(GitBinary::new(
- self.any_git_binary_path.clone(),
- self.working_directory()
- .with_context(|| "Can't run git commands without a working directory")?,
- self.executor.clone(),
- self.is_trusted(),
- ))
- }
-
async fn any_git_binary_help_output(&self) -> SharedString {
if let Some(output) = self.any_git_binary_help_output.lock().clone() {
return output;
}
- let git_binary = self.git_binary();
+ let git_binary_path = self.any_git_binary_path.clone();
+ let executor = self.executor.clone();
+ let working_directory = self.working_directory();
let output: SharedString = self
.executor
- .spawn(async move { git_binary?.run(["help", "-a"]).await })
+ .spawn(async move {
+ GitBinary::new(git_binary_path, working_directory?, executor)
+ .run(["help", "-a"])
+ .await
+ })
.await
.unwrap_or_default()
.into();
@@ -1054,7 +1044,6 @@ pub async fn get_git_committer(cx: &AsyncApp) -> GitCommitter {
git_binary_path.unwrap_or(PathBuf::from("git")),
paths::home_dir().clone(),
cx.background_executor().clone(),
- true,
);
cx.background_spawn(async move {
@@ -1086,12 +1075,14 @@ impl GitRepository for RealGitRepository {
}
fn show(&self, commit: String) -> BoxFuture<'_, Result<CommitDetails>> {
- let git_binary = self.git_binary();
+ let git_binary_path = self.any_git_binary_path.clone();
+ let working_directory = self.working_directory();
self.executor
.spawn(async move {
- let git = git_binary?;
- let output = git
- .build_command([
+ let working_directory = working_directory?;
+ let output = new_command(git_binary_path)
+ .current_dir(&working_directory)
+ .args([
"--no-optional-locks",
"show",
"--no-patch",
@@ -1122,14 +1113,15 @@ impl GitRepository for RealGitRepository {
}
fn load_commit(&self, commit: String, cx: AsyncApp) -> BoxFuture<'_, Result<CommitDiff>> {
- if self.repository.lock().workdir().is_none() {
+ let Some(working_directory) = self.repository.lock().workdir().map(ToOwned::to_owned)
+ else {
return future::ready(Err(anyhow!("no working directory"))).boxed();
- }
- let git_binary = self.git_binary();
+ };
+ let git_binary_path = self.any_git_binary_path.clone();
cx.background_spawn(async move {
- let git = git_binary?;
- let show_output = git
- .build_command([
+ let show_output = util::command::new_command(&git_binary_path)
+ .current_dir(&working_directory)
+ .args([
"--no-optional-locks",
"show",
"--format=",
@@ -1150,8 +1142,9 @@ impl GitRepository for RealGitRepository {
let changes = parse_git_diff_name_status(&show_stdout);
let parent_sha = format!("{}^", commit);
- let mut cat_file_process = git
- .build_command(["--no-optional-locks", "cat-file", "--batch=%(objectsize)"])
+ let mut cat_file_process = util::command::new_command(&git_binary_path)
+ .current_dir(&working_directory)
+ .args(["--no-optional-locks", "cat-file", "--batch=%(objectsize)"])
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
@@ -1258,17 +1251,18 @@ impl GitRepository for RealGitRepository {
mode: ResetMode,
env: Arc<HashMap<String, String>>,
) -> BoxFuture<'_, Result<()>> {
- let git_binary = self.git_binary();
async move {
+ let working_directory = self.working_directory();
+
let mode_flag = match mode {
ResetMode::Mixed => "--mixed",
ResetMode::Soft => "--soft",
};
- let git = git_binary?;
- let output = git
- .build_command(["reset", mode_flag, &commit])
+ let output = new_command(&self.any_git_binary_path)
.envs(env.iter())
+ .current_dir(&working_directory?)
+ .args(["reset", mode_flag, &commit])
.output()
.await?;
anyhow::ensure!(
@@ -1287,16 +1281,17 @@ impl GitRepository for RealGitRepository {
paths: Vec<RepoPath>,
env: Arc<HashMap<String, String>>,
) -> BoxFuture<'_, Result<()>> {
- let git_binary = self.git_binary();
+ let working_directory = self.working_directory();
+ let git_binary_path = self.any_git_binary_path.clone();
async move {
if paths.is_empty() {
return Ok(());
}
- let git = git_binary?;
- let output = git
- .build_command(["checkout", &commit, "--"])
+ let output = new_command(&git_binary_path)
+ .current_dir(&working_directory?)
.envs(env.iter())
+ .args(["checkout", &commit, "--"])
.args(paths.iter().map(|path| path.as_unix_str()))
.output()
.await?;
@@ -1383,16 +1378,18 @@ impl GitRepository for RealGitRepository {
env: Arc<HashMap<String, String>>,
is_executable: bool,
) -> BoxFuture<'_, anyhow::Result<()>> {
- let git_binary = self.git_binary();
+ let working_directory = self.working_directory();
+ let git_binary_path = self.any_git_binary_path.clone();
self.executor
.spawn(async move {
- let git = git_binary?;
+ let working_directory = working_directory?;
let mode = if is_executable { "100755" } else { "100644" };
if let Some(content) = content {
- let mut child = git
- .build_command(["hash-object", "-w", "--stdin"])
+ let mut child = new_command(&git_binary_path)
+ .current_dir(&working_directory)
.envs(env.iter())
+ .args(["hash-object", "-w", "--stdin"])
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()?;
@@ -1405,9 +1402,10 @@ impl GitRepository for RealGitRepository {
log::debug!("indexing SHA: {sha}, path {path:?}");
- let output = git
- .build_command(["update-index", "--add", "--cacheinfo", mode, sha])
+ let output = new_command(&git_binary_path)
+ .current_dir(&working_directory)
.envs(env.iter())
+ .args(["update-index", "--add", "--cacheinfo", mode, sha])
.arg(path.as_unix_str())
.output()
.await?;
@@ -1419,9 +1417,10 @@ impl GitRepository for RealGitRepository {
);
} else {
log::debug!("removing path {path:?} from the index");
- let output = git
- .build_command(["update-index", "--force-remove"])
+ let output = new_command(&git_binary_path)
+ .current_dir(&working_directory)
.envs(env.iter())
+ .args(["update-index", "--force-remove"])
.arg(path.as_unix_str())
.output()
.await?;
@@ -1450,12 +1449,14 @@ impl GitRepository for RealGitRepository {
}
fn revparse_batch(&self, revs: Vec<String>) -> BoxFuture<'_, Result<Vec<Option<String>>>> {
- let git_binary = self.git_binary();
+ let working_directory = self.working_directory();
+ let git_binary_path = self.any_git_binary_path.clone();
self.executor
.spawn(async move {
- let git = git_binary?;
- let mut process = git
- .build_command([
+ let working_directory = working_directory?;
+ let mut process = new_command(&git_binary_path)
+ .current_dir(&working_directory)
+ .args([
"--no-optional-locks",
"cat-file",
"--batch-check=%(objectname)",
@@ -1508,14 +1509,19 @@ impl GitRepository for RealGitRepository {
}
fn status(&self, path_prefixes: &[RepoPath]) -> Task<Result<GitStatus>> {
- let git = match self.git_binary() {
- Ok(git) => git,
+ let git_binary_path = self.any_git_binary_path.clone();
+ let working_directory = match self.working_directory() {
+ Ok(working_directory) => working_directory,
Err(e) => return Task::ready(Err(e)),
};
let args = git_status_args(path_prefixes);
log::debug!("Checking for git status in {path_prefixes:?}");
self.executor.spawn(async move {
- let output = git.build_command(args).output().await?;
+ let output = new_command(&git_binary_path)
+ .current_dir(working_directory)
+ .args(args)
+ .output()
+ .await?;
if output.status.success() {
let stdout = String::from_utf8_lossy(&output.stdout);
stdout.parse()
@@ -1527,8 +1533,9 @@ impl GitRepository for RealGitRepository {
}
fn diff_tree(&self, request: DiffTreeType) -> BoxFuture<'_, Result<TreeDiff>> {
- let git = match self.git_binary() {
- Ok(git) => git,
+ let git_binary_path = self.any_git_binary_path.clone();
+ let working_directory = match self.working_directory() {
+ Ok(working_directory) => working_directory,
Err(e) => return Task::ready(Err(e)).boxed(),
};
@@ -1553,7 +1560,11 @@ impl GitRepository for RealGitRepository {
self.executor
.spawn(async move {
- let output = git.build_command(args).output().await?;
+ let output = new_command(&git_binary_path)
+ .current_dir(working_directory)
+ .args(args)
+ .output()
+ .await?;
if output.status.success() {
let stdout = String::from_utf8_lossy(&output.stdout);
stdout.parse()
@@ -1566,12 +1577,13 @@ impl GitRepository for RealGitRepository {
}
fn stash_entries(&self) -> BoxFuture<'_, Result<GitStash>> {
- let git_binary = self.git_binary();
+ let git_binary_path = self.any_git_binary_path.clone();
+ let working_directory = self.working_directory();
self.executor
.spawn(async move {
- let git = git_binary?;
- let output = git
- .build_command(&["stash", "list", "--pretty=format:%gd%x00%H%x00%ct%x00%s"])
+ let output = new_command(&git_binary_path)
+ .current_dir(working_directory?)
+ .args(&["stash", "list", "--pretty=format:%gd%x00%H%x00%ct%x00%s"])
.output()
.await?;
if output.status.success() {
@@ -1586,7 +1598,8 @@ impl GitRepository for RealGitRepository {
}
fn branches(&self) -> BoxFuture<'_, Result<Vec<Branch>>> {
- let git_binary = self.git_binary();
+ let working_directory = self.working_directory();
+ let git_binary_path = self.any_git_binary_path.clone();
self.executor
.spawn(async move {
let fields = [
@@ -1608,8 +1621,12 @@ impl GitRepository for RealGitRepository {
"--format",
&fields,
];
- let git = git_binary?;
- let output = git.build_command(args).output().await?;
+ let working_directory = working_directory?;
+ let output = new_command(&git_binary_path)
+ .current_dir(&working_directory)
+ .args(args)
+ .output()
+ .await?;
anyhow::ensure!(
output.status.success(),
@@ -1623,7 +1640,11 @@ impl GitRepository for RealGitRepository {
if branches.is_empty() {
let args = vec!["symbolic-ref", "--quiet", "HEAD"];
- let output = git.build_command(args).output().await?;
+ let output = new_command(&git_binary_path)
+ .current_dir(&working_directory)
+ .args(args)
+ .output()
+ .await?;
// git symbolic-ref returns a non-0 exit code if HEAD points
// to something other than a branch
@@ -1645,12 +1666,13 @@ impl GitRepository for RealGitRepository {
}
fn worktrees(&self) -> BoxFuture<'_, Result<Vec<Worktree>>> {
- let git_binary = self.git_binary();
+ let git_binary_path = self.any_git_binary_path.clone();
+ let working_directory = self.working_directory();
self.executor
.spawn(async move {
- let git = git_binary?;
- let output = git
- .build_command(&["--no-optional-locks", "worktree", "list", "--porcelain"])
+ let output = new_command(&git_binary_path)
+ .current_dir(working_directory?)
+ .args(&["--no-optional-locks", "worktree", "list", "--porcelain"])
.output()
.await?;
if output.status.success() {
@@ -1670,7 +1692,8 @@ impl GitRepository for RealGitRepository {
directory: PathBuf,
from_commit: Option<String>,
) -> BoxFuture<'_, Result<()>> {
- let git_binary = self.git_binary();
+ let git_binary_path = self.any_git_binary_path.clone();
+ let working_directory = self.working_directory();
let final_path = directory.join(&name);
let mut args = vec![
OsString::from("--no-optional-locks"),
@@ -1690,8 +1713,11 @@ impl GitRepository for RealGitRepository {
self.executor
.spawn(async move {
std::fs::create_dir_all(final_path.parent().unwrap_or(&final_path))?;
- let git = git_binary?;
- let output = git.build_command(args).output().await?;
+ let output = new_command(&git_binary_path)
+ .current_dir(working_directory?)
+ .args(args)
+ .output()
+ .await?;
if output.status.success() {
Ok(())
} else {
@@ -1703,7 +1729,9 @@ impl GitRepository for RealGitRepository {
}
fn remove_worktree(&self, path: PathBuf, force: bool) -> BoxFuture<'_, Result<()>> {
- let git_binary = self.git_binary();
+ let git_binary_path = self.any_git_binary_path.clone();
+ let working_directory = self.working_directory();
+ let executor = self.executor.clone();
self.executor
.spawn(async move {
@@ -1717,14 +1745,18 @@ impl GitRepository for RealGitRepository {
}
args.push("--".into());
args.push(path.as_os_str().into());
- git_binary?.run(args).await?;
+ GitBinary::new(git_binary_path, working_directory?, executor)
+ .run(args)
+ .await?;
anyhow::Ok(())
})
.boxed()
}
fn rename_worktree(&self, old_path: PathBuf, new_path: PathBuf) -> BoxFuture<'_, Result<()>> {
- let git_binary = self.git_binary();
+ let git_binary_path = self.any_git_binary_path.clone();
+ let working_directory = self.working_directory();
+ let executor = self.executor.clone();
self.executor
.spawn(async move {
@@ -1736,7 +1768,9 @@ impl GitRepository for RealGitRepository {
old_path.as_os_str().into(),
new_path.as_os_str().into(),
];
- git_binary?.run(args).await?;
+ GitBinary::new(git_binary_path, working_directory?, executor)
+ .run(args)
+ .await?;
anyhow::Ok(())
})
.boxed()
@@ -1744,7 +1778,9 @@ impl GitRepository for RealGitRepository {
fn change_branch(&self, name: String) -> BoxFuture<'_, Result<()>> {
let repo = self.repository.clone();
- let git_binary = self.git_binary();
+ let working_directory = self.working_directory();
+ let git_binary_path = self.any_git_binary_path.clone();
+ let executor = self.executor.clone();
let branch = self.executor.spawn(async move {
let repo = repo.lock();
let branch = if let Ok(branch) = repo.find_branch(&name, BranchType::Local) {
@@ -1779,7 +1815,9 @@ impl GitRepository for RealGitRepository {
self.executor
.spawn(async move {
let branch = branch.await?;
- git_binary?.run(&["checkout", &branch]).await?;
+ GitBinary::new(git_binary_path, working_directory?, executor)
+ .run(&["checkout", &branch])
+ .await?;
anyhow::Ok(())
})
.boxed()
@@ -1790,7 +1828,9 @@ impl GitRepository for RealGitRepository {
name: String,
base_branch: Option<String>,
) -> BoxFuture<'_, Result<()>> {
- let git_binary = self.git_binary();
+ let git_binary_path = self.any_git_binary_path.clone();
+ let working_directory = self.working_directory();
+ let executor = self.executor.clone();
self.executor
.spawn(async move {
@@ -1801,18 +1841,22 @@ impl GitRepository for RealGitRepository {
args.push(&base_branch_str);
}
- git_binary?.run(&args).await?;
+ GitBinary::new(git_binary_path, working_directory?, executor)
+ .run(&args)
+ .await?;
anyhow::Ok(())
})
.boxed()
}
fn rename_branch(&self, branch: String, new_name: String) -> BoxFuture<'_, Result<()>> {
- let git_binary = self.git_binary();
+ let git_binary_path = self.any_git_binary_path.clone();
+ let working_directory = self.working_directory();
+ let executor = self.executor.clone();
self.executor
.spawn(async move {
- git_binary?
+ GitBinary::new(git_binary_path, working_directory?, executor)
.run(&["branch", "-m", &branch, &new_name])
.await?;
anyhow::Ok(())
@@ -1821,11 +1865,15 @@ impl GitRepository for RealGitRepository {
}
fn delete_branch(&self, name: String) -> BoxFuture<'_, Result<()>> {
- let git_binary = self.git_binary();
+ let git_binary_path = self.any_git_binary_path.clone();
+ let working_directory = self.working_directory();
+ let executor = self.executor.clone();
self.executor
.spawn(async move {
- git_binary?.run(&["branch", "-d", &name]).await?;
+ GitBinary::new(git_binary_path, working_directory?, executor)
+ .run(&["branch", "-d", &name])
+ .await?;
anyhow::Ok(())
})
.boxed()
@@ -1837,11 +1885,20 @@ impl GitRepository for RealGitRepository {
content: Rope,
line_ending: LineEnding,
) -> BoxFuture<'_, Result<crate::blame::Blame>> {
- let git = self.git_binary();
+ let working_directory = self.working_directory();
+ let git_binary_path = self.any_git_binary_path.clone();
+ let executor = self.executor.clone();
- self.executor
+ executor
.spawn(async move {
- crate::blame::Blame::for_path(&git?, &path, &content, line_ending).await
+ crate::blame::Blame::for_path(
+ &git_binary_path,
+ &working_directory?,
+ &path,
+ &content,
+ line_ending,
+ )
+ .await
})
.boxed()
}
@@ -1856,10 +1913,11 @@ impl GitRepository for RealGitRepository {
skip: usize,
limit: Option<usize>,
) -> BoxFuture<'_, Result<FileHistory>> {
- let git_binary = self.git_binary();
+ let working_directory = self.working_directory();
+ let git_binary_path = self.any_git_binary_path.clone();
self.executor
.spawn(async move {
- let git = git_binary?;
+ let working_directory = working_directory?;
// Use a unique delimiter with a hardcoded UUID to separate commits
// This essentially eliminates any chance of encountering the delimiter in actual commit data
let commit_delimiter =
@@ -1887,8 +1945,9 @@ impl GitRepository for RealGitRepository {
args.push("--");
- let output = git
- .build_command(&args)
+ let output = new_command(&git_binary_path)
+ .current_dir(&working_directory)
+ .args(&args)
.arg(path.as_unix_str())
.output()
.await?;
@@ -1933,17 +1992,30 @@ impl GitRepository for RealGitRepository {
}
fn diff(&self, diff: DiffType) -> BoxFuture<'_, Result<String>> {
- let git_binary = self.git_binary();
+ let working_directory = self.working_directory();
+ let git_binary_path = self.any_git_binary_path.clone();
self.executor
.spawn(async move {
- let git = git_binary?;
+ let working_directory = working_directory?;
let output = match diff {
DiffType::HeadToIndex => {
- git.build_command(["diff", "--staged"]).output().await?
+ new_command(&git_binary_path)
+ .current_dir(&working_directory)
+ .args(["diff", "--staged"])
+ .output()
+ .await?
+ }
+ DiffType::HeadToWorktree => {
+ new_command(&git_binary_path)
+ .current_dir(&working_directory)
+ .args(["diff"])
+ .output()
+ .await?
}
- DiffType::HeadToWorktree => git.build_command(["diff"]).output().await?,
DiffType::MergeBase { base_ref } => {
- git.build_command(["diff", "--merge-base", base_ref.as_ref()])
+ new_command(&git_binary_path)
+ .current_dir(&working_directory)
+ .args(["diff", "--merge-base", base_ref.as_ref()])
.output()
.await?
}
@@ -1964,14 +2036,15 @@ impl GitRepository for RealGitRepository {
paths: Vec<RepoPath>,
env: Arc<HashMap<String, String>>,
) -> BoxFuture<'_, Result<()>> {
- let git_binary = self.git_binary();
+ let working_directory = self.working_directory();
+ let git_binary_path = self.any_git_binary_path.clone();
self.executor
.spawn(async move {
if !paths.is_empty() {
- let git = git_binary?;
- let output = git
- .build_command(["update-index", "--add", "--remove", "--"])
+ let output = new_command(&git_binary_path)
+ .current_dir(&working_directory?)
.envs(env.iter())
+ .args(["update-index", "--add", "--remove", "--"])
.args(paths.iter().map(|p| p.as_unix_str()))
.output()
.await?;
@@ -1991,15 +2064,16 @@ impl GitRepository for RealGitRepository {
paths: Vec<RepoPath>,
env: Arc<HashMap<String, String>>,
) -> BoxFuture<'_, Result<()>> {
- let git_binary = self.git_binary();
+ let working_directory = self.working_directory();
+ let git_binary_path = self.any_git_binary_path.clone();
self.executor
.spawn(async move {
if !paths.is_empty() {
- let git = git_binary?;
- let output = git
- .build_command(["reset", "--quiet", "--"])
+ let output = new_command(&git_binary_path)
+ .current_dir(&working_directory?)
.envs(env.iter())
+ .args(["reset", "--quiet", "--"])
.args(paths.iter().map(|p| p.as_std_path()))
.output()
.await?;
@@ -2020,16 +2094,19 @@ impl GitRepository for RealGitRepository {
paths: Vec<RepoPath>,
env: Arc<HashMap<String, String>>,
) -> BoxFuture<'_, Result<()>> {
- let git_binary = self.git_binary();
+ let working_directory = self.working_directory();
+ let git_binary_path = self.any_git_binary_path.clone();
self.executor
.spawn(async move {
- let git = git_binary?;
- let output = git
- .build_command(["stash", "push", "--quiet", "--include-untracked"])
+ let mut cmd = new_command(&git_binary_path);
+ cmd.current_dir(&working_directory?)
.envs(env.iter())
- .args(paths.iter().map(|p| p.as_unix_str()))
- .output()
- .await?;
+ .args(["stash", "push", "--quiet"])
+ .arg("--include-untracked");
+
+ cmd.args(paths.iter().map(|p| p.as_unix_str()));
+
+ let output = cmd.output().await?;
anyhow::ensure!(
output.status.success(),
@@ -2046,15 +2123,20 @@ impl GitRepository for RealGitRepository {
index: Option<usize>,
env: Arc<HashMap<String, String>>,
) -> BoxFuture<'_, Result<()>> {
- let git_binary = self.git_binary();
+ let working_directory = self.working_directory();
+ let git_binary_path = self.any_git_binary_path.clone();
self.executor
.spawn(async move {
- let git = git_binary?;
+ let mut cmd = new_command(git_binary_path);
let mut args = vec!["stash".to_string(), "pop".to_string()];
if let Some(index) = index {
args.push(format!("stash@{{{}}}", index));
}
- let output = git.build_command(&args).envs(env.iter()).output().await?;
+ cmd.current_dir(&working_directory?)
+ .envs(env.iter())
+ .args(args);
+
+ let output = cmd.output().await?;
anyhow::ensure!(
output.status.success(),
@@ -2071,15 +2153,20 @@ impl GitRepository for RealGitRepository {
index: Option<usize>,
env: Arc<HashMap<String, String>>,
) -> BoxFuture<'_, Result<()>> {
- let git_binary = self.git_binary();
+ let working_directory = self.working_directory();
+ let git_binary_path = self.any_git_binary_path.clone();
self.executor
.spawn(async move {
- let git = git_binary?;
+ let mut cmd = new_command(git_binary_path);
let mut args = vec!["stash".to_string(), "apply".to_string()];
if let Some(index) = index {
args.push(format!("stash@{{{}}}", index));
}
- let output = git.build_command(&args).envs(env.iter()).output().await?;
+ cmd.current_dir(&working_directory?)
+ .envs(env.iter())
+ .args(args);
+
+ let output = cmd.output().await?;
anyhow::ensure!(
output.status.success(),
@@ -2096,15 +2183,20 @@ impl GitRepository for RealGitRepository {
index: Option<usize>,
env: Arc<HashMap<String, String>>,
) -> BoxFuture<'_, Result<()>> {
- let git_binary = self.git_binary();
+ let working_directory = self.working_directory();
+ let git_binary_path = self.any_git_binary_path.clone();
self.executor
.spawn(async move {
- let git = git_binary?;
+ let mut cmd = new_command(git_binary_path);
let mut args = vec!["stash".to_string(), "drop".to_string()];
if let Some(index) = index {
args.push(format!("stash@{{{}}}", index));
}
- let output = git.build_command(&args).envs(env.iter()).output().await?;
+ cmd.current_dir(&working_directory?)
+ .envs(env.iter())
+ .args(args);
+
+ let output = cmd.output().await?;
anyhow::ensure!(
output.status.success(),
@@ -2124,14 +2216,16 @@ impl GitRepository for RealGitRepository {
ask_pass: AskPassDelegate,
env: Arc<HashMap<String, String>>,
) -> BoxFuture<'_, Result<()>> {
- let git_binary = self.git_binary();
+ let working_directory = self.working_directory();
+ let git_binary_path = self.any_git_binary_path.clone();
let executor = self.executor.clone();
// Note: Do not spawn this command on the background thread, it might pop open the credential helper
// which we want to block on.
async move {
- let git = git_binary?;
- let mut cmd = git.build_command(["commit", "--quiet", "-m"]);
- cmd.envs(env.iter())
+ let mut cmd = new_command(git_binary_path);
+ cmd.current_dir(&working_directory?)
+ .envs(env.iter())
+ .args(["commit", "--quiet", "-m"])
.arg(&message.to_string())
.arg("--cleanup=strip")
.arg("--no-verify")
@@ -2170,21 +2264,16 @@ impl GitRepository for RealGitRepository {
let working_directory = self.working_directory();
let executor = cx.background_executor().clone();
let git_binary_path = self.system_git_binary_path.clone();
- let is_trusted = self.is_trusted();
// Note: Do not spawn this command on the background thread, it might pop open the credential helper
// which we want to block on.
async move {
let git_binary_path = git_binary_path.context("git not found on $PATH, can't push")?;
let working_directory = working_directory?;
- let git = GitBinary::new(
- git_binary_path,
- working_directory,
- executor.clone(),
- is_trusted,
- );
- let mut command = git.build_command(["push"]);
+ let mut command = new_command(git_binary_path);
command
.envs(env.iter())
+ .current_dir(&working_directory)
+ .args(["push"])
.args(options.map(|option| match option {
PushOptions::SetUpstream => "--set-upstream",
PushOptions::Force => "--force-with-lease",
@@ -2212,20 +2301,15 @@ impl GitRepository for RealGitRepository {
let working_directory = self.working_directory();
let executor = cx.background_executor().clone();
let git_binary_path = self.system_git_binary_path.clone();
- let is_trusted = self.is_trusted();
// Note: Do not spawn this command on the background thread, it might pop open the credential helper
// which we want to block on.
async move {
let git_binary_path = git_binary_path.context("git not found on $PATH, can't pull")?;
- let working_directory = working_directory?;
- let git = GitBinary::new(
- git_binary_path,
- working_directory,
- executor.clone(),
- is_trusted,
- );
- let mut command = git.build_command(["pull"]);
- command.envs(env.iter());
+ let mut command = new_command(git_binary_path);
+ command
+ .envs(env.iter())
+ .current_dir(&working_directory?)
+ .arg("pull");
if rebase {
command.arg("--rebase");
@@ -2253,21 +2337,15 @@ impl GitRepository for RealGitRepository {
let remote_name = format!("{}", fetch_options);
let git_binary_path = self.system_git_binary_path.clone();
let executor = cx.background_executor().clone();
- let is_trusted = self.is_trusted();
// Note: Do not spawn this command on the background thread, it might pop open the credential helper
// which we want to block on.
async move {
let git_binary_path = git_binary_path.context("git not found on $PATH, can't fetch")?;
- let working_directory = working_directory?;
- let git = GitBinary::new(
- git_binary_path,
- working_directory,
- executor.clone(),
- is_trusted,
- );
- let mut command = git.build_command(["fetch", &remote_name]);
+ let mut command = new_command(git_binary_path);
command
.envs(env.iter())
+ .current_dir(&working_directory?)
+ .args(["fetch", &remote_name])
.stdout(Stdio::piped())
.stderr(Stdio::piped());
@@ -2277,12 +2355,14 @@ impl GitRepository for RealGitRepository {
}
fn get_push_remote(&self, branch: String) -> BoxFuture<'_, Result<Option<Remote>>> {
- let git_binary = self.git_binary();
+ let working_directory = self.working_directory();
+ let git_binary_path = self.any_git_binary_path.clone();
self.executor
.spawn(async move {
- let git = git_binary?;
- let output = git
- .build_command(["rev-parse", "--abbrev-ref"])
+ let working_directory = working_directory?;
+ let output = new_command(&git_binary_path)
+ .current_dir(&working_directory)
+ .args(["rev-parse", "--abbrev-ref"])
.arg(format!("{branch}@{{push}}"))
.output()
.await?;
@@ -2302,12 +2382,14 @@ impl GitRepository for RealGitRepository {
}
fn get_branch_remote(&self, branch: String) -> BoxFuture<'_, Result<Option<Remote>>> {
- let git_binary = self.git_binary();
+ let working_directory = self.working_directory();
+ let git_binary_path = self.any_git_binary_path.clone();
self.executor
.spawn(async move {
- let git = git_binary?;
- let output = git
- .build_command(["config", "--get"])
+ let working_directory = working_directory?;
+ let output = new_command(&git_binary_path)
+ .current_dir(&working_directory)
+ .args(["config", "--get"])
.arg(format!("branch.{branch}.remote"))
.output()
.await?;
@@ -2324,11 +2406,16 @@ impl GitRepository for RealGitRepository {
}
fn get_all_remotes(&self) -> BoxFuture<'_, Result<Vec<Remote>>> {
- let git_binary = self.git_binary();
+ let working_directory = self.working_directory();
+ let git_binary_path = self.any_git_binary_path.clone();
self.executor
.spawn(async move {
- let git = git_binary?;
- let output = git.build_command(["remote", "-v"]).output().await?;
+ let working_directory = working_directory?;
+ let output = new_command(&git_binary_path)
+ .current_dir(&working_directory)
+ .args(["remote", "-v"])
+ .output()
+ .await?;
anyhow::ensure!(
output.status.success(),
@@ -2377,12 +2464,17 @@ impl GitRepository for RealGitRepository {
}
fn check_for_pushed_commit(&self) -> BoxFuture<'_, Result<Vec<SharedString>>> {
- let git_binary = self.git_binary();
+ let working_directory = self.working_directory();
+ let git_binary_path = self.any_git_binary_path.clone();
self.executor
.spawn(async move {
- let git = git_binary?;
+ let working_directory = working_directory?;
let git_cmd = async |args: &[&str]| -> Result<String> {
- let output = git.build_command(args).output().await?;
+ let output = new_command(&git_binary_path)
+ .current_dir(&working_directory)
+ .args(args)
+ .output()
+ .await?;
anyhow::ensure!(
output.status.success(),
String::from_utf8_lossy(&output.stderr).to_string()
@@ -2431,10 +2523,14 @@ impl GitRepository for RealGitRepository {
}
fn checkpoint(&self) -> BoxFuture<'static, Result<GitRepositoryCheckpoint>> {
- let git_binary = self.git_binary();
+ let working_directory = self.working_directory();
+ let git_binary_path = self.any_git_binary_path.clone();
+ let executor = self.executor.clone();
self.executor
.spawn(async move {
- let mut git = git_binary?.envs(checkpoint_author_envs());
+ let working_directory = working_directory?;
+ let mut git = GitBinary::new(git_binary_path, working_directory.clone(), executor)
+ .envs(checkpoint_author_envs());
git.with_temp_index(async |git| {
let head_sha = git.run(&["rev-parse", "HEAD"]).await.ok();
let mut excludes = exclude_files(git).await?;
@@ -2460,10 +2556,15 @@ impl GitRepository for RealGitRepository {
}
fn restore_checkpoint(&self, checkpoint: GitRepositoryCheckpoint) -> BoxFuture<'_, Result<()>> {
- let git_binary = self.git_binary();
+ let working_directory = self.working_directory();
+ let git_binary_path = self.any_git_binary_path.clone();
+
+ let executor = self.executor.clone();
self.executor
.spawn(async move {
- let git = git_binary?;
+ let working_directory = working_directory?;
+
+ let git = GitBinary::new(git_binary_path, working_directory, executor);
git.run(&[
"restore",
"--source",
@@ -2494,10 +2595,14 @@ impl GitRepository for RealGitRepository {
left: GitRepositoryCheckpoint,
right: GitRepositoryCheckpoint,
) -> BoxFuture<'_, Result<bool>> {
- let git_binary = self.git_binary();
+ let working_directory = self.working_directory();
+ let git_binary_path = self.any_git_binary_path.clone();
+
+ let executor = self.executor.clone();
self.executor
.spawn(async move {
- let git = git_binary?;
+ let working_directory = working_directory?;
+ let git = GitBinary::new(git_binary_path, working_directory, executor);
let result = git
.run(&[
"diff-tree",
@@ -2528,10 +2633,14 @@ impl GitRepository for RealGitRepository {
base_checkpoint: GitRepositoryCheckpoint,
target_checkpoint: GitRepositoryCheckpoint,
) -> BoxFuture<'_, Result<String>> {
- let git_binary = self.git_binary();
+ let working_directory = self.working_directory();
+ let git_binary_path = self.any_git_binary_path.clone();
+
+ let executor = self.executor.clone();
self.executor
.spawn(async move {
- let git = git_binary?;
+ let working_directory = working_directory?;
+ let git = GitBinary::new(git_binary_path, working_directory, executor);
git.run(&[
"diff",
"--find-renames",
@@ -2548,10 +2657,14 @@ impl GitRepository for RealGitRepository {
&self,
include_remote_name: bool,
) -> BoxFuture<'_, Result<Option<SharedString>>> {
- let git_binary = self.git_binary();
+ let working_directory = self.working_directory();
+ let git_binary_path = self.any_git_binary_path.clone();
+
+ let executor = self.executor.clone();
self.executor
.spawn(async move {
- let git = git_binary?;
+ let working_directory = working_directory?;
+ let git = GitBinary::new(git_binary_path, working_directory, executor);
let strip_prefix = if include_remote_name {
"refs/remotes/"
@@ -2601,19 +2714,15 @@ impl GitRepository for RealGitRepository {
hook: RunHook,
env: Arc<HashMap<String, String>>,
) -> BoxFuture<'_, Result<()>> {
- let git_binary = self.git_binary();
+ let working_directory = self.working_directory();
let repository = self.repository.clone();
+ let git_binary_path = self.any_git_binary_path.clone();
+ let executor = self.executor.clone();
let help_output = self.any_git_binary_help_output();
// Note: Do not spawn these commands on the background thread, as this causes some git hooks to hang.
async move {
- let git = git_binary?;
-
- if !git.is_trusted {
- bail!("Can't run git commit hooks in restrictive workspace");
- }
-
- let working_directory = git.working_directory.clone();
+ let working_directory = working_directory?;
if !help_output
.await
.lines()
@@ -6,9 +6,6 @@ pub mod pending_op;
use crate::{
ProjectEnvironment, ProjectItem, ProjectPath,
buffer_store::{BufferStore, BufferStoreEvent},
- trusted_worktrees::{
- PathTrust, TrustedWorktrees, TrustedWorktreesEvent, TrustedWorktreesStore,
- },
worktree_store::{WorktreeStore, WorktreeStoreEvent},
};
use anyhow::{Context as _, Result, anyhow, bail};
@@ -346,7 +343,6 @@ impl LocalRepositoryState {
dot_git_abs_path: Arc<Path>,
project_environment: WeakEntity<ProjectEnvironment>,
fs: Arc<dyn Fs>,
- is_trusted: bool,
cx: &mut AsyncApp,
) -> anyhow::Result<Self> {
let environment = project_environment
@@ -374,7 +370,6 @@ impl LocalRepositoryState {
}
})
.await?;
- backend.set_trusted(is_trusted);
Ok(LocalRepositoryState {
backend,
environment: Arc::new(environment),
@@ -483,15 +478,11 @@ impl GitStore {
state: GitStoreState,
cx: &mut Context<Self>,
) -> Self {
- let mut _subscriptions = vec![
+ let _subscriptions = vec![
cx.subscribe(&worktree_store, Self::on_worktree_store_event),
cx.subscribe(&buffer_store, Self::on_buffer_store_event),
];
- if let Some(trusted_worktrees) = TrustedWorktrees::try_get_global(cx) {
- _subscriptions.push(cx.subscribe(&trusted_worktrees, Self::on_trusted_worktrees_event));
- }
-
GitStore {
state,
buffer_store,
@@ -1506,13 +1497,6 @@ impl GitStore {
} = update
{
let id = RepositoryId(next_repository_id.fetch_add(1, atomic::Ordering::Release));
- let is_trusted = TrustedWorktrees::try_get_global(cx)
- .map(|trusted_worktrees| {
- trusted_worktrees.update(cx, |trusted_worktrees, cx| {
- trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
- })
- })
- .unwrap_or(false);
let git_store = cx.weak_entity();
let repo = cx.new(|cx| {
let mut repo = Repository::local(
@@ -1521,7 +1505,6 @@ impl GitStore {
dot_git_abs_path.clone(),
project_environment.downgrade(),
fs.clone(),
- is_trusted,
git_store,
cx,
);
@@ -1562,39 +1545,6 @@ impl GitStore {
}
}
- fn on_trusted_worktrees_event(
- &mut self,
- _: Entity<TrustedWorktreesStore>,
- event: &TrustedWorktreesEvent,
- cx: &mut Context<Self>,
- ) {
- if !matches!(self.state, GitStoreState::Local { .. }) {
- return;
- }
-
- let (is_trusted, event_paths) = match event {
- TrustedWorktreesEvent::Trusted(_, trusted_paths) => (true, trusted_paths),
- TrustedWorktreesEvent::Restricted(_, restricted_paths) => (false, restricted_paths),
- };
-
- for (repo_id, worktree_ids) in &self.worktree_ids {
- if worktree_ids
- .iter()
- .any(|worktree_id| event_paths.contains(&PathTrust::Worktree(*worktree_id)))
- {
- if let Some(repo) = self.repositories.get(repo_id) {
- let repository_state = repo.read(cx).repository_state.clone();
- cx.background_spawn(async move {
- if let Ok(RepositoryState::Local(state)) = repository_state.await {
- state.backend.set_trusted(is_trusted);
- }
- })
- .detach();
- }
- }
- }
- }
-
fn on_buffer_store_event(
&mut self,
_: Entity<BufferStore>,
@@ -3743,13 +3693,6 @@ impl MergeDetails {
}
impl Repository {
- pub fn is_trusted(&self) -> bool {
- match self.repository_state.peek() {
- Some(Ok(RepositoryState::Local(state))) => state.backend.is_trusted(),
- _ => false,
- }
- }
-
pub fn snapshot(&self) -> RepositorySnapshot {
self.snapshot.clone()
}
@@ -3774,7 +3717,6 @@ impl Repository {
dot_git_abs_path: Arc<Path>,
project_environment: WeakEntity<ProjectEnvironment>,
fs: Arc<dyn Fs>,
- is_trusted: bool,
git_store: WeakEntity<GitStore>,
cx: &mut Context<Self>,
) -> Self {
@@ -3787,7 +3729,6 @@ impl Repository {
dot_git_abs_path,
project_environment,
fs,
- is_trusted,
cx,
)
.await