zed-industries/zed · error
git diff-tree failed: {stderr}
Error message
git diff-tree failed: {stderr} What it means
While computing a tree diff for a comparison, the code runs `git diff-tree` between a base ref and HEAD; a non-zero exit surfaces git's stderr here. As with all such wrappers, the real cause is in the appended stderr text.
Source
Thrown at crates/git/src/repository.rs:1909
.boxed()
}
fn status(&self, path_prefixes: &[RepoPath]) -> Task<Result<GitStatus>> {
let git = self.git_binary_in_worktree();
let args = git_status_args(path_prefixes);
log::debug!("Checking for git status in {path_prefixes:?}");
self.executor.spawn(async move {
let git = git?;
let output = git.build_command(&args).output().await?;
if output.status.success() {
let stdout = String::from_utf8_lossy(&output.stdout);
stdout.parse()
} else {
let stderr = String::from_utf8_lossy(&output.stderr);
anyhow::bail!("git status failed: {stderr}");
}
})
}
fn check_access(&self) -> BoxFuture<'_, Result<()>> {
let git = self.git_binary_in_worktree();
self.executor
.spawn(async move {
git?.run(&["rev-parse"]).await?;
Ok(())
})
.boxed()
}
fn diff_tree(&self, request: DiffTreeType) -> BoxFuture<'_, Result<TreeDiff>> {
let git = self.git_binary_in_worktree();
let working_directory = self.working_directory.clone();
let merge_base_ref = match &request {
DiffTreeType::MergeBaseWithWorktree { base } => Some(base.clone()),
DiffTreeType::MergeBase { .. } | DiffTreeType::Since { .. } => None,
};View on GitHub (pinned to 5a9b9558db)
Solutions
- Check the appended stderr for the failing revision name.
- Treat unborn HEAD as an empty diff and skip the diff-tree call until the first commit exists.
- Validate the base ref resolves: `git rev-parse --verify <base_ref>`.
- If stderr says `bad object`, run `git fsck`; re-clone if the object store is damaged.
Defensive patterns
Strategy: try-catch
Validate before calling
// skip diffs while HEAD is unborn (repo with no commits)
if git.run(&["rev-parse", "--verify", "--quiet", "HEAD"]).await.is_err() {
return Ok(TreeDiff::default());
} Try / catch
match repo.diff_for_paths(..).await {
Err(e) if e.to_string().contains("diff-tree failed") && e.to_string().contains("bad revision HEAD") => {
Ok(TreeDiff::default()) // unborn branch: no diff yet
}
other => other?,
} Prevention
- Guard comparisons with a HEAD-exists check before requesting diffs against HEAD.
- Validate the compare/base ref resolves before starting the diff.
- Re-clone interrupted clones instead of diffing a partially written object store.
When it happens
Trigger: `git diff-tree ... HEAD` fails when HEAD is unborn (a fresh repo or new branch with zero commits yields `fatal: bad revision HEAD`), when the base/merge-base ref does not resolve, when the object database is corrupt (`fatal: bad object`), or on repository permission problems.
Common situations: Opening comparisons on a brand-new repository with no initial commit; comparing against a ref that was deleted or pruned; interrupted clones leaving a broken object store; worktrees created from an empty branch.
Understand the failure class
Background: "git command failed": what it means when a tool shells out to git and git exits non-zero — this error's family across 21 libraries.
Related errors
- git status failed: {stderr}
- git merge-base failed: {stderr}
- git worktree list failed: {stderr}
- git worktree add failed: {stderr}
- git log command failed with {}: {}
AI-assisted analysis of zed-industries/zed@5a9b9558db (2026-08-20).
Data as JSON: /api/errors/1307dabd7050eb10.
Report an issue: GitHub.