Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ git-commit-helper translate /path/to/existing/file # 文件路径
| ai list | 列出所有服务 | `git-commit-helper ai list` |
| ai test | 测试指定服务 | `git-commit-helper ai test [-t "测试文本"]` |
| translate | 翻译内容 | `git-commit-helper translate [-f 文件] [-t 文本]` |
| commit | 生成提交信息 | `git-commit-helper commit [-t 类型] [-m 描述] [-a] [--no-review/--no-influence/--no-log/--only-chinese/--only-english] [--issues ISSUE...]` |
| commit | 生成提交信息 | `git-commit-helper commit [-t 类型] [-m 描述] [-a] [--amend] [--no-review/--no-influence/--no-log/--only-chinese/--only-english] [--issues ISSUE...]` |
| ai-review | 管理 AI 代码审查 | `git-commit-helper ai-review [--enable/--disable/--status]` |

### 提交类型
Expand Down Expand Up @@ -304,6 +304,10 @@ git-commit-helper commit --issues "https://pms.uniontech.com/story-view-38949.ht
# 混合关联
git-commit-helper commit --issues "123" "https://pms.uniontech.com/bug-view-320461.html"
git-commit-helper commit --issues "https://github.com/owner/repo/issues/123" "https://pms.uniontech.com/task-view-374223.html"

# 修补上次提交
git-commit-helper commit --amend
git-commit-helper commit --amend --only-chinese
```

### AI 代码审查功能
Expand Down
82 changes: 65 additions & 17 deletions src/commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -686,6 +686,7 @@ pub async fn generate_commit_message(
commit_type: Option<String>,
message: Option<String>,
auto_add: bool,
amend: bool,
no_review: bool,
no_translate: bool,
mut only_chinese: bool,
Expand Down Expand Up @@ -726,15 +727,26 @@ pub async fn generate_commit_message(
std::env::set_var("GIT_COMMIT_HELPER_NO_TRANSLATE", "1");
}

let diff = get_staged_diff()?;
// 根据是否是 amend 模式选择不同的 diff
let diff = if amend {
println!("正在分析上一次提交的更改内容...");
git::get_last_commit_diff()?
} else {
get_staged_diff()?
};

if diff.is_empty() {
return Err(anyhow::anyhow!("没有已暂存的改动,请先使用 git add 添加改动"));
if amend {
return Err(anyhow::anyhow!("无法获取上一次提交的差异内容,可能没有足够的提交历史"));
} else {
return Err(anyhow::anyhow!("没有已暂存的改动,请先使用 git add 添加改动"));
}
}

let config = config::Config::load()?;

// 在确认有暂存的改动后执行代码审查
if !no_review && config.ai_review {
// 在确认有差异内容后执行代码审查(对于 amend 模式,我们跳过审查,因为是对已有提交的修改)
if !amend && !no_review && config.ai_review {
info!("正在进行代码审查...");
if let Some(review) = review::review_changes(&config, no_review).await? {
println!("\n{}\n", review);
Expand All @@ -756,7 +768,19 @@ pub async fn generate_commit_message(
let service = config.get_default_service()?;
let translator = ai_service::create_translator_for_service(service).await?;

println!("\n正在生成提交信息建议...");
if amend {
println!("\n正在基于上一次提交的更改生成新的提交信息...");
// 显示原提交信息供参考
if let Ok(original_msg) = git::get_last_commit_message() {
println!("原提交信息:");
println!("----------------------------------------");
println!("{}", original_msg.trim());
println!("----------------------------------------\n");
}
} else {
println!("\n正在生成提交信息建议...");
}

let mut message = translator.chat(&prompt, &diff).await?
.trim_start_matches("[NO_TRANSLATE]")
.trim_start_matches("、、、plaintext")
Expand Down Expand Up @@ -795,38 +819,62 @@ pub async fn generate_commit_message(
}

// 预览生成的提交信息
println!("\n生成的提交信息预览:");
if amend {
println!("\n生成的修改后提交信息预览:");
} else {
println!("\n生成的提交信息预览:");
}
println!("----------------------------------------");
println!("{}", content);
println!("----------------------------------------");

// 移除翻译相关的询问,直接询问用户是否确认提交
// 询问用户是否确认提交
let prompt_text = if amend {
"是否使用此提交信息修改上一次提交?"
} else {
"是否使用此提交信息?"
};

if !Confirm::with_theme(&dialoguer::theme::ColorfulTheme::default())
.with_prompt("是否使用此提交信息?")
.with_prompt(prompt_text)
.default(true)
.interact()?
{
println!("已取消提交");
if amend {
println!("已取消修改上一次提交");
} else {
println!("已取消提交");
}
return Ok(());
}

// 执行git commit
let status = Command::new("git")
.current_dir(std::env::current_dir()?)
.arg("commit")
.arg("-m")
.arg(content)
.status()?;
let mut cmd = Command::new("git");
cmd.current_dir(std::env::current_dir()?);
cmd.arg("commit");

if amend {
cmd.arg("--amend");
}

cmd.arg("-m").arg(content);

let status = cmd.status()?;

// 清理环境变量(无论命令是否执行成功)
std::env::remove_var("GIT_COMMIT_HELPER_SKIP_REVIEW");
std::env::remove_var("GIT_COMMIT_HELPER_NO_TRANSLATE");

if !status.success() {
return Err(anyhow::anyhow!("git commit 命令执行失败"));
let action = if amend { "修改提交" } else { "提交" };
return Err(anyhow::anyhow!("git commit 命令执行失败,{} 失败", action));
}

println!("提交成功!");
if amend {
println!("修改提交成功!");
} else {
println!("提交成功!");
}
Ok(())
}

Expand Down
34 changes: 32 additions & 2 deletions src/git.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,36 @@ fn contains_chinese(text: &str) -> bool {
text.chars().any(|c| c as u32 >= 0x4E00 && c as u32 <= 0x9FFF)
}

pub fn wrap_text(text: &str, max_length: usize) -> String {
fill(text, max_length)
pub fn wrap_text(text: &str, width: usize) -> String {
fill(text, width)
}

/// 获取上一次提交的差异内容,用于 amend 模式
pub fn get_last_commit_diff() -> anyhow::Result<String> {
use std::process::Command;

let output = Command::new("git")
.args(["diff", "HEAD~1..HEAD", "--no-prefix"])
.output()?;

if !output.status.success() {
return Err(anyhow::anyhow!("执行 git diff HEAD~1..HEAD --no-prefix 命令失败,可能没有足够的提交历史"));
}

Ok(String::from_utf8(output.stdout)?)
}

/// 获取上一次提交的信息
pub fn get_last_commit_message() -> anyhow::Result<String> {
use std::process::Command;

let output = Command::new("git")
.args(["log", "-1", "--pretty=format:%s%n%n%b"])
.output()?;

if !output.status.success() {
return Err(anyhow::anyhow!("执行 git log 命令失败"));
}

Ok(String::from_utf8(output.stdout)?)
}
7 changes: 5 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ enum Commands {
/// 自动添加所有已修改但未暂存的文件
#[arg(short, long)]
all: bool,
/// 修改上一次提交信息
#[arg(long)]
amend: bool,
/// 不翻译提交信息
#[arg(long)]
no_translate: bool,
Expand Down Expand Up @@ -413,13 +416,13 @@ async fn main() -> Result<()> {
Err(e) => Err(e)
}
}
Some(Commands::Commit { r#type, message, all, no_translate, only_chinese, only_english, no_influence, no_log, issues }) => {
Some(Commands::Commit { r#type, message, all, amend, no_translate, only_chinese, only_english, no_influence, no_log, issues }) => {
let issues_str = if issues.is_empty() {
None
} else {
Some(issues.join(" "))
};
commit::generate_commit_message(r#type, message, all, cli.no_review, no_translate, only_chinese, only_english, no_influence, no_log, issues_str).await
commit::generate_commit_message(r#type, message, all, amend, cli.no_review, no_translate, only_chinese, only_english, no_influence, no_log, issues_str).await
}
Some(Commands::AIReview { enable, disable, status }) => {
let mut config = config::Config::load()?;
Expand Down