git: Add ability to pass --signoff
(#29874)
This adds an option for `--signoff` to the git panel and commit modal. It allows users to enable the [`--signoff` flag](https://git-scm.com/docs/git-commit#Documentation/git-commit.txt-code--signoffcode) when committing through Zed. The option is added to the context menu of the commit button (following the style of the "Editor Controls"). To support this, the commit+amend experience was revamped (following the ideas of [this comment](https://github.com/zed-industries/zed/pull/29874#issuecomment-2950848000)). Amending is now also a toggle in the commit button's dropdown menu. I've kept some of the original experience such as the changed button text and ability to cancel outside the context menu. The tooltip of the commit buttons now also includes the flags that will be used based on the amending and signoff status (which I couldn't capture in screenshots unfortunately). So, by default the tooltip will say `git commit` and if you toggle, e.g., amending on it will say `git commit --amend`. | What | Panel | Modal | | --- | --- | --- | | Not amending, dropdown |  |  | | Amending, dropdown |  |  | | Amending |  | - | The initial implementation was based on the changeset of https://github.com/zed-industries/zed/pull/28187. Closes https://github.com/zed-industries/zed/discussions/26114 Release Notes: - Added git `--signoff` support. - Update the git `--amend` experience. - Improved git panel to persist width as well as amend and signoff on a per-workspace basis.
This commit is contained in:
parent
1ce384bbda
commit
1d72fa8e9e
6 changed files with 342 additions and 337 deletions
|
@ -1,8 +1,8 @@
|
|||
use crate::branch_picker::{self, BranchList};
|
||||
use crate::git_panel::{GitPanel, commit_message_editor};
|
||||
use git::repository::CommitOptions;
|
||||
use git::{Amend, Commit, GenerateCommitMessage};
|
||||
use panel::{panel_button, panel_editor_style, panel_filled_button};
|
||||
use git::{Amend, Commit, GenerateCommitMessage, Signoff};
|
||||
use panel::{panel_button, panel_editor_style};
|
||||
use ui::{
|
||||
ContextMenu, KeybindingHint, PopoverMenu, PopoverMenuHandle, SplitButton, Tooltip, prelude::*,
|
||||
};
|
||||
|
@ -273,14 +273,51 @@ impl CommitModal {
|
|||
.child(Icon::new(IconName::ChevronDownSmall).size(IconSize::XSmall)),
|
||||
),
|
||||
)
|
||||
.menu(move |window, cx| {
|
||||
Some(ContextMenu::build(window, cx, |context_menu, _, _| {
|
||||
context_menu
|
||||
.when_some(keybinding_target.clone(), |el, keybinding_target| {
|
||||
el.context(keybinding_target.clone())
|
||||
})
|
||||
.action("Amend", Amend.boxed_clone())
|
||||
}))
|
||||
.menu({
|
||||
let git_panel_entity = self.git_panel.clone();
|
||||
move |window, cx| {
|
||||
let git_panel = git_panel_entity.read(cx);
|
||||
let amend_enabled = git_panel.amend_pending();
|
||||
let signoff_enabled = git_panel.signoff_enabled();
|
||||
let has_previous_commit = git_panel.head_commit(cx).is_some();
|
||||
|
||||
Some(ContextMenu::build(window, cx, |context_menu, _, _| {
|
||||
context_menu
|
||||
.when_some(keybinding_target.clone(), |el, keybinding_target| {
|
||||
el.context(keybinding_target.clone())
|
||||
})
|
||||
.when(has_previous_commit, |this| {
|
||||
this.toggleable_entry(
|
||||
"Amend",
|
||||
amend_enabled,
|
||||
IconPosition::Start,
|
||||
Some(Box::new(Amend)),
|
||||
{
|
||||
let git_panel = git_panel_entity.clone();
|
||||
move |window, cx| {
|
||||
git_panel.update(cx, |git_panel, cx| {
|
||||
git_panel.toggle_amend_pending(&Amend, window, cx);
|
||||
})
|
||||
}
|
||||
},
|
||||
)
|
||||
})
|
||||
.toggleable_entry(
|
||||
"Signoff",
|
||||
signoff_enabled,
|
||||
IconPosition::Start,
|
||||
Some(Box::new(Signoff)),
|
||||
{
|
||||
let git_panel = git_panel_entity.clone();
|
||||
move |window, cx| {
|
||||
git_panel.update(cx, |git_panel, cx| {
|
||||
git_panel.toggle_signoff_enabled(&Signoff, window, cx);
|
||||
})
|
||||
}
|
||||
},
|
||||
)
|
||||
}))
|
||||
}
|
||||
})
|
||||
.with_handle(self.commit_menu_handle.clone())
|
||||
.anchor(Corner::TopRight)
|
||||
|
@ -295,7 +332,7 @@ impl CommitModal {
|
|||
generate_commit_message,
|
||||
active_repo,
|
||||
is_amend_pending,
|
||||
has_previous_commit,
|
||||
is_signoff_enabled,
|
||||
) = self.git_panel.update(cx, |git_panel, cx| {
|
||||
let (can_commit, tooltip) = git_panel.configure_commit_button(cx);
|
||||
let title = git_panel.commit_button_title();
|
||||
|
@ -303,10 +340,7 @@ impl CommitModal {
|
|||
let generate_commit_message = git_panel.render_generate_commit_message_button(cx);
|
||||
let active_repo = git_panel.active_repository.clone();
|
||||
let is_amend_pending = git_panel.amend_pending();
|
||||
let has_previous_commit = active_repo
|
||||
.as_ref()
|
||||
.and_then(|repo| repo.read(cx).head_commit.as_ref())
|
||||
.is_some();
|
||||
let is_signoff_enabled = git_panel.signoff_enabled();
|
||||
(
|
||||
can_commit,
|
||||
tooltip,
|
||||
|
@ -315,7 +349,7 @@ impl CommitModal {
|
|||
generate_commit_message,
|
||||
active_repo,
|
||||
is_amend_pending,
|
||||
has_previous_commit,
|
||||
is_signoff_enabled,
|
||||
)
|
||||
});
|
||||
|
||||
|
@ -396,126 +430,59 @@ impl CommitModal {
|
|||
.px_1()
|
||||
.gap_4()
|
||||
.children(close_kb_hint)
|
||||
.when(is_amend_pending, |this| {
|
||||
let focus_handle = focus_handle.clone();
|
||||
this.child(
|
||||
panel_filled_button(commit_label)
|
||||
.tooltip(move |window, cx| {
|
||||
if can_commit {
|
||||
Tooltip::for_action_in(
|
||||
tooltip,
|
||||
&Amend,
|
||||
&focus_handle,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
} else {
|
||||
Tooltip::simple(tooltip, cx)
|
||||
}
|
||||
})
|
||||
.disabled(!can_commit)
|
||||
.on_click(cx.listener(move |this, _: &ClickEvent, window, cx| {
|
||||
telemetry::event!("Git Amended", source = "Git Modal");
|
||||
this.git_panel.update(cx, |git_panel, cx| {
|
||||
git_panel.set_amend_pending(false, cx);
|
||||
git_panel.commit_changes(
|
||||
CommitOptions { amend: true },
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
});
|
||||
cx.emit(DismissEvent);
|
||||
})),
|
||||
.child(SplitButton::new(
|
||||
ui::ButtonLike::new_rounded_left(ElementId::Name(
|
||||
format!("split-button-left-{}", commit_label).into(),
|
||||
))
|
||||
.layer(ui::ElevationIndex::ModalSurface)
|
||||
.size(ui::ButtonSize::Compact)
|
||||
.child(
|
||||
div()
|
||||
.child(Label::new(commit_label).size(LabelSize::Small))
|
||||
.mr_0p5(),
|
||||
)
|
||||
})
|
||||
.when(!is_amend_pending, |this| {
|
||||
this.when(has_previous_commit, |this| {
|
||||
this.child(SplitButton::new(
|
||||
ui::ButtonLike::new_rounded_left(ElementId::Name(
|
||||
format!("split-button-left-{}", commit_label).into(),
|
||||
))
|
||||
.layer(ui::ElevationIndex::ModalSurface)
|
||||
.size(ui::ButtonSize::Compact)
|
||||
.child(
|
||||
div()
|
||||
.child(Label::new(commit_label).size(LabelSize::Small))
|
||||
.mr_0p5(),
|
||||
.on_click(cx.listener(move |this, _: &ClickEvent, window, cx| {
|
||||
telemetry::event!("Git Committed", source = "Git Modal");
|
||||
this.git_panel.update(cx, |git_panel, cx| {
|
||||
git_panel.commit_changes(
|
||||
CommitOptions {
|
||||
amend: is_amend_pending,
|
||||
signoff: is_signoff_enabled,
|
||||
},
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
.on_click(cx.listener(move |this, _: &ClickEvent, window, cx| {
|
||||
telemetry::event!("Git Committed", source = "Git Modal");
|
||||
this.git_panel.update(cx, |git_panel, cx| {
|
||||
git_panel.commit_changes(
|
||||
CommitOptions { amend: false },
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
});
|
||||
cx.emit(DismissEvent);
|
||||
}))
|
||||
.disabled(!can_commit)
|
||||
.tooltip({
|
||||
let focus_handle = focus_handle.clone();
|
||||
move |window, cx| {
|
||||
if can_commit {
|
||||
Tooltip::with_meta_in(
|
||||
tooltip,
|
||||
Some(&git::Commit),
|
||||
"git commit",
|
||||
&focus_handle.clone(),
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
} else {
|
||||
Tooltip::simple(tooltip, cx)
|
||||
}
|
||||
}
|
||||
}),
|
||||
self.render_git_commit_menu(
|
||||
ElementId::Name(
|
||||
format!("split-button-right-{}", commit_label).into(),
|
||||
),
|
||||
Some(focus_handle.clone()),
|
||||
)
|
||||
.into_any_element(),
|
||||
))
|
||||
})
|
||||
.when(!has_previous_commit, |this| {
|
||||
this.child(
|
||||
panel_filled_button(commit_label)
|
||||
.tooltip(move |window, cx| {
|
||||
if can_commit {
|
||||
Tooltip::with_meta_in(
|
||||
tooltip,
|
||||
Some(&git::Commit),
|
||||
"git commit",
|
||||
&focus_handle,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
} else {
|
||||
Tooltip::simple(tooltip, cx)
|
||||
}
|
||||
})
|
||||
.disabled(!can_commit)
|
||||
.on_click(cx.listener(
|
||||
move |this, _: &ClickEvent, window, cx| {
|
||||
telemetry::event!(
|
||||
"Git Committed",
|
||||
source = "Git Modal"
|
||||
);
|
||||
this.git_panel.update(cx, |git_panel, cx| {
|
||||
git_panel.commit_changes(
|
||||
CommitOptions { amend: false },
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
});
|
||||
cx.emit(DismissEvent);
|
||||
},
|
||||
)),
|
||||
)
|
||||
})
|
||||
}),
|
||||
});
|
||||
cx.emit(DismissEvent);
|
||||
}))
|
||||
.disabled(!can_commit)
|
||||
.tooltip({
|
||||
let focus_handle = focus_handle.clone();
|
||||
move |window, cx| {
|
||||
if can_commit {
|
||||
Tooltip::with_meta_in(
|
||||
tooltip,
|
||||
Some(&git::Commit),
|
||||
format!(
|
||||
"git commit{}{}",
|
||||
if is_amend_pending { " --amend" } else { "" },
|
||||
if is_signoff_enabled { " --signoff" } else { "" }
|
||||
),
|
||||
&focus_handle.clone(),
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
} else {
|
||||
Tooltip::simple(tooltip, cx)
|
||||
}
|
||||
}
|
||||
}),
|
||||
self.render_git_commit_menu(
|
||||
ElementId::Name(format!("split-button-right-{}", commit_label).into()),
|
||||
Some(focus_handle.clone()),
|
||||
)
|
||||
.into_any_element(),
|
||||
)),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -534,7 +501,14 @@ impl CommitModal {
|
|||
}
|
||||
telemetry::event!("Git Committed", source = "Git Modal");
|
||||
self.git_panel.update(cx, |git_panel, cx| {
|
||||
git_panel.commit_changes(CommitOptions { amend: false }, window, cx)
|
||||
git_panel.commit_changes(
|
||||
CommitOptions {
|
||||
amend: false,
|
||||
signoff: git_panel.signoff_enabled(),
|
||||
},
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
});
|
||||
cx.emit(DismissEvent);
|
||||
}
|
||||
|
@ -559,7 +533,14 @@ impl CommitModal {
|
|||
telemetry::event!("Git Amended", source = "Git Modal");
|
||||
self.git_panel.update(cx, |git_panel, cx| {
|
||||
git_panel.set_amend_pending(false, cx);
|
||||
git_panel.commit_changes(CommitOptions { amend: true }, window, cx);
|
||||
git_panel.commit_changes(
|
||||
CommitOptions {
|
||||
amend: true,
|
||||
signoff: git_panel.signoff_enabled(),
|
||||
},
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
});
|
||||
cx.emit(DismissEvent);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue