Skip to main content

git_workflow/commands/
home.rs

1//! `gw home` command - Switch to home branch and sync with origin/main
2
3use crate::error::{GwError, Result};
4use crate::git;
5use crate::output;
6use crate::state::RepoType;
7
8/// Execute the `home` command
9pub fn run(verbose: bool) -> Result<()> {
10    // Ensure we're in a git repo
11    if !git::is_git_repo() {
12        return Err(GwError::NotAGitRepository);
13    }
14
15    // Check for detached HEAD
16    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
26    println!();
27    output::info(&format!("Home branch: {}", output::bold(home_branch)));
28
29    // Fetch latest
30    output::info("Fetching from origin...");
31    git::fetch_prune(verbose)?;
32    output::success("Fetched (stale remote branches pruned)");
33
34    // Detect default remote branch (origin/main or origin/master)
35    let default_remote = git::get_default_remote_branch()?;
36    let default_branch = default_remote.strip_prefix("origin/").unwrap_or("main");
37
38    // Switch to home branch if needed
39    if current != home_branch {
40        if !git::branch_exists(home_branch) {
41            output::info(&format!("Creating home branch from {}...", default_remote));
42            git::checkout_new_branch(home_branch, &default_remote, verbose)?;
43            output::success(&format!(
44                "Created and switched to {}",
45                output::bold(home_branch)
46            ));
47        } else {
48            git::checkout(home_branch, verbose)?;
49            output::success(&format!("Switched to {}", output::bold(home_branch)));
50        }
51    } else {
52        output::success(&format!("Already on {}", output::bold(home_branch)));
53    }
54
55    // Sync with default remote branch
56    output::info(&format!("Syncing with {}...", default_remote));
57    let before = git::head_commit()?;
58    git::pull("origin", default_branch, verbose)?;
59    let after = git::head_commit()?;
60
61    if before != after {
62        let count = git::commit_count(&before, &after)?;
63        output::success(&format!(
64            "Pulled {} commit(s) from {}",
65            output::bold(&count.to_string()),
66            default_remote
67        ));
68    } else {
69        output::success(&format!("Already up to date with {}", default_remote));
70    }
71
72    output::ready("Ready", home_branch);
73    output::hints(&["mise run git:new feature/your-feature  # Create new branch"]);
74
75    Ok(())
76}