From ae6d3503348fcff36831367f02ebd06d368f3e01 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Sun, 2 Mar 2025 17:31:47 -0800 Subject: [PATCH] Use system-installed git binary for push/pull/fetch (#25900) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Problem When using HTTPS remotes, users are getting errors when trying to push or pull via the git panel. On macOS, Zed bundles a `git` binary that's part of [`dugite-native`](https://github.com/desktop/dugite-native). But we don't include the entire package. Additional binaries from `dugite-native` are needed for pulling and pushing over HTTPS. ### Solution Rather than bundling those additional binaries, I've changed the `push`, `pull`, and `fetch` actions to rely on the *system-installed* `git` binary. The downside of this is that, if the user does not have Git installed, they wont' be able to push, pull, or fetch from within Zed. But we believe that the vast majority of users will have Git installed. Also, unlike `diff` and `status`, which Zed needs to call in the background without any user interaction, `push`/`pull` and `fetch` are explicit actions that the user takes in Zed, so there is an opportunity to prompt them to install Git if they haven't. ### Background There are three ways (that I know of) that users might authenticate when pushing, pulling, or fetching over HTTPS. 1. Via a built-in [Git `credential.helper`](https://git-scm.com/docs/gitcredentials). On macOS, Git ships with a helper called `credential-osxkeychain` that stores internet passwords in the OS Keychain. You can opt into this globally with the command `git config --global credential.helper osxkeychain`, which writes to your `~/.gitconfig`. 2. Via [`Git Credential Manager` (GCM)](https://github.com/git-ecosystem/git-credential-manager), which is a different `credential.helper`, [built by GitHub](https://github.blog/security/application-security/git-credential-manager-authentication-for-everyone/), which must be installed manually, and integrates with specific Git hosting providers like GitHub and Azure. 3. By typing their Username and Password/Access-token interactively when pushing/pulling/fetching. ### Testing Status * [ ] 🚫 Interactive password auth - not yet supported, requires https://github.com/zed-industries/zed/pull/25848 * [x] **credential-osxkeychain** - when using the built-in credential helper, and the credentials are already stored in the keychain, push/pull/fetch now work fine . * [ ] **GCM** - still testing. * Right now, I'm seeing `git-credential-manager` just hang indefinitely when pushing from Zed, even though it works when pushing from a terminal. Release Notes: - N/A --- crates/git/src/repository.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/git/src/repository.rs b/crates/git/src/repository.rs index c2c5173fa11d4e83ea8052cf889ae335f45724e8..b690887ca1fa392de24dc851f027c6e254ed313f 100644 --- a/crates/git/src/repository.rs +++ b/crates/git/src/repository.rs @@ -614,7 +614,7 @@ impl GitRepository for RealGitRepository { ) -> Result<()> { let working_directory = self.working_directory()?; - let output = new_std_command(&self.git_binary_path) + let output = new_std_command("git") .current_dir(&working_directory) .args(["push", "--quiet"]) .args(options.map(|option| match option { @@ -638,7 +638,7 @@ impl GitRepository for RealGitRepository { fn pull(&self, branch_name: &str, remote_name: &str) -> Result<()> { let working_directory = self.working_directory()?; - let output = new_std_command(&self.git_binary_path) + let output = new_std_command("git") .current_dir(&working_directory) .args(["pull", "--quiet"]) .arg(remote_name) @@ -658,7 +658,7 @@ impl GitRepository for RealGitRepository { fn fetch(&self) -> Result<()> { let working_directory = self.working_directory()?; - let output = new_std_command(&self.git_binary_path) + let output = new_std_command("git") .current_dir(&working_directory) .args(["fetch", "--quiet", "--all"]) .output()?;