From 058fdeaf856bbc5e90edc97e521ef74b466a0d14 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 31 Oct 2025 14:05:21 +0100 Subject: [PATCH] git: Make GitJobKey::WriteIndex accept a string instead path This way, we can naively assign the same identifier to jobs consisting of the same set of paths. Of course, this assumes paths are always in the same order, etc. but it's the first step towards maybe a bit smarter solution. --- crates/git_ui/src/git_panel.rs | 34 ++++++++++++++++++----------- crates/project/src/git_store.rs | 38 ++++++++++++++++----------------- 2 files changed, 40 insertions(+), 32 deletions(-) diff --git a/crates/git_ui/src/git_panel.rs b/crates/git_ui/src/git_panel.rs index a2322634674142f17081f7679e4dfa24ea7efb26..7a6a4c8ad636c629fb7e93f3be6dd47cb0fc1c38 100644 --- a/crates/git_ui/src/git_panel.rs +++ b/crates/git_ui/src/git_panel.rs @@ -1223,14 +1223,18 @@ impl GitPanel { }); } - pub fn stage_all(&mut self, _: &StageAll, _window: &mut Window, cx: &mut Context) { + pub fn change_all_files_stage(&mut self, stage: bool, cx: &mut Context) { let Some(active_repository) = self.active_repository.clone() else { return; }; let op_id = self.pending.iter().map(|p| p.op_id).max().unwrap_or(0) + 1; self.pending.push(PendingOperation { op_id, - target_status: TargetStatus::Staged, + target_status: if stage { + TargetStatus::Staged + } else { + TargetStatus::Unstaged + }, entries: PendingEntries::All, finished: false, }); @@ -1241,7 +1245,15 @@ impl GitPanel { cx.spawn({ async move |this, cx| { let result = cx - .update(|cx| active_repository.update(cx, |repo, cx| repo.stage_all(cx)))? + .update(|cx| { + active_repository.update(cx, |repo, cx| { + if stage { + repo.stage_all(cx) + } else { + repo.unstage_all(cx) + } + }) + })? .await; this.update(cx, |this, cx| { @@ -1252,7 +1264,7 @@ impl GitPanel { } result .map_err(|e| { - this.show_error_toast("add", e, cx); + this.show_error_toast(if stage { "add" } else { "reset" }, e, cx); }) .ok(); cx.notify(); @@ -1262,16 +1274,12 @@ impl GitPanel { .detach(); } + pub fn stage_all(&mut self, _: &StageAll, _window: &mut Window, cx: &mut Context) { + self.change_all_files_stage(true, cx); + } + pub fn unstage_all(&mut self, _: &UnstageAll, _window: &mut Window, cx: &mut Context) { - let entries = self - .entries - .iter() - .filter_map(|entry| entry.status_entry()) - .filter(|status_entry| status_entry.staging.has_staged()) - .cloned() - .collect::>(); - dbg!(&entries); - self.change_file_stage(false, entries, cx); + self.change_all_files_stage(false, cx); } fn toggle_staged_for_entry( diff --git a/crates/project/src/git_store.rs b/crates/project/src/git_store.rs index 827f2eb51d1c239415aed9c2c3c90a90cef205f2..09c7025494ab53a1a7cb078261a4bf2931861c3e 100644 --- a/crates/project/src/git_store.rs +++ b/crates/project/src/git_store.rs @@ -338,7 +338,7 @@ pub struct GitJob { #[derive(Debug, PartialEq, Eq)] enum GitJobKey { - WriteIndex(RepoPath), + WriteIndex(String), ReloadBufferDiffBases, RefreshStatuses, ReloadGitState, @@ -3754,12 +3754,13 @@ impl Repository { let id = self.id; let save_tasks = self.save_buffers(&entries, cx); - let job_key = match entries.len() { - 1 => Some(GitJobKey::WriteIndex(entries[0].clone())), - _ => None, - }; - let paths: Vec<_> = entries.iter().map(|p| p.as_unix_str()).collect(); - let status = format!("git add {}", paths.join(" ")); + let paths = entries + .iter() + .map(|p| p.as_unix_str()) + .collect::>() + .join(" "); + let status = format!("git add {paths}"); + let job_key = GitJobKey::WriteIndex(paths); cx.spawn(async move |this, cx| { for save_task in save_tasks { @@ -3768,7 +3769,7 @@ impl Repository { this.update(cx, |this, _| { this.send_keyed_job( - job_key, + Some(job_key), Some(status.into()), move |git_repo, _cx| async move { match git_repo { @@ -3813,12 +3814,13 @@ impl Repository { let id = self.id; let save_tasks = self.save_buffers(&entries, cx); - let job_key = match entries.len() { - 1 => Some(GitJobKey::WriteIndex(entries[0].clone())), - _ => None, - }; - let paths: Vec<_> = entries.iter().map(|p| p.as_unix_str()).collect(); - let status = format!("git reset {}", paths.join(" ")); + let paths = entries + .iter() + .map(|p| p.as_unix_str()) + .collect::>() + .join(" "); + let status = format!("git reset {paths}"); + let job_key = GitJobKey::WriteIndex(paths); cx.spawn(async move |this, cx| { for save_task in save_tasks { @@ -3827,7 +3829,7 @@ impl Repository { this.update(cx, |this, _| { this.send_keyed_job( - job_key, + Some(job_key), Some(status.into()), move |git_repo, _cx| async move { match git_repo { @@ -3867,17 +3869,15 @@ impl Repository { .filter(|entry| !entry.status.staging().is_fully_staged()) .map(|entry| entry.repo_path) .collect(); - dbg!(&to_stage); self.stage_entries(to_stage, cx) } pub fn unstage_all(&self, cx: &mut Context) -> Task> { let to_unstage = self .cached_status() - .filter(|entry| entry.status.staging().has_staged()) + .filter(|entry| entry.status.staging().is_fully_unstaged()) .map(|entry| entry.repo_path) .collect(); - dbg!(&to_unstage); self.unstage_entries(to_unstage, cx) } @@ -4303,7 +4303,7 @@ impl Repository { let this = cx.weak_entity(); let git_store = self.git_store.clone(); self.send_keyed_job( - Some(GitJobKey::WriteIndex(path.clone())), + Some(GitJobKey::WriteIndex(path.as_unix_str().to_string())), None, move |git_repo, mut cx| async move { log::debug!(