git: Skip directories in git status output (#23300)

The output of `git status --porcelain=v1` includes untracked
directories, i.e. directories that have no tracked files beneath. Since
we have our own way of computing a "summary" status for each directory
in a repo, this is not helpful for Zed; and it interferes with our
handling of nested repos. So just skip these lines in the output.

Closes #23133 

Release Notes:

- Fix project panel colors when one git repository is nested beneath
another
This commit is contained in:
Cole Miller 2025-01-20 13:57:19 -05:00 committed by GitHub
parent 5f59536208
commit fed4b48c57
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -421,15 +421,15 @@ impl GitStatus {
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.map_err(|e| anyhow!("Failed to start git status process: {}", e))?;
.map_err(|e| anyhow!("Failed to start git status process: {e}"))?;
let output = child
.wait_with_output()
.map_err(|e| anyhow!("Failed to read git blame output: {}", e))?;
.map_err(|e| anyhow!("Failed to read git status output: {e}"))?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
return Err(anyhow!("git status process failed: {}", stderr));
return Err(anyhow!("git status process failed: {stderr}"));
}
let stdout = String::from_utf8_lossy(&output.stdout);
let mut entries = stdout
@ -440,6 +440,13 @@ impl GitStatus {
return None;
};
let path = &entry[3..];
// The git status output includes untracked directories as well as untracked files.
// We do our own processing to compute the "summary" status of each directory,
// so just skip any directories in the output, since they'll otherwise interfere
// with our handling of nested repositories.
if path.ends_with('/') {
return None;
}
let status = entry[0..2].as_bytes().try_into().unwrap();
let status = FileStatus::from_bytes(status).log_err()?;
let path = RepoPath(Path::new(path).into());