mirror of
https://github.com/extrawurst/gitui.git
synced 2024-11-22 02:12:58 +03:00
support reset from log view (#1534)
This commit is contained in:
parent
1a0167e7f8
commit
8ab62244ce
@ -7,11 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
**reset to commit**
|
||||||
|
|
||||||
|
![reset](assets/reset_in_log.gif)
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
* changes in commit message inside external editor [[@bc-universe]](https://github.com/bc-universe) ([#1420](https://github.com/extrawurst/gitui/issues/1420))
|
* changes in commit message inside external editor [[@bc-universe]](https://github.com/bc-universe) ([#1420](https://github.com/extrawurst/gitui/issues/1420))
|
||||||
* allow detaching HEAD and checking out specific commit from log view [[@fralcow]](https://github.com/fralcow) ([#1499](https://github.com/extrawurst/gitui/pull/1499))
|
* allow detaching HEAD and checking out specific commit from log view [[@fralcow]](https://github.com/fralcow) ([#1499](https://github.com/extrawurst/gitui/pull/1499))
|
||||||
* add no-verify option on commits to not run hooks [[@dam5h]](https://github.com/dam5h) ([#1374](https://github.com/extrawurst/gitui/issues/1374))
|
* add no-verify option on commits to not run hooks [[@dam5h]](https://github.com/dam5h) ([#1374](https://github.com/extrawurst/gitui/issues/1374))
|
||||||
* allow `fetch` on status tab [[@alensiljak]](https://github.com/alensiljak) ([#1471](https://github.com/extrawurst/gitui/issues/1471))
|
* allow `fetch` on status tab [[@alensiljak]](https://github.com/alensiljak) ([#1471](https://github.com/extrawurst/gitui/issues/1471))
|
||||||
|
* allow reset (soft,mixed,hard) from commit log ([#1500](https://github.com/extrawurst/gitui/issues/1500))
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
* commit msg history ordered the wrong way ([#1445](https://github.com/extrawurst/gitui/issues/1445))
|
* commit msg history ordered the wrong way ([#1445](https://github.com/extrawurst/gitui/issues/1445))
|
||||||
|
BIN
assets/reset_in_log.gif
Normal file
BIN
assets/reset_in_log.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 MiB |
@ -75,7 +75,7 @@ pub use remotes::{
|
|||||||
};
|
};
|
||||||
pub(crate) use repository::repo;
|
pub(crate) use repository::repo;
|
||||||
pub use repository::{RepoPath, RepoPathRef};
|
pub use repository::{RepoPath, RepoPathRef};
|
||||||
pub use reset::{reset_stage, reset_workdir};
|
pub use reset::{reset_repo, reset_stage, reset_workdir};
|
||||||
pub use staging::{discard_lines, stage_lines};
|
pub use staging::{discard_lines, stage_lines};
|
||||||
pub use stash::{
|
pub use stash::{
|
||||||
get_stashes, stash_apply, stash_drop, stash_pop, stash_save,
|
get_stashes, stash_apply, stash_drop, stash_pop, stash_save,
|
||||||
@ -96,6 +96,8 @@ pub use utils::{
|
|||||||
stage_add_file, stage_addremoved, Head,
|
stage_add_file, stage_addremoved, Head,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub use git2::ResetType;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{
|
use super::{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use super::{utils::get_head_repo, RepoPath};
|
use super::{utils::get_head_repo, CommitId, RepoPath};
|
||||||
use crate::{error::Result, sync::repository::repo};
|
use crate::{error::Result, sync::repository::repo};
|
||||||
use git2::{build::CheckoutBuilder, ObjectType};
|
use git2::{build::CheckoutBuilder, ObjectType, ResetType};
|
||||||
use scopetime::scope_time;
|
use scopetime::scope_time;
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -38,6 +38,23 @@ pub fn reset_workdir(repo_path: &RepoPath, path: &str) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn reset_repo(
|
||||||
|
repo_path: &RepoPath,
|
||||||
|
commit: CommitId,
|
||||||
|
kind: ResetType,
|
||||||
|
) -> Result<()> {
|
||||||
|
scope_time!("reset_repo");
|
||||||
|
|
||||||
|
let repo = repo(repo_path)?;
|
||||||
|
|
||||||
|
let c = repo.find_commit(commit.into())?;
|
||||||
|
|
||||||
|
repo.reset(c.as_object(), kind, None)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{reset_stage, reset_workdir};
|
use super::{reset_stage, reset_workdir};
|
||||||
|
15
src/app.rs
15
src/app.rs
@ -10,7 +10,7 @@ use crate::{
|
|||||||
FileRevlogComponent, HelpComponent, InspectCommitComponent,
|
FileRevlogComponent, HelpComponent, InspectCommitComponent,
|
||||||
MsgComponent, OptionsPopupComponent, PullComponent,
|
MsgComponent, OptionsPopupComponent, PullComponent,
|
||||||
PushComponent, PushTagsComponent, RenameBranchComponent,
|
PushComponent, PushTagsComponent, RenameBranchComponent,
|
||||||
RevisionFilesPopup, StashMsgComponent,
|
ResetPopupComponent, RevisionFilesPopup, StashMsgComponent,
|
||||||
SubmodulesListComponent, TagCommitComponent,
|
SubmodulesListComponent, TagCommitComponent,
|
||||||
TagListComponent,
|
TagListComponent,
|
||||||
},
|
},
|
||||||
@ -84,6 +84,7 @@ pub struct App {
|
|||||||
options_popup: OptionsPopupComponent,
|
options_popup: OptionsPopupComponent,
|
||||||
submodule_popup: SubmodulesListComponent,
|
submodule_popup: SubmodulesListComponent,
|
||||||
tags_popup: TagListComponent,
|
tags_popup: TagListComponent,
|
||||||
|
reset_popup: ResetPopupComponent,
|
||||||
cmdbar: RefCell<CommandBar>,
|
cmdbar: RefCell<CommandBar>,
|
||||||
tab: usize,
|
tab: usize,
|
||||||
revlog: Revlog,
|
revlog: Revlog,
|
||||||
@ -204,6 +205,12 @@ impl App {
|
|||||||
theme.clone(),
|
theme.clone(),
|
||||||
key_config.clone(),
|
key_config.clone(),
|
||||||
),
|
),
|
||||||
|
reset_popup: ResetPopupComponent::new(
|
||||||
|
&queue,
|
||||||
|
&repo,
|
||||||
|
theme.clone(),
|
||||||
|
key_config.clone(),
|
||||||
|
),
|
||||||
pull_popup: PullComponent::new(
|
pull_popup: PullComponent::new(
|
||||||
&repo,
|
&repo,
|
||||||
&queue,
|
&queue,
|
||||||
@ -484,6 +491,7 @@ impl App {
|
|||||||
self.files_tab.update()?;
|
self.files_tab.update()?;
|
||||||
self.stashing_tab.update()?;
|
self.stashing_tab.update()?;
|
||||||
self.stashlist_tab.update()?;
|
self.stashlist_tab.update()?;
|
||||||
|
self.reset_popup.update()?;
|
||||||
|
|
||||||
self.update_commands();
|
self.update_commands();
|
||||||
|
|
||||||
@ -590,6 +598,7 @@ impl App {
|
|||||||
revision_files_popup,
|
revision_files_popup,
|
||||||
submodule_popup,
|
submodule_popup,
|
||||||
tags_popup,
|
tags_popup,
|
||||||
|
reset_popup,
|
||||||
options_popup,
|
options_popup,
|
||||||
help,
|
help,
|
||||||
revlog,
|
revlog,
|
||||||
@ -615,6 +624,7 @@ impl App {
|
|||||||
select_branch_popup,
|
select_branch_popup,
|
||||||
submodule_popup,
|
submodule_popup,
|
||||||
tags_popup,
|
tags_popup,
|
||||||
|
reset_popup,
|
||||||
create_branch_popup,
|
create_branch_popup,
|
||||||
rename_branch_popup,
|
rename_branch_popup,
|
||||||
revision_files_popup,
|
revision_files_popup,
|
||||||
@ -926,6 +936,9 @@ impl App {
|
|||||||
self.do_quit =
|
self.do_quit =
|
||||||
QuitState::OpenSubmodule(submodule_repo_path);
|
QuitState::OpenSubmodule(submodule_repo_path);
|
||||||
}
|
}
|
||||||
|
InternalEvent::OpenResetPopup(id) => {
|
||||||
|
self.reset_popup.open(id)?;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(flags)
|
Ok(flags)
|
||||||
|
@ -22,6 +22,7 @@ mod push;
|
|||||||
mod push_tags;
|
mod push_tags;
|
||||||
mod rename_branch;
|
mod rename_branch;
|
||||||
mod reset;
|
mod reset;
|
||||||
|
mod reset_popup;
|
||||||
mod revision_files;
|
mod revision_files;
|
||||||
mod revision_files_popup;
|
mod revision_files_popup;
|
||||||
mod stashmsg;
|
mod stashmsg;
|
||||||
@ -57,6 +58,7 @@ pub use push::PushComponent;
|
|||||||
pub use push_tags::PushTagsComponent;
|
pub use push_tags::PushTagsComponent;
|
||||||
pub use rename_branch::RenameBranchComponent;
|
pub use rename_branch::RenameBranchComponent;
|
||||||
pub use reset::ConfirmComponent;
|
pub use reset::ConfirmComponent;
|
||||||
|
pub use reset_popup::ResetPopupComponent;
|
||||||
pub use revision_files::RevisionFilesComponent;
|
pub use revision_files::RevisionFilesComponent;
|
||||||
pub use revision_files_popup::{FileTreeOpen, RevisionFilesPopup};
|
pub use revision_files_popup::{FileTreeOpen, RevisionFilesPopup};
|
||||||
pub use stashmsg::StashMsgComponent;
|
pub use stashmsg::StashMsgComponent;
|
||||||
|
272
src/components/reset_popup.rs
Normal file
272
src/components/reset_popup.rs
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
use super::{
|
||||||
|
visibility_blocking, CommandBlocking, CommandInfo, Component,
|
||||||
|
DrawableComponent, EventState,
|
||||||
|
};
|
||||||
|
use crate::{
|
||||||
|
keys::{key_match, SharedKeyConfig},
|
||||||
|
queue::Queue,
|
||||||
|
strings, try_or_popup,
|
||||||
|
ui::{self, style::SharedTheme},
|
||||||
|
};
|
||||||
|
use anyhow::Result;
|
||||||
|
use asyncgit::{
|
||||||
|
cached,
|
||||||
|
sync::{CommitId, RepoPath, RepoPathRef, ResetType},
|
||||||
|
};
|
||||||
|
use crossterm::event::Event;
|
||||||
|
use tui::{
|
||||||
|
backend::Backend,
|
||||||
|
layout::{Alignment, Rect},
|
||||||
|
text::{Span, Spans},
|
||||||
|
widgets::{Block, Borders, Clear, Paragraph},
|
||||||
|
Frame,
|
||||||
|
};
|
||||||
|
|
||||||
|
const fn type_to_string(
|
||||||
|
kind: ResetType,
|
||||||
|
) -> (&'static str, &'static str) {
|
||||||
|
const RESET_TYPE_DESC_SOFT: &str =
|
||||||
|
" 🟢 Keep all changes. Stage differences";
|
||||||
|
const RESET_TYPE_DESC_MIXED: &str =
|
||||||
|
" 🟡 Keep all changes. Unstage differences";
|
||||||
|
const RESET_TYPE_DESC_HARD: &str =
|
||||||
|
" 🔴 Discard all local changes";
|
||||||
|
|
||||||
|
match kind {
|
||||||
|
ResetType::Soft => ("Soft", RESET_TYPE_DESC_SOFT),
|
||||||
|
ResetType::Mixed => ("Mixed", RESET_TYPE_DESC_MIXED),
|
||||||
|
ResetType::Hard => ("Hard", RESET_TYPE_DESC_HARD),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ResetPopupComponent {
|
||||||
|
queue: Queue,
|
||||||
|
repo: RepoPath,
|
||||||
|
commit: Option<CommitId>,
|
||||||
|
kind: ResetType,
|
||||||
|
git_branch_name: cached::BranchName,
|
||||||
|
visible: bool,
|
||||||
|
key_config: SharedKeyConfig,
|
||||||
|
theme: SharedTheme,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ResetPopupComponent {
|
||||||
|
///
|
||||||
|
pub fn new(
|
||||||
|
queue: &Queue,
|
||||||
|
repo: &RepoPathRef,
|
||||||
|
theme: SharedTheme,
|
||||||
|
key_config: SharedKeyConfig,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
queue: queue.clone(),
|
||||||
|
repo: repo.borrow().clone(),
|
||||||
|
commit: None,
|
||||||
|
kind: ResetType::Soft,
|
||||||
|
git_branch_name: cached::BranchName::new(repo.clone()),
|
||||||
|
visible: false,
|
||||||
|
key_config,
|
||||||
|
theme,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_text(&self, _width: u16) -> Vec<Spans> {
|
||||||
|
let mut txt: Vec<Spans> = Vec::with_capacity(10);
|
||||||
|
|
||||||
|
txt.push(Spans::from(vec![
|
||||||
|
Span::styled(
|
||||||
|
String::from("Branch: "),
|
||||||
|
self.theme.text(true, false),
|
||||||
|
),
|
||||||
|
Span::styled(
|
||||||
|
self.git_branch_name.last().unwrap_or_default(),
|
||||||
|
self.theme.branch(false, true),
|
||||||
|
),
|
||||||
|
]));
|
||||||
|
|
||||||
|
txt.push(Spans::from(vec![
|
||||||
|
Span::styled(
|
||||||
|
String::from("Reset to: "),
|
||||||
|
self.theme.text(true, false),
|
||||||
|
),
|
||||||
|
Span::styled(
|
||||||
|
self.commit
|
||||||
|
.map(|c| c.to_string())
|
||||||
|
.unwrap_or_default(),
|
||||||
|
self.theme.commit_hash(false),
|
||||||
|
),
|
||||||
|
]));
|
||||||
|
|
||||||
|
let (kind_name, kind_desc) = type_to_string(self.kind);
|
||||||
|
|
||||||
|
txt.push(Spans::from(vec![
|
||||||
|
Span::styled(
|
||||||
|
String::from("How: "),
|
||||||
|
self.theme.text(true, false),
|
||||||
|
),
|
||||||
|
Span::styled(kind_name, self.theme.text(true, true)),
|
||||||
|
Span::styled(kind_desc, self.theme.text(true, false)),
|
||||||
|
]));
|
||||||
|
|
||||||
|
txt
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn open(&mut self, id: CommitId) -> Result<()> {
|
||||||
|
self.show()?;
|
||||||
|
|
||||||
|
self.commit = Some(id);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
#[allow(clippy::unnecessary_wraps)]
|
||||||
|
pub fn update(&mut self) -> Result<()> {
|
||||||
|
self.git_branch_name.lookup().map(Some).unwrap_or(None);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reset(&mut self) {
|
||||||
|
if let Some(id) = self.commit {
|
||||||
|
try_or_popup!(
|
||||||
|
self,
|
||||||
|
"reset:",
|
||||||
|
asyncgit::sync::reset_repo(&self.repo, id, self.kind)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn change_kind(&mut self, incr: bool) {
|
||||||
|
self.kind = if incr {
|
||||||
|
match self.kind {
|
||||||
|
ResetType::Soft => ResetType::Mixed,
|
||||||
|
ResetType::Mixed => ResetType::Hard,
|
||||||
|
ResetType::Hard => ResetType::Soft,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
match self.kind {
|
||||||
|
ResetType::Soft => ResetType::Hard,
|
||||||
|
ResetType::Mixed => ResetType::Soft,
|
||||||
|
ResetType::Hard => ResetType::Mixed,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DrawableComponent for ResetPopupComponent {
|
||||||
|
fn draw<B: Backend>(
|
||||||
|
&self,
|
||||||
|
f: &mut Frame<B>,
|
||||||
|
area: Rect,
|
||||||
|
) -> Result<()> {
|
||||||
|
if self.is_visible() {
|
||||||
|
const SIZE: (u16, u16) = (55, 5);
|
||||||
|
let area =
|
||||||
|
ui::centered_rect_absolute(SIZE.0, SIZE.1, area);
|
||||||
|
|
||||||
|
let width = area.width;
|
||||||
|
|
||||||
|
f.render_widget(Clear, area);
|
||||||
|
f.render_widget(
|
||||||
|
Paragraph::new(self.get_text(width))
|
||||||
|
.block(
|
||||||
|
Block::default()
|
||||||
|
.borders(Borders::ALL)
|
||||||
|
.title(Span::styled(
|
||||||
|
"Reset",
|
||||||
|
self.theme.title(true),
|
||||||
|
))
|
||||||
|
.border_style(self.theme.block(true)),
|
||||||
|
)
|
||||||
|
.alignment(Alignment::Left),
|
||||||
|
area,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Component for ResetPopupComponent {
|
||||||
|
fn commands(
|
||||||
|
&self,
|
||||||
|
out: &mut Vec<CommandInfo>,
|
||||||
|
force_all: bool,
|
||||||
|
) -> CommandBlocking {
|
||||||
|
if self.is_visible() || force_all {
|
||||||
|
out.push(
|
||||||
|
CommandInfo::new(
|
||||||
|
strings::commands::close_popup(&self.key_config),
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
.order(1),
|
||||||
|
);
|
||||||
|
|
||||||
|
out.push(
|
||||||
|
CommandInfo::new(
|
||||||
|
strings::commands::reset_commit(&self.key_config),
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
.order(1),
|
||||||
|
);
|
||||||
|
|
||||||
|
out.push(
|
||||||
|
CommandInfo::new(
|
||||||
|
strings::commands::reset_type(&self.key_config),
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
.order(1),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
visibility_blocking(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn event(
|
||||||
|
&mut self,
|
||||||
|
event: &crossterm::event::Event,
|
||||||
|
) -> Result<EventState> {
|
||||||
|
if self.is_visible() {
|
||||||
|
if let Event::Key(key) = &event {
|
||||||
|
if key_match(key, self.key_config.keys.exit_popup) {
|
||||||
|
self.hide();
|
||||||
|
} else if key_match(
|
||||||
|
key,
|
||||||
|
self.key_config.keys.move_down,
|
||||||
|
) {
|
||||||
|
self.change_kind(true);
|
||||||
|
} else if key_match(key, self.key_config.keys.move_up)
|
||||||
|
{
|
||||||
|
self.change_kind(false);
|
||||||
|
} else if key_match(key, self.key_config.keys.enter) {
|
||||||
|
self.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(EventState::Consumed);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(EventState::NotConsumed)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_visible(&self) -> bool {
|
||||||
|
self.visible
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hide(&mut self) {
|
||||||
|
self.visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show(&mut self) -> Result<()> {
|
||||||
|
self.visible = true;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
@ -16,10 +16,12 @@ macro_rules! try_or_popup {
|
|||||||
($self:ident, $msg:expr, $e:expr) => {
|
($self:ident, $msg:expr, $e:expr) => {
|
||||||
if let Err(err) = $e {
|
if let Err(err) = $e {
|
||||||
::log::error!("{} {}", $msg, err);
|
::log::error!("{} {}", $msg, err);
|
||||||
$self.queue.push(InternalEvent::ShowErrorMsg(format!(
|
$self.queue.push(
|
||||||
"{}\n{}",
|
$crate::queue::InternalEvent::ShowErrorMsg(format!(
|
||||||
$msg, err
|
"{}\n{}",
|
||||||
)));
|
$msg, err
|
||||||
|
)),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -88,6 +88,7 @@ pub struct KeysList {
|
|||||||
pub log_tag_commit: GituiKeyEvent,
|
pub log_tag_commit: GituiKeyEvent,
|
||||||
pub log_mark_commit: GituiKeyEvent,
|
pub log_mark_commit: GituiKeyEvent,
|
||||||
pub log_checkout_commit: GituiKeyEvent,
|
pub log_checkout_commit: GituiKeyEvent,
|
||||||
|
pub log_reset_comit: GituiKeyEvent,
|
||||||
pub commit_amend: GituiKeyEvent,
|
pub commit_amend: GituiKeyEvent,
|
||||||
pub toggle_verify: GituiKeyEvent,
|
pub toggle_verify: GituiKeyEvent,
|
||||||
pub copy: GituiKeyEvent,
|
pub copy: GituiKeyEvent,
|
||||||
@ -173,6 +174,7 @@ impl Default for KeysList {
|
|||||||
log_tag_commit: GituiKeyEvent::new(KeyCode::Char('t'), KeyModifiers::empty()),
|
log_tag_commit: GituiKeyEvent::new(KeyCode::Char('t'), KeyModifiers::empty()),
|
||||||
log_mark_commit: GituiKeyEvent::new(KeyCode::Char(' '), KeyModifiers::empty()),
|
log_mark_commit: GituiKeyEvent::new(KeyCode::Char(' '), KeyModifiers::empty()),
|
||||||
log_checkout_commit: GituiKeyEvent { code: KeyCode::Char('S'), modifiers: KeyModifiers::SHIFT },
|
log_checkout_commit: GituiKeyEvent { code: KeyCode::Char('S'), modifiers: KeyModifiers::SHIFT },
|
||||||
|
log_reset_comit: GituiKeyEvent { code: KeyCode::Char('R'), modifiers: KeyModifiers::SHIFT },
|
||||||
commit_amend: GituiKeyEvent::new(KeyCode::Char('a'), KeyModifiers::CONTROL),
|
commit_amend: GituiKeyEvent::new(KeyCode::Char('a'), KeyModifiers::CONTROL),
|
||||||
toggle_verify: GituiKeyEvent::new(KeyCode::Char('f'), KeyModifiers::CONTROL),
|
toggle_verify: GituiKeyEvent::new(KeyCode::Char('f'), KeyModifiers::CONTROL),
|
||||||
copy: GituiKeyEvent::new(KeyCode::Char('y'), KeyModifiers::empty()),
|
copy: GituiKeyEvent::new(KeyCode::Char('y'), KeyModifiers::empty()),
|
||||||
|
@ -59,6 +59,7 @@ pub struct KeysListFile {
|
|||||||
pub log_tag_commit: Option<GituiKeyEvent>,
|
pub log_tag_commit: Option<GituiKeyEvent>,
|
||||||
pub log_mark_commit: Option<GituiKeyEvent>,
|
pub log_mark_commit: Option<GituiKeyEvent>,
|
||||||
pub log_checkout_commit: Option<GituiKeyEvent>,
|
pub log_checkout_commit: Option<GituiKeyEvent>,
|
||||||
|
pub log_reset_commit: Option<GituiKeyEvent>,
|
||||||
pub commit_amend: Option<GituiKeyEvent>,
|
pub commit_amend: Option<GituiKeyEvent>,
|
||||||
pub toggle_verify: Option<GituiKeyEvent>,
|
pub toggle_verify: Option<GituiKeyEvent>,
|
||||||
pub copy: Option<GituiKeyEvent>,
|
pub copy: Option<GituiKeyEvent>,
|
||||||
@ -153,6 +154,7 @@ impl KeysListFile {
|
|||||||
log_tag_commit: self.log_tag_commit.unwrap_or(default.log_tag_commit),
|
log_tag_commit: self.log_tag_commit.unwrap_or(default.log_tag_commit),
|
||||||
log_mark_commit: self.log_mark_commit.unwrap_or(default.log_mark_commit),
|
log_mark_commit: self.log_mark_commit.unwrap_or(default.log_mark_commit),
|
||||||
log_checkout_commit: self.log_checkout_commit.unwrap_or(default.log_checkout_commit),
|
log_checkout_commit: self.log_checkout_commit.unwrap_or(default.log_checkout_commit),
|
||||||
|
log_reset_comit: self.log_reset_commit.unwrap_or(default.log_reset_comit),
|
||||||
commit_amend: self.commit_amend.unwrap_or(default.commit_amend),
|
commit_amend: self.commit_amend.unwrap_or(default.commit_amend),
|
||||||
toggle_verify: self.toggle_verify.unwrap_or(default.toggle_verify),
|
toggle_verify: self.toggle_verify.unwrap_or(default.toggle_verify),
|
||||||
copy: self.copy.unwrap_or(default.copy),
|
copy: self.copy.unwrap_or(default.copy),
|
||||||
|
@ -126,6 +126,8 @@ pub enum InternalEvent {
|
|||||||
ViewSubmodules,
|
ViewSubmodules,
|
||||||
///
|
///
|
||||||
OpenRepo { path: PathBuf },
|
OpenRepo { path: PathBuf },
|
||||||
|
///
|
||||||
|
OpenResetPopup(CommitId),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// single threaded simple queue for components to communicate with each other
|
/// single threaded simple queue for components to communicate with each other
|
||||||
|
@ -1233,6 +1233,39 @@ pub mod commands {
|
|||||||
CMD_GROUP_LOG,
|
CMD_GROUP_LOG,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
pub fn log_reset_commit(
|
||||||
|
key_config: &SharedKeyConfig,
|
||||||
|
) -> CommandText {
|
||||||
|
CommandText::new(
|
||||||
|
format!(
|
||||||
|
"Reset [{}]",
|
||||||
|
key_config.get_hint(key_config.keys.log_reset_comit),
|
||||||
|
),
|
||||||
|
"reset to commit",
|
||||||
|
CMD_GROUP_LOG,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
pub fn reset_commit(key_config: &SharedKeyConfig) -> CommandText {
|
||||||
|
CommandText::new(
|
||||||
|
format!(
|
||||||
|
"Confirm [{}]",
|
||||||
|
key_config.get_hint(key_config.keys.enter),
|
||||||
|
),
|
||||||
|
"confirm reset",
|
||||||
|
CMD_GROUP_LOG,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
pub fn reset_type(key_config: &SharedKeyConfig) -> CommandText {
|
||||||
|
CommandText::new(
|
||||||
|
format!(
|
||||||
|
"Change Type [{}{}]",
|
||||||
|
key_config.get_hint(key_config.keys.move_up),
|
||||||
|
key_config.get_hint(key_config.keys.move_down)
|
||||||
|
),
|
||||||
|
"change reset type",
|
||||||
|
CMD_GROUP_LOG,
|
||||||
|
)
|
||||||
|
}
|
||||||
pub fn tag_commit_confirm_msg(
|
pub fn tag_commit_confirm_msg(
|
||||||
key_config: &SharedKeyConfig,
|
key_config: &SharedKeyConfig,
|
||||||
) -> CommandText {
|
) -> CommandText {
|
||||||
|
@ -327,6 +327,19 @@ impl Component for Revlog {
|
|||||||
} else if key_match(k, self.key_config.keys.tags) {
|
} else if key_match(k, self.key_config.keys.tags) {
|
||||||
self.queue.push(InternalEvent::Tags);
|
self.queue.push(InternalEvent::Tags);
|
||||||
return Ok(EventState::Consumed);
|
return Ok(EventState::Consumed);
|
||||||
|
} else if key_match(
|
||||||
|
k,
|
||||||
|
self.key_config.keys.log_reset_comit,
|
||||||
|
) {
|
||||||
|
return self.selected_commit().map_or(
|
||||||
|
Ok(EventState::NotConsumed),
|
||||||
|
|id| {
|
||||||
|
self.queue.push(
|
||||||
|
InternalEvent::OpenResetPopup(id),
|
||||||
|
);
|
||||||
|
Ok(EventState::Consumed)
|
||||||
|
},
|
||||||
|
);
|
||||||
} else if key_match(
|
} else if key_match(
|
||||||
k,
|
k,
|
||||||
self.key_config.keys.compare_commits,
|
self.key_config.keys.compare_commits,
|
||||||
@ -449,6 +462,12 @@ impl Component for Revlog {
|
|||||||
self.visible || force_all,
|
self.visible || force_all,
|
||||||
));
|
));
|
||||||
|
|
||||||
|
out.push(CommandInfo::new(
|
||||||
|
strings::commands::log_reset_commit(&self.key_config),
|
||||||
|
self.selected_commit().is_some(),
|
||||||
|
self.visible || force_all,
|
||||||
|
));
|
||||||
|
|
||||||
visibility_blocking(self)
|
visibility_blocking(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user