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