feat: add auto-push functionality to commit and tag commands

This commit is contained in:
2026-02-01 12:35:26 +00:00
parent 0cbd975748
commit 09d2b6db8c
6 changed files with 131 additions and 27 deletions

View File

@@ -15,7 +15,7 @@ use crate::utils::validators::get_commit_types;
#[derive(Parser)]
pub struct CommitCommand {
/// Commit type
#[arg(short, long)]
#[arg(long)]
commit_type: Option<String>,
/// Commit scope
@@ -39,7 +39,7 @@ pub struct CommitCommand {
date: bool,
/// Manual input (skip AI generation)
#[arg(short, long)]
#[arg(long)]
manual: bool,
/// Sign the commit
@@ -73,6 +73,14 @@ pub struct CommitCommand {
/// Skip interactive prompts
#[arg(short = 'y', long)]
yes: bool,
/// Push after committing
#[arg(long)]
push: bool,
/// Remote to push to
#[arg(long, default_value = "origin")]
remote: String,
}
impl CommitCommand {
@@ -101,6 +109,13 @@ impl CommitCommand {
config.commit.format
};
// Auto-add if no files are staged and there are unstaged/untracked changes
if status.staged == 0 && (status.unstaged > 0 || status.untracked > 0) && !self.all {
println!("{}", messages.auto_stage_changes().yellow());
repo.stage_all()?;
println!("{}", messages.staged_all().green());
}
// Stage all if requested
if self.all {
repo.stage_all()?;
@@ -175,6 +190,24 @@ impl CommitCommand {
println!("{} {}", messages.commit_amended().green().bold(), "successfully");
}
// Push after commit if requested or ask user
if self.push {
println!("\n{}", messages.pushing_commit(&self.remote));
repo.push(&self.remote, "HEAD")?;
println!("{}", messages.pushed_commit(&self.remote));
} else if !self.yes && !self.dry_run {
let should_push = Confirm::new()
.with_prompt(messages.push_after_commit())
.default(false)
.interact()?;
if should_push {
println!("\n{}", messages.pushing_commit(&self.remote));
repo.push(&self.remote, "HEAD")?;
println!("{}", messages.pushed_commit(&self.remote));
}
}
Ok(())
}
@@ -184,12 +217,22 @@ impl CommitCommand {
}
fn create_manual_commit(&self, format: CommitFormat) -> Result<String> {
let commit_type = self.commit_type.clone()
.ok_or_else(|| anyhow::anyhow!("Commit type required for manual commit. Use -t <type>"))?;
let description = self.message.clone()
.ok_or_else(|| anyhow::anyhow!("Description required for manual commit. Use -m <message>"))?;
// Try to extract commit type from message if not provided
let commit_type = if let Some(ref ct) = self.commit_type {
ct.clone()
} else {
// Parse from conventional commit format: "type: description"
description
.split(':')
.next()
.unwrap_or("feat")
.trim()
.to_string()
};
let builder = CommitBuilder::new()
.commit_type(commit_type)
.description(description)