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 if current != home_branch {
80 if !git::branch_exists(home_branch) {
81 output::info(&format!("Creating home branch from {}...", default_remote));
82 git::checkout_new_branch(home_branch, &default_remote, verbose)?;
83 } else {
84 git::checkout(home_branch, verbose)?;
85 }
86 output::success(&format!("Switched to {}", output::bold(home_branch)));
87 }
88
89 git::fetch_prune(verbose)?;
91 helpers::pull_with_output(&default_remote, default_branch, verbose)?;
92
93 output::ready("Ready", home_branch);
94 output::hints(&["gw new feature/your-feature # Start fresh"]);
95
96 Ok(())
97}