git_ui: Fix indent guide rendering in tree view with collapsed folders (#48194)

The indent guide computation was using visible list indices directly to
access entries, instead of mapping through `logical_indices` first. This
caused incorrect depths to be read from hidden entries when a folder was
collapsed, resulting in stray vertical lines extending to unrelated folders.

Closes #48189 

Release Notes:

- Fixed a visual bug in the Git Panel where collapsing a folder in tree
view would cause indent guide lines to incorrectly extend to unrelated
folders below it.
This commit is contained in:
Dino authored and GitHub committed 2026-02-02 16:54:41 +00:00
1 parent b0040c7743
commit b27e8d88f1
3 files changed
+31 -9

No files matched your search

Generated
+1
View File
@@ -7303,6 +7303,7 @@ dependencies = [
"serde",
"serde_json",
"settings",
"smallvec",
"smol",
"strum 0.27.2",
"telemetry",
+1
View File
@@ -51,6 +51,7 @@ schemars.workspace = true
serde.workspace = true
serde_json.workspace = true
settings.workspace = true
smallvec.workspace = true
smol.workspace = true
strum.workspace = true
telemetry.workspace = true
+29 -9
View File
@@ -57,6 +57,7 @@ use project::{
use prompt_store::{BuiltInPrompt, PromptId, PromptStore, RULES_FILE_NAMES};
use serde::{Deserialize, Serialize};
use settings::{Settings, SettingsStore, StatusStyle};
use smallvec::SmallVec;
use std::future::Future;
use std::ops::Range;
use std::path::Path;
@@ -290,6 +291,15 @@ impl GitListEntry {
_ => None,
}
}
/// Returns the tree indentation depth for this entry.
fn depth(&self) -> usize {
match self {
GitListEntry::Directory(dir) => dir.depth,
GitListEntry::TreeStatus(status) => status.depth,
_ => 0,
}
}
}
enum GitPanelViewMode {
@@ -3806,6 +3816,24 @@ impl GitPanel {
self.has_staged_changes()
}
/// Computes tree indentation depths for visible entries in the given range.
/// Used by indent guides to render vertical connector lines in tree view.
fn compute_visible_depths(&self, range: Range<usize>) -> SmallVec<[usize; 64]> {
let GitPanelViewMode::Tree(state) = &self.view_mode else {
return SmallVec::new();
};
range
.map(|ix| {
state
.logical_indices
.get(ix)
.and_then(|&entry_ix| self.entries.get(entry_ix))
.map_or(0, |entry| entry.depth())
})
.collect()
}
fn status_width_estimate(
tree_view: bool,
entry: &GitStatusEntry,
@@ -4683,15 +4711,7 @@ impl GitPanel {
.with_compute_indents_fn(
cx.entity(),
|this, range, _window, _cx| {
range
.map(|ix| match this.entries.get(ix) {
Some(GitListEntry::Directory(dir)) => dir.depth,
Some(GitListEntry::TreeStatus(status)) => {
status.depth
}
_ => 0,
})
.collect()
this.compute_visible_depths(range)
},
)
.with_render_fn(cx.entity(), |_, params, _, _| {