use crate::error::{GwError, Result};
use crate::git;
use crate::output;
use crate::state::{RepoType, SyncState, WorkingDirState};
pub fn run(verbose: bool) -> Result<()> {
if !git::is_git_repo() {
return Err(GwError::NotAGitRepository);
}
if git::is_detached_head() {
return Err(GwError::Other(
"Cannot run from detached HEAD. Checkout a branch first.".to_string(),
));
}
let repo_type = RepoType::detect()?;
let home_branch = repo_type.home_branch();
let current = git::current_branch()?;
let working_dir = WorkingDirState::detect();
println!();
output::info(&format!("Current branch: {}", output::bold(¤t)));
output::info(&format!("Home branch: {}", output::bold(home_branch)));
let has_changes = !working_dir.is_clean();
let has_untracked = git::has_untracked_files();
let sync_state = SyncState::detect(¤t).unwrap_or(SyncState::NoUpstream);
let default_remote = git::get_default_remote_branch()?;
let default_branch = default_remote.strip_prefix("origin/").unwrap_or("main");
if !has_changes && !has_untracked && current == home_branch {
output::success("Already on home branch with clean working directory");
output::info(&format!("Syncing with {}...", default_remote));
git::fetch_prune(verbose)?;
git::pull("origin", default_branch, verbose)?;
output::success("Synced");
return Ok(());
}
if has_changes {
output::warn(&format!(
"Uncommitted changes will be DISCARDED: {}",
working_dir.description()
));
}
if has_untracked {
output::warn("Untracked files will be DELETED");
}
if let SyncState::HasUnpushedCommits { count } = sync_state {
output::warn(&format!(
"Branch '{}' has {} unpushed commit(s). They will remain on the branch.",
current, count
));
}
if has_changes || has_untracked {
output::info("Discarding changes...");
git::discard_all_changes(verbose)?;
output::success("Changes discarded");
}
if current != home_branch {
if !git::branch_exists(home_branch) {
output::info(&format!("Creating home branch from {}...", default_remote));
git::checkout_new_branch(home_branch, &default_remote, verbose)?;
} else {
git::checkout(home_branch, verbose)?;
}
output::success(&format!("Switched to {}", output::bold(home_branch)));
}
output::info(&format!("Syncing with {}...", default_remote));
git::fetch_prune(verbose)?;
git::pull("origin", default_branch, verbose)?;
output::success("Synced");
output::ready("Ready", home_branch);
output::hints(&["gw new feature/your-feature # Start fresh"]);
Ok(())
}