Skip to content

Add undo_last_commit command #769

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

## Added
- undo-last-commit command under `[U]` key [[@remique](https://github.com/remique)] ([#758](https://github.com/extrawurst/gitui/issues/758))

## Fixed
- openssl vendoring broken on macos ([#772](https://github.com/extrawurst/gitui/issues/772))

Expand Down
56 changes: 55 additions & 1 deletion asyncgit/src/sync/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,21 @@ pub fn stage_add_all(repo_path: &str, pattern: &str) -> Result<()> {
Ok(())
}

/// Undo last commit in repo
pub fn undo_last_commit(repo_path: &str) -> Result<()> {
let repo = repo(repo_path)?;
let previous_commit = repo.revparse_single("HEAD~")?;

Repository::reset(
&repo,
&previous_commit,
git2::ResetType::Soft,
None,
)?;

Ok(())
}

/// stage a removed file
pub fn stage_addremoved(repo_path: &str, path: &Path) -> Result<()> {
scope_time!("stage_addremoved");
Expand Down Expand Up @@ -206,9 +221,11 @@ mod tests {
use super::*;
use crate::sync::{
commit,
diff::get_diff,
status::{get_status, StatusType},
tests::{
debug_cmd_print, get_statuses, repo_init, repo_init_empty,
debug_cmd_print, get_statuses, repo_init,
repo_init_empty, write_commit_file,
},
};
use std::{
Expand Down Expand Up @@ -282,6 +299,43 @@ mod tests {
Ok(())
}

#[test]
fn test_undo_commit_empty_repo() {
let (_td, repo) = repo_init().unwrap();
let root = repo.path().parent().unwrap();
let repo_path = root.as_os_str().to_str().unwrap();

// expect to fail
assert!(undo_last_commit(repo_path).is_err());
}

#[test]
fn test_undo_commit() {
let (_td, repo) = repo_init().unwrap();
let root = repo.path().parent().unwrap();
let repo_path = root.as_os_str().to_str().unwrap();

// write commit file test.txt
let c1 =
write_commit_file(&repo, "test.txt", "content1", "c1");
let _c2 =
write_commit_file(&repo, "test.txt", "content2", "c2");
assert!(undo_last_commit(repo_path).is_ok());

// Make sure that HEAD points to c1
assert_eq!(c1, get_head_repo(&repo).unwrap());

// Make sure that now we have 1 file staged
assert_eq!(get_statuses(repo_path), (0, 1));

// And that file is test.txt
let diff = get_diff(repo_path, "test.txt", true).unwrap();
assert_eq!(
diff.hunks[0].lines[0].content,
String::from("@@ -1 +1 @@\n")
);
}

#[test]
fn test_not_staging_untracked_folder() -> Result<()> {
let (_td, repo) = repo_init().unwrap();
Expand Down
2 changes: 2 additions & 0 deletions src/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ pub struct KeyConfig {
pub force_push: KeyEvent,
pub pull: KeyEvent,
pub abort_merge: KeyEvent,
pub undo_commit: KeyEvent,
}

#[rustfmt::skip]
Expand Down Expand Up @@ -144,6 +145,7 @@ impl Default for KeyConfig {
select_tag: KeyEvent { code: KeyCode::Enter, modifiers: KeyModifiers::empty()},
push: KeyEvent { code: KeyCode::Char('p'), modifiers: KeyModifiers::empty()},
force_push: KeyEvent { code: KeyCode::Char('P'), modifiers: KeyModifiers::SHIFT},
undo_commit: KeyEvent { code: KeyCode::Char('U'), modifiers: KeyModifiers::SHIFT},
pull: KeyEvent { code: KeyCode::Char('f'), modifiers: KeyModifiers::empty()},
abort_merge: KeyEvent { code: KeyCode::Char('M'), modifiers: KeyModifiers::SHIFT},
open_file_tree: KeyEvent { code: KeyCode::Char('F'), modifiers: KeyModifiers::SHIFT},
Expand Down
10 changes: 10 additions & 0 deletions src/strings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,16 @@ pub mod commands {
CMD_GROUP_GENERAL,
)
}
pub fn undo_commit(key_config: &SharedKeyConfig) -> CommandText {
CommandText::new(
format!(
"Undo Commit [{}]",
key_config.get_hint(key_config.undo_commit),
),
"undo last commit",
CMD_GROUP_GENERAL,
)
}
pub fn commit_open(key_config: &SharedKeyConfig) -> CommandText {
CommandText::new(
format!(
Expand Down
24 changes: 23 additions & 1 deletion src/tabs/status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
FileTreeItemKind,
},
keys::SharedKeyConfig,
queue::{Action, InternalEvent, Queue, ResetItem},
queue::{Action, InternalEvent, NeedsUpdate, Queue, ResetItem},
strings, try_or_popup,
ui::style::SharedTheme,
};
Expand Down Expand Up @@ -468,6 +468,14 @@ impl Status {
}
}

fn undo_last_commit(&self) {
try_or_popup!(
self,
"undo commit failed:",
sync::utils::undo_last_commit(CWD)
);
}

fn branch_compare(&mut self) {
self.git_branch_state =
self.git_branch_name.last().and_then(|branch| {
Expand Down Expand Up @@ -579,6 +587,12 @@ impl Component for Status {
!focus_on_diff,
));

out.push(CommandInfo::new(
strings::commands::undo_commit(&self.key_config),
true,
!focus_on_diff,
));

out.push(CommandInfo::new(
strings::commands::abort_merge(&self.key_config),
true,
Expand Down Expand Up @@ -687,6 +701,14 @@ impl Component for Status {
{
self.pull();
Ok(EventState::Consumed)
} else if k == self.key_config.undo_commit
&& !self.is_focus_on_diff()
{
self.undo_last_commit();
self.queue.borrow_mut().push_back(
InternalEvent::Update(NeedsUpdate::ALL),
);
Ok(EventState::Consumed)
} else if k == self.key_config.abort_merge
&& Self::can_abort_merge()
{
Expand Down
1 change: 1 addition & 0 deletions vim_style_key_config.ron
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
// Also just plain text characters will not work because the commit
// msg editor will interpret them as text input
open_commit_editor: ( code: Char('e'), modifiers: ( bits: 2,),),
undo_commit: ( code: Char('U'), modifiers: ( bits: 1,),),

move_left: ( code: Char('h'), modifiers: ( bits: 0,),),
move_right: ( code: Char('l'), modifiers: ( bits: 0,),),
Expand Down