From 495612be2ea2da0e698aa96c3e407db8c86ced09 Mon Sep 17 00:00:00 2001 From: Cole Miller Date: Mon, 3 Mar 2025 23:20:41 -0500 Subject: [PATCH] Revert "git: Use worktree paths in the panel (#25950)" (#25995) This reverts commit e7b3b8bf03f5f8693f8c330b98b656b16ab8f931. Release Notes: - N/A --- Cargo.lock | 1 - crates/git_ui/Cargo.toml | 1 - crates/git_ui/src/git_panel.rs | 321 ++++++++++----------------------- crates/zed/src/zed.rs | 6 +- 4 files changed, 96 insertions(+), 233 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fb26340d0f..b2bcec6ee0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5439,7 +5439,6 @@ dependencies = [ "panel", "picker", "postage", - "pretty_assertions", "project", "schemars", "serde", diff --git a/crates/git_ui/Cargo.toml b/crates/git_ui/Cargo.toml index 7af228bcdb..fc5f777da2 100644 --- a/crates/git_ui/Cargo.toml +++ b/crates/git_ui/Cargo.toml @@ -61,7 +61,6 @@ ctor.workspace = true env_logger.workspace = true editor = { workspace = true, features = ["test-support"] } gpui = { workspace = true, features = ["test-support"] } -pretty_assertions.workspace = true project = { workspace = true, features = ["test-support"] } settings = { workspace = true, features = ["test-support"] } unindent.workspace = true diff --git a/crates/git_ui/src/git_panel.rs b/crates/git_ui/src/git_panel.rs index 8caed2fc11..9f8dfe4d27 100644 --- a/crates/git_ui/src/git_panel.rs +++ b/crates/git_ui/src/git_panel.rs @@ -18,14 +18,7 @@ use git::repository::{ }; use git::{repository::RepoPath, status::FileStatus, Commit, ToggleStaged}; use git::{RestoreTrackedFiles, StageAll, TrashUntrackedFiles, UnstageAll}; -use gpui::{ - actions, anchored, deferred, hsla, percentage, point, uniform_list, Action, Animation, - AnimationExt as _, AnyView, BoxShadow, ClickEvent, Corner, DismissEvent, Entity, EventEmitter, - FocusHandle, Focusable, KeyContext, ListHorizontalSizingBehavior, ListSizingBehavior, - Modifiers, ModifiersChangedEvent, MouseButton, MouseDownEvent, Point, PromptLevel, - ScrollStrategy, Stateful, Subscription, Task, Transformation, UniformListScrollHandle, - WeakEntity, -}; +use gpui::*; use itertools::Itertools; use language::{Buffer, File}; use menu::{Confirm, SecondaryConfirm, SelectFirst, SelectLast, SelectNext, SelectPrevious}; @@ -42,7 +35,6 @@ use settings::Settings as _; use smallvec::smallvec; use std::cell::RefCell; use std::future::Future; -use std::path::Path; use std::rc::Rc; use std::{collections::HashSet, sync::Arc, time::Duration, usize}; use strum::{IntoEnumIterator, VariantNames}; @@ -52,7 +44,6 @@ use ui::{ Scrollbar, ScrollbarState, Tooltip, }; use util::{maybe, post_inc, ResultExt, TryFutureExt}; -use workspace::AppState; use workspace::{ dock::{DockPosition, Panel, PanelEvent}, @@ -72,12 +63,7 @@ actions!( ] ); -fn prompt( - msg: &str, - detail: Option<&str>, - window: &mut Window, - cx: &mut App, -) -> Task> +fn prompt(msg: &str, detail: Option<&str>, window: &mut Window, cx: &mut App) -> Task> where T: IntoEnumIterator + VariantNames + 'static, { @@ -179,7 +165,6 @@ impl GitListEntry { #[derive(Debug, PartialEq, Eq, Clone)] pub struct GitStatusEntry { pub(crate) repo_path: RepoPath, - pub(crate) worktree_path: Arc, pub(crate) status: FileStatus, pub(crate) is_staged: Option, } @@ -277,94 +262,96 @@ pub(crate) fn commit_message_editor( impl GitPanel { pub fn new( - workspace: Entity, - project: Entity, - app_state: Arc, + workspace: &mut Workspace, window: &mut Window, - cx: &mut Context, - ) -> Self { - let fs = app_state.fs.clone(); + cx: &mut Context, + ) -> Entity { + let fs = workspace.app_state().fs.clone(); + let project = workspace.project().clone(); let git_store = project.read(cx).git_store().clone(); let active_repository = project.read(cx).active_repository(cx); - let workspace = workspace.downgrade(); + let workspace = cx.entity().downgrade(); - let focus_handle = cx.focus_handle(); - cx.on_focus(&focus_handle, window, Self::focus_in).detach(); - cx.on_focus_out(&focus_handle, window, |this, _, window, cx| { - this.hide_scrollbar(window, cx); + cx.new(|cx| { + let focus_handle = cx.focus_handle(); + cx.on_focus(&focus_handle, window, Self::focus_in).detach(); + cx.on_focus_out(&focus_handle, window, |this, _, window, cx| { + this.hide_scrollbar(window, cx); + }) + .detach(); + + // just to let us render a placeholder editor. + // Once the active git repo is set, this buffer will be replaced. + let temporary_buffer = cx.new(|cx| Buffer::local("", cx)); + let commit_editor = cx.new(|cx| { + commit_message_editor(temporary_buffer, None, project.clone(), true, window, cx) + }); + + commit_editor.update(cx, |editor, cx| { + editor.clear(window, cx); + }); + + let scroll_handle = UniformListScrollHandle::new(); + + cx.subscribe_in( + &git_store, + window, + move |this, git_store, event, window, cx| match event { + GitEvent::FileSystemUpdated => { + this.schedule_update(false, window, cx); + } + GitEvent::ActiveRepositoryChanged | GitEvent::GitStateUpdated => { + this.active_repository = git_store.read(cx).active_repository(); + this.schedule_update(true, window, cx); + } + }, + ) + .detach(); + + let scrollbar_state = + ScrollbarState::new(scroll_handle.clone()).parent_entity(&cx.entity()); + + let repository_selector = + cx.new(|cx| RepositorySelector::new(project.clone(), window, cx)); + + let mut git_panel = Self { + pending_remote_operations: Default::default(), + remote_operation_id: 0, + active_repository, + commit_editor, + suggested_commit_message: None, + conflicted_count: 0, + conflicted_staged_count: 0, + current_modifiers: window.modifiers(), + add_coauthors: true, + entries: Vec::new(), + focus_handle: cx.focus_handle(), + fs, + hide_scrollbar_task: None, + new_count: 0, + new_staged_count: 0, + pending: Vec::new(), + pending_commit: None, + pending_serialization: Task::ready(None), + project, + repository_selector, + scroll_handle, + scrollbar_state, + selected_entry: None, + marked_entries: Vec::new(), + show_scrollbar: false, + tracked_count: 0, + tracked_staged_count: 0, + update_visible_entries_task: Task::ready(()), + width: Some(px(360.)), + context_menu: None, + workspace, + modal_open: false, + }; + git_panel.schedule_update(false, window, cx); + git_panel.show_scrollbar = git_panel.should_show_scrollbar(cx); + git_panel }) - .detach(); - - // just to let us render a placeholder editor. - // Once the active git repo is set, this buffer will be replaced. - let temporary_buffer = cx.new(|cx| Buffer::local("", cx)); - let commit_editor = cx.new(|cx| { - commit_message_editor(temporary_buffer, None, project.clone(), true, window, cx) - }); - - commit_editor.update(cx, |editor, cx| { - editor.clear(window, cx); - }); - - let scroll_handle = UniformListScrollHandle::new(); - - cx.subscribe_in( - &git_store, - window, - move |this, git_store, event, window, cx| match event { - GitEvent::FileSystemUpdated => { - this.schedule_update(false, window, cx); - } - GitEvent::ActiveRepositoryChanged | GitEvent::GitStateUpdated => { - this.active_repository = git_store.read(cx).active_repository(); - this.schedule_update(true, window, cx); - } - }, - ) - .detach(); - - let scrollbar_state = - ScrollbarState::new(scroll_handle.clone()).parent_entity(&cx.entity()); - - let repository_selector = cx.new(|cx| RepositorySelector::new(project.clone(), window, cx)); - - let mut git_panel = Self { - pending_remote_operations: Default::default(), - remote_operation_id: 0, - active_repository, - commit_editor, - suggested_commit_message: None, - conflicted_count: 0, - conflicted_staged_count: 0, - current_modifiers: window.modifiers(), - add_coauthors: true, - entries: Vec::new(), - focus_handle: cx.focus_handle(), - fs, - hide_scrollbar_task: None, - new_count: 0, - new_staged_count: 0, - pending: Vec::new(), - pending_commit: None, - pending_serialization: Task::ready(None), - project, - repository_selector, - scroll_handle, - scrollbar_state, - selected_entry: None, - marked_entries: Vec::new(), - show_scrollbar: false, - tracked_count: 0, - tracked_staged_count: 0, - update_visible_entries_task: Task::ready(()), - width: Some(px(360.)), - context_menu: None, - workspace, - modal_open: false, - }; - git_panel.schedule_update(false, window, cx); - git_panel.show_scrollbar = git_panel.should_show_scrollbar(cx); - git_panel } pub fn entry_by_path(&self, path: &RepoPath) -> Option { @@ -1489,7 +1476,7 @@ impl GitPanel { &mut self, window: &mut Window, cx: &mut Context, - ) -> impl Future>> { + ) -> impl Future>> { let repo = self.active_repository.clone(); let workspace = self.workspace.clone(); let mut cx = window.to_async(cx); @@ -1726,8 +1713,10 @@ impl GitPanel { return; }; + // First pass - collect all paths let repo = repo.read(cx); + // Second pass - create entries with proper depth calculation for entry in repo.status() { let is_conflict = repo.has_conflict(&entry.repo_path); let is_new = entry.status.is_created(); @@ -1741,12 +1730,8 @@ impl GitPanel { continue; } - let Some(worktree_path) = repo.repository_entry.unrelativize(&entry.repo_path) else { - continue; - }; let entry = GitStatusEntry { repo_path: entry.repo_path.clone(), - worktree_path, status: entry.status, is_staged, }; @@ -2394,7 +2379,7 @@ impl GitPanel { &self, sha: &str, cx: &mut Context, - ) -> Task> { + ) -> Task> { let Some(repo) = self.active_repository.clone() else { return Task::ready(Err(anyhow::anyhow!("no active repo"))); }; @@ -2479,12 +2464,12 @@ impl GitPanel { cx: &Context, ) -> AnyElement { let display_name = entry - .worktree_path + .repo_path .file_name() .map(|name| name.to_string_lossy().into_owned()) - .unwrap_or_else(|| entry.worktree_path.to_string_lossy().into_owned()); + .unwrap_or_else(|| entry.repo_path.to_string_lossy().into_owned()); - let worktree_path = entry.worktree_path.clone(); + let repo_path = entry.repo_path.clone(); let selected = self.selected_entry == Some(ix); let marked = self.marked_entries.contains(&ix); let status_style = GitPanelSettings::get_global(cx).status_style; @@ -2655,7 +2640,7 @@ impl GitPanel { h_flex() .items_center() .overflow_hidden() - .when_some(worktree_path.parent(), |this, parent| { + .when_some(repo_path.parent(), |this, parent| { let parent_str = parent.to_string_lossy(); if !parent_str.is_empty() { this.child( @@ -3703,119 +3688,3 @@ impl ComponentPreview for PanelRepoFooter { .into_any_element() } } - -#[cfg(test)] -mod tests { - use git::status::StatusCode; - use gpui::TestAppContext; - use project::{FakeFs, WorktreeSettings}; - use serde_json::json; - use settings::SettingsStore; - use theme::LoadThemes; - use util::path; - - use super::*; - - fn init_test(cx: &mut gpui::TestAppContext) { - if std::env::var("RUST_LOG").is_ok() { - env_logger::try_init().ok(); - } - - cx.update(|cx| { - let settings_store = SettingsStore::test(cx); - cx.set_global(settings_store); - WorktreeSettings::register(cx); - workspace::init_settings(cx); - theme::init(LoadThemes::JustBase, cx); - language::init(cx); - editor::init(cx); - Project::init_settings(cx); - crate::init(cx); - }); - } - - #[gpui::test] - async fn test_entry_worktree_paths(cx: &mut TestAppContext) { - init_test(cx); - let fs = FakeFs::new(cx.background_executor.clone()); - fs.insert_tree( - "/root", - json!({ - "zed": { - ".git": {}, - "crates": { - "gpui": { - "gpui.rs": "fn main() {}" - }, - "util": { - "util.rs": "fn do_it() {}" - } - } - }, - }), - ) - .await; - - fs.set_status_for_repo_via_git_operation( - Path::new("/root/zed/.git"), - &[ - ( - Path::new("crates/gpui/gpui.rs"), - StatusCode::Modified.worktree(), - ), - ( - Path::new("crates/util/util.rs"), - StatusCode::Modified.worktree(), - ), - ], - ); - - let project = - Project::test(fs.clone(), [path!("/root/zed/crates/gpui").as_ref()], cx).await; - let (workspace, cx) = - cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx)); - - cx.read(|cx| { - project - .read(cx) - .worktrees(cx) - .nth(0) - .unwrap() - .read(cx) - .as_local() - .unwrap() - .scan_complete() - }) - .await; - - cx.executor().run_until_parked(); - - let app_state = workspace.update(cx, |workspace, _| workspace.app_state().clone()); - let panel = cx.new_window_entity(|window, cx| { - GitPanel::new(workspace, project, app_state, window, cx) - }); - - let handle = cx.update_window_entity(&panel, |panel, window, cx| { - panel.schedule_update(false, window, cx); - std::mem::replace(&mut panel.update_visible_entries_task, Task::ready(())) - }); - cx.executor().advance_clock(2 * UPDATE_DEBOUNCE); - handle.await; - - let entries = panel.update(cx, |panel, _| panel.entries.clone()); - pretty_assertions::assert_eq!( - entries, - [ - GitListEntry::Header(GitHeaderEntry { - header: Section::Tracked - }), - GitListEntry::GitStatusEntry(GitStatusEntry { - repo_path: "crates/gpui/gpui.rs".into(), - worktree_path: Path::new("gpui.rs").into(), - status: StatusCode::Modified.worktree(), - is_staged: Some(false), - }) - ], - ) - } -} diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index c1812d3f08..0344c2e82d 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -22,7 +22,6 @@ use editor::ProposedChangesEditorToolbar; use editor::{scroll::Autoscroll, Editor, MultiBuffer}; use feature_flags::{FeatureFlagAppExt, FeatureFlagViewExt, GitUiFeatureFlag}; use futures::{channel::mpsc, select_biased, StreamExt}; -use git_ui::git_panel::GitPanel; use git_ui::project_diff::ProjectDiffToolbar; use gpui::{ actions, point, px, Action, App, AppContext as _, AsyncApp, Context, DismissEvent, Element, @@ -430,10 +429,7 @@ fn initialize_panels( workspace.add_panel(chat_panel, window, cx); workspace.add_panel(notification_panel, window, cx); cx.when_flag_enabled::(window, |workspace, window, cx| { - let entity = cx.entity(); - let project = workspace.project().clone(); - let app_state = workspace.app_state().clone(); - let git_panel = cx.new(|cx| GitPanel::new(entity, project, app_state, window, cx)); + let git_panel = git_ui::git_panel::GitPanel::new(workspace, window, cx); workspace.add_panel(git_panel, window, cx); }); })?;