git_workflow/commands/
abandon.rs1use super::helpers;
4use crate::error::{GwError, Result};
5use crate::git;
6use crate::output;
7use crate::state::{RepoType, SyncState, WorkingDirState};
8
9pub fn run(verbose: bool) -> Result<()> {
11 if !git::is_git_repo() {
13 return Err(GwError::NotAGitRepository);
14 }
15
16 if git::is_detached_head() {
18 return Err(GwError::Other(
19 "Cannot run from detached HEAD. Checkout a branch first.".to_string(),
20 ));
21 }
22
23 let repo_type = RepoType::detect()?;
24 let home_branch = repo_type.home_branch();
25 let current = git::current_branch()?;
26 let working_dir = WorkingDirState::detect();
27
28 println!();
29 output::info(&format!("Current branch: {}", output::bold(¤t)));
30 output::info(&format!("Home branch: {}", output::bold(home_branch)));
31
32 let has_changes = !working_dir.is_clean();
34 let has_untracked = git::has_untracked_files();
35 let sync_state = SyncState::detect(¤t).unwrap_or(SyncState::NoUpstream);
36
37 let default_remote = git::get_default_remote_branch()?;
39 let default_branch = default_remote.strip_prefix("origin/").unwrap_or("main");
40
41 if !has_changes && !has_untracked && current == home_branch {
43 output::success("Already on home branch with clean working directory");
44 git::fetch_prune(verbose)?;
46 helpers::pull_with_output(&default_remote, default_branch, verbose)?;
47 return Ok(());
48 }
49
50 if working_dir.has_tracked_changes() {
54 output::warn(&format!(
55 "Uncommitted changes will be DISCARDED: {}",
56 working_dir.description()
57 ));
58 }
59 if has_untracked {
60 output::warn("Untracked files will be DELETED");
61 }
62
63 if let SyncState::HasUnpushedCommits { count } = sync_state {
65 output::warn(&format!(
66 "Branch '{}' has {} unpushed commit(s). They will remain on the branch.",
67 current, count
68 ));
69 }
70
71 if has_changes || has_untracked {
73 output::info("Discarding changes...");
74 git::discard_all_changes(verbose)?;
75 output::success("Changes discarded");
76 }
77
78 git::fetch_prune(verbose)?;
80
81 if current != home_branch {
83 if !git::branch_exists(home_branch) {
84 output::info(&format!("Creating home branch from {}...", default_remote));
85 git::checkout_new_branch(home_branch, &default_remote, verbose)?;
86 } else {
87 helpers::fast_forward_home_ref(home_branch, &default_remote, verbose);
90 git::checkout(home_branch, verbose)?;
91 }
92 output::success(&format!("Switched to {}", output::bold(home_branch)));
93 }
94
95 helpers::pull_with_output(&default_remote, default_branch, verbose)?;
97
98 output::ready("Ready", home_branch);
99 output::hints(&["gw new feature/your-feature # Start fresh"]);
100
101 Ok(())
102}