Skip to main content

git_workflow/commands/
pause.rs

1//! `gw pause` command - Pause current work by creating a WIP commit and returning to home
2
3use super::helpers;
4use crate::error::{GwError, Result};
5use crate::git;
6use crate::github;
7use crate::output;
8use crate::state::{RepoType, WorkingDirState};
9
10/// Execute the `pause` command
11pub fn run(message: Option<String>, verbose: bool) -> Result<()> {
12    // Ensure we're in a git repo
13    if !git::is_git_repo() {
14        return Err(GwError::NotAGitRepository);
15    }
16
17    let repo_type = RepoType::detect()?;
18    let home_branch = repo_type.home_branch();
19    let current = git::current_branch()?;
20    let working_dir = WorkingDirState::detect();
21
22    println!();
23
24    // If on home branch, just inform
25    if current == home_branch {
26        output::info(&format!("Already on home branch '{}'", home_branch));
27        if !working_dir.is_clean() {
28            output::warn(
29                "You have uncommitted changes. Consider committing or using 'gw new <branch>'.",
30            );
31        }
32        return Ok(());
33    }
34
35    // Create WIP commit if there are changes
36    if !working_dir.is_clean() {
37        let commit_message = match &message {
38            Some(msg) => format!("WIP: {}", msg),
39            None => "WIP: paused".to_string(),
40        };
41
42        output::info("Creating WIP commit...");
43        git::add_all(verbose)?;
44        git::commit(&commit_message, verbose)?;
45        output::success(&format!("Created: {}", commit_message));
46
47        // Try to add PR comment if message provided
48        if let Some(msg) = &message {
49            if github::is_gh_available() {
50                if let Ok(Some(pr)) = github::get_pr_for_branch(&current) {
51                    let comment = format!("⏸️ Paused work on this PR: {}", msg);
52                    match github::add_pr_comment(pr.number, &comment) {
53                        Ok(()) => output::success(&format!("Added comment to PR #{}", pr.number)),
54                        Err(e) => output::warn(&format!("Could not add PR comment: {}", e)),
55                    }
56                }
57            }
58        }
59    } else {
60        output::info("Working directory is clean. No WIP commit needed.");
61    }
62
63    // Switch to home branch
64    output::info("Switching to home branch...");
65    git::fetch_prune(verbose)?;
66
67    // Detect default remote branch
68    let default_remote = git::get_default_remote_branch()?;
69    let default_branch = default_remote.strip_prefix("origin/").unwrap_or("main");
70
71    if !git::branch_exists(home_branch) {
72        git::checkout_new_branch(home_branch, &default_remote, verbose)?;
73    } else {
74        git::checkout(home_branch, verbose)?;
75    }
76
77    // Sync with default remote (fast-forward only; stop on divergence)
78    helpers::pull_with_output(&default_remote, default_branch, verbose)?;
79    output::success(&format!("Switched to {}", output::bold(home_branch)));
80
81    output::ready("Paused", home_branch);
82    output::hints(&[
83        &format!("git checkout {}  # Return to paused branch", current),
84        "gw undo              # Undo WIP commit after checkout",
85        "gw new <branch>      # Start different work",
86    ]);
87
88    Ok(())
89}