@@ -351,6 +351,7 @@ pub struct GitPanel {
pending: Vec<PendingOperation>,
pending_commit: Option<Task<()>>,
amend_pending: bool,
+ original_commit_message: Option<String>,
signoff_enabled: bool,
pending_serialization: Task<()>,
pub(crate) project: Entity<Project>,
@@ -532,6 +533,7 @@ impl GitPanel {
pending: Vec::new(),
pending_commit: None,
amend_pending: false,
+ original_commit_message: None,
signoff_enabled: false,
pending_serialization: Task::ready(()),
single_staged_entry: None,
@@ -1713,6 +1715,7 @@ impl GitPanel {
Ok(()) => {
this.commit_editor
.update(cx, |editor, cx| editor.clear(window, cx));
+ this.original_commit_message = None;
}
Err(e) => this.show_error_toast("commit", e, cx),
}
@@ -4345,6 +4348,22 @@ impl GitPanel {
}
pub fn set_amend_pending(&mut self, value: bool, cx: &mut Context<Self>) {
+ if value && !self.amend_pending {
+ let current_message = self.commit_message_buffer(cx).read(cx).text();
+ self.original_commit_message = if current_message.trim().is_empty() {
+ None
+ } else {
+ Some(current_message)
+ };
+ } else if !value && self.amend_pending {
+ let message = self.original_commit_message.take().unwrap_or_default();
+ self.commit_message_buffer(cx).update(cx, |buffer, cx| {
+ let start = buffer.anchor_before(0);
+ let end = buffer.anchor_after(buffer.len());
+ buffer.edit([(start..end, message)], None, cx);
+ });
+ }
+
self.amend_pending = value;
self.serialize(cx);
cx.notify();
@@ -5490,4 +5509,73 @@ mod tests {
],
);
}
+
+ #[gpui::test]
+ async fn test_amend_commit_message_handling(cx: &mut TestAppContext) {
+ init_test(cx);
+ let fs = FakeFs::new(cx.background_executor.clone());
+ fs.insert_tree(
+ "/root",
+ json!({
+ "project": {
+ ".git": {},
+ "src": {
+ "main.rs": "fn main() {}"
+ }
+ }
+ }),
+ )
+ .await;
+
+ fs.set_status_for_repo(
+ Path::new(path!("/root/project/.git")),
+ &[(Path::new("src/main.rs"), StatusCode::Modified.worktree())],
+ );
+
+ let project = Project::test(fs.clone(), [Path::new(path!("/root/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();
+
+ // Test: User has commit message, enables amend (saves message), then disables (restores message)
+ panel.update(cx, |panel, cx| {
+ panel.commit_message_buffer(cx).update(cx, |buffer, cx| {
+ let start = buffer.anchor_before(0);
+ let end = buffer.anchor_after(buffer.len());
+ buffer.edit([(start..end, "Initial commit message")], None, cx);
+ });
+
+ panel.set_amend_pending(true, cx);
+ assert!(panel.original_commit_message.is_some());
+
+ panel.set_amend_pending(false, cx);
+ let current_message = panel.commit_message_buffer(cx).read(cx).text();
+ assert_eq!(current_message, "Initial commit message");
+ assert!(panel.original_commit_message.is_none());
+ });
+
+ // Test: User has empty commit message, enables amend, then disables (clears message)
+ panel.update(cx, |panel, cx| {
+ panel.commit_message_buffer(cx).update(cx, |buffer, cx| {
+ let start = buffer.anchor_before(0);
+ let end = buffer.anchor_after(buffer.len());
+ buffer.edit([(start..end, "")], None, cx);
+ });
+
+ panel.set_amend_pending(true, cx);
+ assert!(panel.original_commit_message.is_none());
+
+ panel.commit_message_buffer(cx).update(cx, |buffer, cx| {
+ let start = buffer.anchor_before(0);
+ let end = buffer.anchor_after(buffer.len());
+ buffer.edit([(start..end, "Previous commit message")], None, cx);
+ });
+
+ panel.set_amend_pending(false, cx);
+ let current_message = panel.commit_message_buffer(cx).read(cx).text();
+ assert_eq!(current_message, "");
+ });
+ }
}