From e7172681b2dc8a60c04500fc6513bd1f0dcee431 Mon Sep 17 00:00:00 2001 From: Anthony Eid <56899983+Anthony-Eid@users.noreply.github.com> Date: Wed, 4 Mar 2026 22:37:25 +0100 Subject: [PATCH] git: Allow committing in restrictive worktrees (#50749) follow up on: https://github.com/zed-industries/zed/pull/50649 When committing in a restrictive workspace we avoid running git hooks instead of failing the commit because hooks aren't allowed. I also passed in more git cli hardening configurations to use when Zed spawns git commands Before you mark this PR as ready for review, make sure that you have: - [ ] Added a solid test coverage and/or screenshots from doing manual testing - [x] Done a self-review taking into account security and performance aspects - [ ] Aligned any UI changes with the [UI checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) Release Notes: - N/A --- crates/git/src/repository.rs | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/crates/git/src/repository.rs b/crates/git/src/repository.rs index c36c70935522836eeea4a83a889109dc807604c8..45e719fb6d5a586074de523b5974ee11bf225453 100644 --- a/crates/git/src/repository.rs +++ b/crates/git/src/repository.rs @@ -2673,20 +2673,16 @@ impl GitRepository for RealGitRepository { // 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 git_binary = git_binary?; - let working_directory = git.working_directory.clone(); + let working_directory = git_binary.working_directory.clone(); if !help_output .await .lines() .any(|line| line.trim().starts_with("hook ")) { let hook_abs_path = repository.lock().path().join("hooks").join(hook.as_str()); - if hook_abs_path.is_file() { + if hook_abs_path.is_file() && git_binary.is_trusted { #[allow(clippy::disallowed_methods)] let output = new_command(&hook_abs_path) .envs(env.iter()) @@ -2707,9 +2703,12 @@ impl GitRepository for RealGitRepository { return Ok(()); } - let git = git.envs(HashMap::clone(&env)); - git.run(&["hook", "run", "--ignore-missing", hook.as_str()]) - .await?; + if git_binary.is_trusted { + let git_binary = git_binary.envs(HashMap::clone(&env)); + git_binary + .run(&["hook", "run", "--ignore-missing", hook.as_str()]) + .await?; + } Ok(()) } .boxed() @@ -3116,8 +3115,14 @@ impl GitBinary { let mut command = new_command(&self.git_binary_path); command.current_dir(&self.working_directory); command.args(["-c", "core.fsmonitor=false"]); + command.arg("--no-pager"); + if !self.is_trusted { command.args(["-c", "core.hooksPath=/dev/null"]); + command.args(["-c", "core.sshCommand=ssh"]); + command.args(["-c", "credential.helper="]); + command.args(["-c", "protocol.ext.allow=never"]); + command.args(["-c", "diff.external="]); } command.args(args); if let Some(index_file_path) = self.index_file_path.as_ref() {