Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions crates/editor/src/editor_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16515,7 +16515,7 @@ async fn test_following_with_multiple_excerpts(cx: &mut TestAppContext) {
leader.update(cx, |leader, cx| {
leader.buffer.update(cx, |multibuffer, cx| {
multibuffer.set_excerpts_for_path(
PathKey::namespaced(1, rel_path("b.txt").into_arc()),
PathKey::with_sort_prefix(1, rel_path("b.txt").into_arc()),
buffer_1.clone(),
vec![
Point::row_range(0..3),
Expand All @@ -16526,7 +16526,7 @@ async fn test_following_with_multiple_excerpts(cx: &mut TestAppContext) {
cx,
);
multibuffer.set_excerpts_for_path(
PathKey::namespaced(1, rel_path("a.txt").into_arc()),
PathKey::with_sort_prefix(1, rel_path("a.txt").into_arc()),
buffer_2.clone(),
vec![Point::row_range(0..6), Point::row_range(8..12)],
0,
Expand Down Expand Up @@ -21029,7 +21029,7 @@ async fn test_display_diff_hunks(cx: &mut TestAppContext) {
for buffer in &buffers {
let snapshot = buffer.read(cx).snapshot();
multibuffer.set_excerpts_for_path(
PathKey::namespaced(0, buffer.read(cx).file().unwrap().path().clone()),
PathKey::with_sort_prefix(0, buffer.read(cx).file().unwrap().path().clone()),
buffer.clone(),
vec![text::Anchor::MIN.to_point(&snapshot)..text::Anchor::MAX.to_point(&snapshot)],
2,
Expand Down
8 changes: 4 additions & 4 deletions crates/git_ui/src/commit_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ struct CommitMetadataFile {
worktree_id: WorktreeId,
}

const COMMIT_METADATA_NAMESPACE: u64 = 0;
const FILE_NAMESPACE: u64 = 1;
const COMMIT_METADATA_SORT_PREFIX: u64 = 0;
const FILE_NAMESPACE_SORT_PREFIX: u64 = 1;

impl CommitView {
pub fn open(
Expand Down Expand Up @@ -145,7 +145,7 @@ impl CommitView {
});
multibuffer.update(cx, |multibuffer, cx| {
multibuffer.set_excerpts_for_path(
PathKey::namespaced(COMMIT_METADATA_NAMESPACE, file.title.clone()),
PathKey::with_sort_prefix(COMMIT_METADATA_SORT_PREFIX, file.title.clone()),
buffer.clone(),
vec![Point::zero()..buffer.read(cx).max_point()],
0,
Expand Down Expand Up @@ -193,7 +193,7 @@ impl CommitView {
.collect::<Vec<_>>();
let path = snapshot.file().unwrap().path().clone();
let _is_newly_added = multibuffer.set_excerpts_for_path(
PathKey::namespaced(FILE_NAMESPACE, path),
PathKey::with_sort_prefix(FILE_NAMESPACE_SORT_PREFIX, path),
buffer,
diff_hunk_ranges,
multibuffer_context_lines(cx),
Expand Down
63 changes: 63 additions & 0 deletions crates/git_ui/src/git_panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4894,6 +4894,7 @@ mod tests {
use settings::SettingsStore;
use theme::LoadThemes;
use util::path;
use util::rel_path::rel_path;

use super::*;

Expand Down Expand Up @@ -5516,6 +5517,68 @@ mod tests {
});
}

#[gpui::test]
async fn test_open_diff(cx: &mut TestAppContext) {
init_test(cx);

let fs = FakeFs::new(cx.background_executor.clone());
fs.insert_tree(
path!("/project"),
json!({
".git": {},
"tracked": "tracked\n",
"untracked": "\n",
}),
)
.await;

fs.set_head_and_index_for_repo(
path!("/project/.git").as_ref(),
&[("tracked", "old tracked\n".into())],
);

let project = Project::test(fs.clone(), [Path::new(path!("/project"))], cx).await;
let workspace =
cx.add_window(|window, cx| Workspace::test_new(project.clone(), window, cx));
let cx = &mut VisualTestContext::from_window(*workspace, cx);
let panel = workspace.update(cx, GitPanel::new).unwrap();

// Enable the `sort_by_path` setting and wait for entries to be updated,
// as there should no longer be separators between Tracked and Untracked
// files.
cx.update(|_window, cx| {
SettingsStore::update_global(cx, |store, cx| {
store.update_user_settings(cx, |settings| {
settings.git_panel.get_or_insert_default().sort_by_path = Some(true);
})
});
});

cx.update_window_entity(&panel, |panel, _, _| {
std::mem::replace(&mut panel.update_visible_entries_task, Task::ready(()))
})
.await;

// Confirm that `Open Diff` still works for the untracked file, updating
// the Project Diff's active path.
panel.update_in(cx, |panel, window, cx| {
panel.selected_entry = Some(1);
panel.open_diff(&Confirm, window, cx);
});
cx.run_until_parked();

let _ = workspace.update(cx, |workspace, _window, cx| {
let active_path = workspace
.item_of_type::<ProjectDiff>(cx)
.expect("ProjectDiff should exist")
.read(cx)
.active_path(cx)
.expect("active_path should exist");

assert_eq!(active_path.path, rel_path("untracked").into_arc());
});
}

fn assert_entry_paths(entries: &[GitListEntry], expected_paths: &[Option<&str>]) {
assert_eq!(entries.len(), expected_paths.len());
for (entry, expected_path) in entries.iter().zip(expected_paths) {
Expand Down
50 changes: 23 additions & 27 deletions crates/git_ui/src/project_diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use editor::{
use futures::StreamExt;
use git::{
Commit, StageAll, StageAndNext, ToggleStaged, UnstageAll, UnstageAndNext,
repository::{Branch, Upstream, UpstreamTracking, UpstreamTrackingStatus},
repository::{Branch, RepoPath, Upstream, UpstreamTracking, UpstreamTrackingStatus},
status::FileStatus,
};
use gpui::{
Expand All @@ -27,7 +27,7 @@ use language::{Anchor, Buffer, Capability, OffsetRangeExt};
use multi_buffer::{MultiBuffer, PathKey};
use project::{
Project, ProjectPath,
git_store::{GitStore, GitStoreEvent},
git_store::{GitStore, GitStoreEvent, Repository},
};
use settings::{Settings, SettingsStore};
use std::any::{Any, TypeId};
Expand Down Expand Up @@ -73,9 +73,9 @@ struct DiffBuffer {
file_status: FileStatus,
}

const CONFLICT_NAMESPACE: u64 = 1;
const TRACKED_NAMESPACE: u64 = 2;
const NEW_NAMESPACE: u64 = 3;
const CONFLICT_SORT_PREFIX: u64 = 1;
const TRACKED_SORT_PREFIX: u64 = 2;
const NEW_SORT_PREFIX: u64 = 3;

impl ProjectDiff {
pub(crate) fn register(workspace: &mut Workspace, cx: &mut Context<Workspace>) {
Expand Down Expand Up @@ -234,16 +234,8 @@ impl ProjectDiff {
return;
};
let repo = git_repo.read(cx);

let namespace = if repo.had_conflict_on_last_merge_head_change(&entry.repo_path) {
CONFLICT_NAMESPACE
} else if entry.status.is_created() {
NEW_NAMESPACE
} else {
TRACKED_NAMESPACE
};

let path_key = PathKey::namespaced(namespace, entry.repo_path.0);
let sort_prefix = sort_prefix(repo, &entry.repo_path, entry.status, cx);
let path_key = PathKey::with_sort_prefix(sort_prefix, entry.repo_path.0);

self.move_to_path(path_key, window, cx)
}
Expand Down Expand Up @@ -388,16 +380,8 @@ impl ProjectDiff {
else {
continue;
};
let namespace = if GitPanelSettings::get_global(cx).sort_by_path {
TRACKED_NAMESPACE
} else if repo.had_conflict_on_last_merge_head_change(&entry.repo_path) {
CONFLICT_NAMESPACE
} else if entry.status.is_created() {
NEW_NAMESPACE
} else {
TRACKED_NAMESPACE
};
let path_key = PathKey::namespaced(namespace, entry.repo_path.0.clone());
let sort_prefix = sort_prefix(repo, &entry.repo_path, entry.status, cx);
let path_key = PathKey::with_sort_prefix(sort_prefix, entry.repo_path.0.clone());

previous_paths.remove(&path_key);
let load_buffer = self
Expand Down Expand Up @@ -541,6 +525,18 @@ impl ProjectDiff {
}
}

fn sort_prefix(repo: &Repository, repo_path: &RepoPath, status: FileStatus, cx: &App) -> u64 {
if GitPanelSettings::get_global(cx).sort_by_path {
TRACKED_SORT_PREFIX
} else if repo.had_conflict_on_last_merge_head_change(repo_path) {
CONFLICT_SORT_PREFIX
} else if status.is_created() {
NEW_SORT_PREFIX
} else {
TRACKED_SORT_PREFIX
}
}

impl EventEmitter<EditorEvent> for ProjectDiff {}

impl Focusable for ProjectDiff {
Expand Down Expand Up @@ -1463,7 +1459,7 @@ mod tests {

let editor = cx.update_window_entity(&diff, |diff, window, cx| {
diff.move_to_path(
PathKey::namespaced(TRACKED_NAMESPACE, rel_path("foo").into_arc()),
PathKey::with_sort_prefix(TRACKED_SORT_PREFIX, rel_path("foo").into_arc()),
window,
cx,
);
Expand All @@ -1484,7 +1480,7 @@ mod tests {

let editor = cx.update_window_entity(&diff, |diff, window, cx| {
diff.move_to_path(
PathKey::namespaced(TRACKED_NAMESPACE, rel_path("bar").into_arc()),
PathKey::with_sort_prefix(TRACKED_SORT_PREFIX, rel_path("bar").into_arc()),
window,
cx,
);
Expand Down
11 changes: 6 additions & 5 deletions crates/multi_buffer/src/multi_buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,24 +161,25 @@ impl MultiBufferDiffHunk {

#[derive(PartialEq, Eq, Ord, PartialOrd, Clone, Hash, Debug)]
pub struct PathKey {
namespace: Option<u64>,
// Used by the derived PartialOrd & Ord
sort_prefix: Option<u64>,
path: Arc<RelPath>,
}

impl PathKey {
pub fn namespaced(namespace: u64, path: Arc<RelPath>) -> Self {
pub fn with_sort_prefix(sort_prefix: u64, path: Arc<RelPath>) -> Self {
Self {
namespace: Some(namespace),
sort_prefix: Some(sort_prefix),
path,
}
}

pub fn for_buffer(buffer: &Entity<Buffer>, cx: &App) -> Self {
if let Some(file) = buffer.read(cx).file() {
Self::namespaced(file.worktree_id(cx).to_proto(), file.path().clone())
Self::with_sort_prefix(file.worktree_id(cx).to_proto(), file.path().clone())
} else {
Self {
namespace: None,
sort_prefix: None,
path: RelPath::unix(&buffer.entity_id().to_string())
.unwrap()
.into_arc(),
Expand Down
8 changes: 4 additions & 4 deletions crates/multi_buffer/src/multi_buffer_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1525,7 +1525,7 @@ fn test_set_excerpts_for_buffer_ordering(cx: &mut TestAppContext) {
cx,
)
});
let path1: PathKey = PathKey::namespaced(0, rel_path("root").into_arc());
let path1: PathKey = PathKey::with_sort_prefix(0, rel_path("root").into_arc());

let multibuffer = cx.new(|_| MultiBuffer::new(Capability::ReadWrite));
multibuffer.update(cx, |multibuffer, cx| {
Expand Down Expand Up @@ -1620,7 +1620,7 @@ fn test_set_excerpts_for_buffer(cx: &mut TestAppContext) {
cx,
)
});
let path1: PathKey = PathKey::namespaced(0, rel_path("root").into_arc());
let path1: PathKey = PathKey::with_sort_prefix(0, rel_path("root").into_arc());
let buf2 = cx.new(|cx| {
Buffer::local(
indoc! {
Expand All @@ -1639,7 +1639,7 @@ fn test_set_excerpts_for_buffer(cx: &mut TestAppContext) {
cx,
)
});
let path2 = PathKey::namespaced(1, rel_path("root").into_arc());
let path2 = PathKey::with_sort_prefix(1, rel_path("root").into_arc());

let multibuffer = cx.new(|_| MultiBuffer::new(Capability::ReadWrite));
multibuffer.update(cx, |multibuffer, cx| {
Expand Down Expand Up @@ -1816,7 +1816,7 @@ fn test_set_excerpts_for_buffer_rename(cx: &mut TestAppContext) {
cx,
)
});
let path: PathKey = PathKey::namespaced(0, rel_path("root").into_arc());
let path: PathKey = PathKey::with_sort_prefix(0, rel_path("root").into_arc());
let buf2 = cx.new(|cx| {
Buffer::local(
indoc! {
Expand Down
Loading