Git uncommit warning (#25977)
Adds a prompt when clicking the uncommit button when the current commit is already present on a remote branch:  Release Notes: - N/A --------- Co-authored-by: Conrad <conrad@zed.dev>
This commit is contained in:
parent
0200dda83d
commit
e505d6bf5b
6 changed files with 171 additions and 19 deletions
|
@ -1265,34 +1265,20 @@ impl GitPanel {
|
|||
return;
|
||||
};
|
||||
|
||||
// TODO: Use git merge-base to find the upstream and main branch split
|
||||
let confirmation = Task::ready(true);
|
||||
// let confirmation = if self.commit_editor.read(cx).is_empty(cx) {
|
||||
// Task::ready(true)
|
||||
// } else {
|
||||
// let prompt = window.prompt(
|
||||
// PromptLevel::Warning,
|
||||
// "Uncomitting will replace the current commit message with the previous commit's message",
|
||||
// None,
|
||||
// &["Ok", "Cancel"],
|
||||
// cx,
|
||||
// );
|
||||
// cx.spawn(|_, _| async move { prompt.await.is_ok_and(|i| i == 0) })
|
||||
// };
|
||||
|
||||
let confirmation = self.check_for_pushed_commits(window, cx);
|
||||
let prior_head = self.load_commit_details("HEAD", cx);
|
||||
|
||||
let task = cx.spawn_in(window, |this, mut cx| async move {
|
||||
let result = maybe!(async {
|
||||
if !confirmation.await {
|
||||
Ok(None)
|
||||
} else {
|
||||
if let Ok(true) = confirmation.await {
|
||||
let prior_head = prior_head.await?;
|
||||
|
||||
repo.update(&mut cx, |repo, _| repo.reset("HEAD^", ResetMode::Soft))?
|
||||
.await??;
|
||||
|
||||
Ok(Some(prior_head))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
})
|
||||
.await;
|
||||
|
@ -1315,6 +1301,48 @@ impl GitPanel {
|
|||
self.pending_commit = Some(task);
|
||||
}
|
||||
|
||||
fn check_for_pushed_commits(
|
||||
&mut self,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> impl Future<Output = Result<bool, anyhow::Error>> {
|
||||
let repo = self.active_repository.clone();
|
||||
let mut cx = window.to_async(cx);
|
||||
|
||||
async move {
|
||||
let Some(repo) = repo else {
|
||||
return Err(anyhow::anyhow!("No active repository"));
|
||||
};
|
||||
|
||||
let pushed_to: Vec<SharedString> = repo
|
||||
.update(&mut cx, |repo, _| repo.check_for_pushed_commits())?
|
||||
.await??;
|
||||
|
||||
if pushed_to.is_empty() {
|
||||
Ok(true)
|
||||
} else {
|
||||
#[derive(strum::EnumIter, strum::VariantNames)]
|
||||
#[strum(serialize_all = "title_case")]
|
||||
enum CancelUncommit {
|
||||
Uncommit,
|
||||
Cancel,
|
||||
}
|
||||
let detail = format!(
|
||||
"This commit was already pushed to {}.",
|
||||
pushed_to.into_iter().join(", ")
|
||||
);
|
||||
let result = cx
|
||||
.update(|window, cx| prompt("Are you sure?", Some(&detail), window, cx))?
|
||||
.await?;
|
||||
|
||||
match result {
|
||||
CancelUncommit::Cancel => Ok(false),
|
||||
CancelUncommit::Uncommit => Ok(true),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Suggests a commit message based on the changed files and their statuses
|
||||
pub fn suggest_commit_message(&self) -> Option<String> {
|
||||
if self.total_staged_count() != 1 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue