Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move git status out of Entry #22224

Merged
merged 39 commits into from
Jan 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
f0ad50b
Add a test covering the git_status API we want for
cole-miller Dec 11, 2024
7b5a1e3
Remove git statuses from the worktree entries,
mikayla-maki Dec 12, 2024
f7452b4
Get initial implementation of the new status checking code
mikayla-maki Dec 16, 2024
cf69b21
Work on git panel test some more
cole-miller Dec 16, 2024
52d8ebe
Get test passing, fix a couple of TODOs
cole-miller Dec 19, 2024
af9dcfe
Small cleanup around RepositoryWorkDirectory
cole-miller Dec 19, 2024
652cb93
Rename
cole-miller Dec 19, 2024
974c3e1
WIP: fix propogation
mikayla-maki Dec 17, 2024
f165119
WIP
cole-miller Dec 18, 2024
ff2a364
wat
cole-miller Dec 18, 2024
e8f3fc6
One test to go
mikayla-maki Dec 19, 2024
51c3016
Fix several bugs in how statuses are computed for multiple sub reposi…
mikayla-maki Dec 19, 2024
2f03726
Debugging
cole-miller Dec 19, 2024
cf68eab
Finish re-implementing status propagation
mikayla-maki Dec 19, 2024
ceaffa8
Roll out some of the git status changes through zed
mikayla-maki Dec 20, 2024
0d8b5e1
Merge branch 'main' into cole/git-panel
mikayla-maki Dec 20, 2024
942bedb
Push entry changes out further
cole-miller Dec 21, 2024
3ddd926
WIP: Switch to using a sumtree for repository entries
mikayla-maki Dec 21, 2024
d7eaa23
Finish shredding worktree, add the work directory data
mikayla-maki Dec 22, 2024
108a53a
Take a first pass at implementing the git status join
mikayla-maki Dec 22, 2024
2ff06ce
speculatively roll this out to API consumers
mikayla-maki Dec 22, 2024
62545e1
Merge remote-tracking branch 'origin/main' into cole/git-panel
cole-miller Dec 30, 2024
7c90ba2
Start fixing compiler errors
cole-miller Dec 30, 2024
92a19d9
More fixes
cole-miller Dec 30, 2024
e968a7c
Get nested repos traversal working
cole-miller Dec 31, 2024
7e54f0a
Upgrade GitTraversal to replace propagate_statuses; all tests passing
cole-miller Jan 1, 2025
7512230
Remove propagate_git_statuses
cole-miller Jan 2, 2025
adb5e66
Make WorkDirectory::repository_for_path faster
cole-miller Jan 2, 2025
69c6b79
Sync changed statuses to collab
cole-miller Jan 3, 2025
eba0917
Merge remote-tracking branch 'origin/main' into cole/git-panel
cole-miller Jan 3, 2025
c239065
Synchronize statuses over collab
cole-miller Jan 3, 2025
e457030
Clippy!
cole-miller Jan 3, 2025
ee98e52
Fix project panel not listening for git updates
cole-miller Jan 3, 2025
f6e79b5
Fix untracked statuses not propagating
cole-miller Jan 3, 2025
701954d
Re-add git statuses field because we can't drop it
cole-miller Jan 3, 2025
8c352ef
Fix ALL THE TYPOS
cole-miller Jan 3, 2025
f104fe7
Fix reused function name revealed by typo fix
cole-miller Jan 3, 2025
0bc71bf
Fix unused dependency
cole-miller Jan 4, 2025
ccfe55d
fix tests
mikayla-maki Jan 4, 2025
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
4 changes: 3 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ hyper = "0.14"
http = "1.1"
ignore = "0.4.22"
image = "0.25.1"
indexmap = { version = "2", features = ["serde"] }
indexmap = { version = "2.7.0", features = ["serde"] }
indoc = "2"
itertools = "0.13.0"
jsonwebtoken = "9.3"
Expand Down Expand Up @@ -443,9 +443,10 @@ runtimelib = { version = "0.24.0", default-features = false, features = [
] }
rustc-demangle = "0.1.23"
rust-embed = { version = "8.4", features = ["include-exclude"] }
rustc-hash = "2.1.0"
rustls = "0.21.12"
rustls-native-certs = "0.8.0"
schemars = { version = "0.8", features = ["impl_json_schema"] }
schemars = { version = "0.8", features = ["impl_json_schema", "indexmap2"] }
semver = "1.0"
serde = { version = "1.0", features = ["derive", "rc"] }
serde_derive = { version = "1.0", features = ["deserialize_in_place"] }
Expand Down
2 changes: 1 addition & 1 deletion crates/assistant/src/assistant_panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ pub fn init(cx: &mut AppContext) {
cx.observe_new_views(
|terminal_panel: &mut TerminalPanel, cx: &mut ViewContext<TerminalPanel>| {
let settings = AssistantSettings::get_global(cx);
terminal_panel.asssistant_enabled(settings.enabled, cx);
terminal_panel.set_assistant_enabled(settings.enabled, cx);
},
)
.detach();
Expand Down
2 changes: 1 addition & 1 deletion crates/assistant/src/inline_assistant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ impl InlineAssistant {
};
let enabled = AssistantSettings::get_global(cx).enabled;
terminal_panel.update(cx, |terminal_panel, cx| {
terminal_panel.asssistant_enabled(enabled, cx)
terminal_panel.set_assistant_enabled(enabled, cx)
});
})
.detach();
Expand Down
2 changes: 1 addition & 1 deletion crates/assistant2/src/inline_assistant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ impl InlineAssistant {
};
let enabled = AssistantSettings::get_global(cx).enabled;
terminal_panel.update(cx, |terminal_panel, cx| {
terminal_panel.asssistant_enabled(enabled, cx)
terminal_panel.set_assistant_enabled(enabled, cx)
});
})
.detach();
Expand Down
2 changes: 1 addition & 1 deletion crates/cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ fn parse_path_with_position(argument_str: &str) -> anyhow::Result<String> {
Ok(existing_path) => PathWithPosition::from_path(existing_path),
Err(_) => {
let path = PathWithPosition::parse_str(argument_str);
let curdir = env::current_dir().context("reteiving current directory")?;
let curdir = env::current_dir().context("retrieving current directory")?;
path.map_path(|path| match fs::canonicalize(&path) {
Ok(path) => Ok(path),
Err(e) => {
Expand Down
16 changes: 16 additions & 0 deletions crates/collab/migrations.sqlite/20221109000000_test_schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,22 @@ CREATE TABLE "worktree_repositories" (
CREATE INDEX "index_worktree_repositories_on_project_id" ON "worktree_repositories" ("project_id");
CREATE INDEX "index_worktree_repositories_on_project_id_and_worktree_id" ON "worktree_repositories" ("project_id", "worktree_id");

CREATE TABLE "worktree_repository_statuses" (
"project_id" INTEGER NOT NULL,
"worktree_id" INT8 NOT NULL,
"work_directory_id" INT8 NOT NULL,
"repo_path" VARCHAR NOT NULL,
"status" INT8 NOT NULL,
"scan_id" INT8 NOT NULL,
"is_deleted" BOOL NOT NULL,
PRIMARY KEY(project_id, worktree_id, work_directory_id, repo_path),
FOREIGN KEY(project_id, worktree_id) REFERENCES worktrees (project_id, id) ON DELETE CASCADE,
FOREIGN KEY(project_id, worktree_id, work_directory_id) REFERENCES worktree_entries (project_id, worktree_id, id) ON DELETE CASCADE
);
CREATE INDEX "index_wt_repos_statuses_on_project_id" ON "worktree_repository_statuses" ("project_id");
CREATE INDEX "index_wt_repos_statuses_on_project_id_and_wt_id" ON "worktree_repository_statuses" ("project_id", "worktree_id");
CREATE INDEX "index_wt_repos_statuses_on_project_id_and_wt_id_and_wd_id" ON "worktree_repository_statuses" ("project_id", "worktree_id", "work_directory_id");

CREATE TABLE "worktree_settings_files" (
"project_id" INTEGER NOT NULL,
"worktree_id" INTEGER NOT NULL,
Expand Down
112 changes: 105 additions & 7 deletions crates/collab/src/db/queries/projects.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use anyhow::Context as _;

use util::ResultExt;

use super::*;
Expand Down Expand Up @@ -274,8 +275,8 @@ impl Database {
mtime_nanos: ActiveValue::set(mtime.nanos as i32),
canonical_path: ActiveValue::set(entry.canonical_path.clone()),
is_ignored: ActiveValue::set(entry.is_ignored),
git_status: ActiveValue::set(None),
is_external: ActiveValue::set(entry.is_external),
git_status: ActiveValue::set(entry.git_status.map(|status| status as i64)),
is_deleted: ActiveValue::set(false),
scan_id: ActiveValue::set(update.scan_id as i64),
is_fifo: ActiveValue::set(entry.is_fifo),
Expand All @@ -295,7 +296,6 @@ impl Database {
worktree_entry::Column::MtimeNanos,
worktree_entry::Column::CanonicalPath,
worktree_entry::Column::IsIgnored,
worktree_entry::Column::GitStatus,
worktree_entry::Column::ScanId,
])
.to_owned(),
Expand Down Expand Up @@ -349,6 +349,79 @@ impl Database {
)
.exec(&*tx)
.await?;

let has_any_statuses = update
.updated_repositories
.iter()
.any(|repository| !repository.updated_statuses.is_empty());

if has_any_statuses {
worktree_repository_statuses::Entity::insert_many(
update.updated_repositories.iter().flat_map(
|repository: &proto::RepositoryEntry| {
repository.updated_statuses.iter().map(|status_entry| {
worktree_repository_statuses::ActiveModel {
project_id: ActiveValue::set(project_id),
worktree_id: ActiveValue::set(worktree_id),
work_directory_id: ActiveValue::set(
repository.work_directory_id as i64,
),
scan_id: ActiveValue::set(update.scan_id as i64),
is_deleted: ActiveValue::set(false),
repo_path: ActiveValue::set(status_entry.repo_path.clone()),
status: ActiveValue::set(status_entry.status as i64),
}
})
},
),
)
.on_conflict(
OnConflict::columns([
worktree_repository_statuses::Column::ProjectId,
worktree_repository_statuses::Column::WorktreeId,
worktree_repository_statuses::Column::WorkDirectoryId,
worktree_repository_statuses::Column::RepoPath,
])
.update_columns([
worktree_repository_statuses::Column::ScanId,
worktree_repository_statuses::Column::Status,
])
.to_owned(),
)
.exec(&*tx)
.await?;
}

let has_any_removed_statuses = update
.updated_repositories
.iter()
.any(|repository| !repository.removed_statuses.is_empty());

if has_any_removed_statuses {
worktree_repository_statuses::Entity::update_many()
.filter(
worktree_repository_statuses::Column::ProjectId
.eq(project_id)
.and(
worktree_repository_statuses::Column::WorktreeId
.eq(worktree_id),
)
.and(
worktree_repository_statuses::Column::RepoPath.is_in(
update.updated_repositories.iter().flat_map(|repository| {
repository.removed_statuses.iter()
}),
),
),
)
.set(worktree_repository_statuses::ActiveModel {
is_deleted: ActiveValue::Set(true),
scan_id: ActiveValue::Set(update.scan_id as i64),
..Default::default()
})
.exec(&*tx)
.await?;
}
}

if !update.removed_repositories.is_empty() {
Expand Down Expand Up @@ -643,7 +716,6 @@ impl Database {
canonical_path: db_entry.canonical_path,
is_ignored: db_entry.is_ignored,
is_external: db_entry.is_external,
git_status: db_entry.git_status.map(|status| status as i32),
// This is only used in the summarization backlog, so if it's None,
// that just means we won't be able to detect when to resummarize
// based on total number of backlogged bytes - instead, we'd go
Expand All @@ -657,23 +729,49 @@ impl Database {

// Populate repository entries.
{
let mut db_repository_entries = worktree_repository::Entity::find()
let db_repository_entries = worktree_repository::Entity::find()
.filter(
Condition::all()
.add(worktree_repository::Column::ProjectId.eq(project.id))
.add(worktree_repository::Column::IsDeleted.eq(false)),
)
.stream(tx)
.all(tx)
.await?;
while let Some(db_repository_entry) = db_repository_entries.next().await {
let db_repository_entry = db_repository_entry?;
for db_repository_entry in db_repository_entries {
if let Some(worktree) = worktrees.get_mut(&(db_repository_entry.worktree_id as u64))
{
let mut repository_statuses = worktree_repository_statuses::Entity::find()
.filter(
Condition::all()
.add(worktree_repository_statuses::Column::ProjectId.eq(project.id))
.add(
worktree_repository_statuses::Column::WorktreeId
.eq(worktree.id),
)
.add(
worktree_repository_statuses::Column::WorkDirectoryId
.eq(db_repository_entry.work_directory_id),
)
.add(worktree_repository_statuses::Column::IsDeleted.eq(false)),
)
.stream(tx)
.await?;
let mut updated_statuses = Vec::new();
while let Some(status_entry) = repository_statuses.next().await {
let status_entry: worktree_repository_statuses::Model = status_entry?;
updated_statuses.push(proto::StatusEntry {
repo_path: status_entry.repo_path,
status: status_entry.status as i32,
});
}

worktree.repository_entries.insert(
db_repository_entry.work_directory_id as u64,
proto::RepositoryEntry {
work_directory_id: db_repository_entry.work_directory_id as u64,
branch: db_repository_entry.branch,
updated_statuses,
removed_statuses: Vec::new(),
},
);
}
Expand Down
52 changes: 47 additions & 5 deletions crates/collab/src/db/queries/rooms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,6 @@ impl Database {
canonical_path: db_entry.canonical_path,
is_ignored: db_entry.is_ignored,
is_external: db_entry.is_external,
git_status: db_entry.git_status.map(|status| status as i32),
// This is only used in the summarization backlog, so if it's None,
// that just means we won't be able to detect when to resummarize
// based on total number of backlogged bytes - instead, we'd go
Expand All @@ -682,26 +681,69 @@ impl Database {
worktree_repository::Column::IsDeleted.eq(false)
};

let mut db_repositories = worktree_repository::Entity::find()
let db_repositories = worktree_repository::Entity::find()
.filter(
Condition::all()
.add(worktree_repository::Column::ProjectId.eq(project.id))
.add(worktree_repository::Column::WorktreeId.eq(worktree.id))
.add(repository_entry_filter),
)
.stream(tx)
.all(tx)
.await?;

while let Some(db_repository) = db_repositories.next().await {
let db_repository = db_repository?;
for db_repository in db_repositories.into_iter() {
if db_repository.is_deleted {
worktree
.removed_repositories
.push(db_repository.work_directory_id as u64);
} else {
let status_entry_filter = if let Some(rejoined_worktree) = rejoined_worktree
{
worktree_repository_statuses::Column::ScanId
.gt(rejoined_worktree.scan_id)
} else {
worktree_repository_statuses::Column::IsDeleted.eq(false)
};

let mut db_statuses = worktree_repository_statuses::Entity::find()
.filter(
Condition::all()
.add(
worktree_repository_statuses::Column::ProjectId
.eq(project.id),
)
.add(
worktree_repository_statuses::Column::WorktreeId
.eq(worktree.id),
)
.add(
worktree_repository_statuses::Column::WorkDirectoryId
.eq(db_repository.work_directory_id),
)
.add(status_entry_filter),
)
.stream(tx)
.await?;
let mut removed_statuses = Vec::new();
let mut updated_statuses = Vec::new();

while let Some(db_status) = db_statuses.next().await {
let db_status: worktree_repository_statuses::Model = db_status?;
if db_status.is_deleted {
removed_statuses.push(db_status.repo_path);
} else {
updated_statuses.push(proto::StatusEntry {
repo_path: db_status.repo_path,
status: db_status.status as i32,
});
}
}

worktree.updated_repositories.push(proto::RepositoryEntry {
work_directory_id: db_repository.work_directory_id as u64,
branch: db_repository.branch,
updated_statuses,
removed_statuses,
});
}
}
Expand Down
12 changes: 7 additions & 5 deletions crates/collab/src/tests/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2925,8 +2925,6 @@ async fn test_git_status_sync(
assert_eq!(snapshot.status_for_file(file), status);
}

// Smoke test status reading

project_local.read_with(cx_a, |project, cx| {
assert_status(&Path::new(A_TXT), Some(GitFileStatus::Added), project, cx);
assert_status(&Path::new(B_TXT), Some(GitFileStatus::Added), project, cx);
Expand Down Expand Up @@ -6669,6 +6667,10 @@ async fn test_remote_git_branches(
client_a
.fs()
.insert_branches(Path::new("/project/.git"), &branches);
let branches_set = branches
.into_iter()
.map(ToString::to_string)
.collect::<HashSet<_>>();

let (project_a, worktree_id) = client_a.build_local_project("/project", cx_a).await;
let project_id = active_call_a
Expand All @@ -6690,10 +6692,10 @@ async fn test_remote_git_branches(

let branches_b = branches_b
.into_iter()
.map(|branch| branch.name)
.collect::<Vec<_>>();
.map(|branch| branch.name.to_string())
.collect::<HashSet<_>>();

assert_eq!(&branches_b, &branches);
assert_eq!(branches_b, branches_set);

cx_b.update(|cx| {
project_b.update(cx, |project, cx| {
Expand Down
Loading
Loading