git_workflow/commands/
undo.rs1use crate::error::{GwError, Result};
4use crate::git;
5use crate::output;
6use crate::state::SyncState;
7
8pub fn run(verbose: bool) -> Result<()> {
10 if !git::is_git_repo() {
12 return Err(GwError::NotAGitRepository);
13 }
14
15 if !git::has_commits_to_undo() {
17 return Err(GwError::NothingToUndo);
18 }
19
20 let current = git::current_branch()?;
21
22 let commit_short = git::short_commit()?;
24 let commit_msg = git::head_commit_message()?;
25
26 println!();
27 output::info(&format!(
28 "Undoing commit: {} {}",
29 output::bold(&commit_short),
30 commit_msg
31 ));
32
33 let sync_state = SyncState::detect(¤t).unwrap_or(SyncState::NoUpstream);
35 if matches!(sync_state, SyncState::Synced | SyncState::Behind { .. }) {
36 output::warn("This commit may have been pushed. Local undo won't affect remote.");
37 output::warn("You may need to force push after undoing.");
38 }
39
40 git::reset_soft("HEAD~1", verbose)?;
42 output::success("Commit undone (changes are now staged)");
43
44 output::ready("Undone", ¤t);
45 output::hints(&[
46 "git status # See staged changes",
47 "git diff --cached # Review staged changes",
48 "git commit -m \"...\" # Re-commit with new message",
49 ]);
50
51 Ok(())
52}