Skip to content

Commit d0d479e

Browse files
mhduiyzccrsCopilot
authored
feat: add --amend option for commit command (#13)
* feat: add --amend option for commit command 1. Added --amend flag to modify the last commit instead of creating a new one 2. Implemented logic to fetch diff from last commit when in amend mode 3. Added display of original commit message for reference during amend 4. Modified git command execution to include --amend flag when appropriate 5. Added proper error handling for amend mode when no commit history exists 6. Updated help documentation to include the new --amend option 7. Skip AI code review for amend operations since it's modifying existing commit Log: Added --amend option to modify last commit with new commit message Influence: 1. Test normal commit functionality to ensure no regression 2. Test --amend option with staged changes to modify last commit 3. Test --amend option with other flags like --only-chinese 4. Verify error handling when no commit history exists for amend 5. Test amend with different commit types and messages 6. Verify that original commit message is displayed correctly 7. Ensure AI code review is skipped for amend operations feat: 为 commit 命令添加 --amend 选项 1. 添加 --amend 标志用于修改上一次提交而不是创建新提交 2. 实现在 amend 模式下从上次提交获取差异内容的逻辑 3. 添加在 amend 时显示原提交信息供参考的功能 4. 修改 git 命令执行以在适当时包含 --amend 标志 5. 为 amend 模式添加适当的错误处理,当没有提交历史时 6. 更新帮助文档以包含新的 --amend 选项 7. 为 amend 操作跳过 AI 代码审查,因为是修改现有提交 Log: 新增 --amend 选项用于使用新提交信息修改上次提交 Influence: 1. 测试正常提交功能以确保没有回归 2. 测试 --amend 选项与暂存更改一起使用来修改上次提交 3. 测试 --amend 选项与其他标志如 --only-chinese 的组合使用 4. 验证当没有提交历史时 amend 的错误处理 5. 测试使用不同提交类型和消息的 amend 操作 6. 验证原提交信息是否正确显示 7. 确保 AI 代码审查在 amend 操作中被跳过 Co-authored-by: zccrs <zccrs@live.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent f6b186f commit d0d479e

4 files changed

Lines changed: 107 additions & 22 deletions

File tree

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ git-commit-helper translate /path/to/existing/file # 文件路径
197197
| ai list | 列出所有服务 | `git-commit-helper ai list` |
198198
| ai test | 测试指定服务 | `git-commit-helper ai test [-t "测试文本"]` |
199199
| translate | 翻译内容 | `git-commit-helper translate [-f 文件] [-t 文本]` |
200-
| commit | 生成提交信息 | `git-commit-helper commit [-t 类型] [-m 描述] [-a] [--no-review/--no-influence/--no-log/--only-chinese/--only-english] [--issues ISSUE...]` |
200+
| commit | 生成提交信息 | `git-commit-helper commit [-t 类型] [-m 描述] [-a] [--amend] [--no-review/--no-influence/--no-log/--only-chinese/--only-english] [--issues ISSUE...]` |
201201
| ai-review | 管理 AI 代码审查 | `git-commit-helper ai-review [--enable/--disable/--status]` |
202202

203203
### 提交类型
@@ -304,6 +304,10 @@ git-commit-helper commit --issues "https://pms.uniontech.com/story-view-38949.ht
304304
# 混合关联
305305
git-commit-helper commit --issues "123" "https://pms.uniontech.com/bug-view-320461.html"
306306
git-commit-helper commit --issues "https://github.com/owner/repo/issues/123" "https://pms.uniontech.com/task-view-374223.html"
307+
308+
# 修补上次提交
309+
git-commit-helper commit --amend
310+
git-commit-helper commit --amend --only-chinese
307311
```
308312

309313
### AI 代码审查功能

src/commit.rs

Lines changed: 65 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,7 @@ pub async fn generate_commit_message(
686686
commit_type: Option<String>,
687687
message: Option<String>,
688688
auto_add: bool,
689+
amend: bool,
689690
no_review: bool,
690691
no_translate: bool,
691692
mut only_chinese: bool,
@@ -726,15 +727,26 @@ pub async fn generate_commit_message(
726727
std::env::set_var("GIT_COMMIT_HELPER_NO_TRANSLATE", "1");
727728
}
728729

729-
let diff = get_staged_diff()?;
730+
// 根据是否是 amend 模式选择不同的 diff
731+
let diff = if amend {
732+
println!("正在分析上一次提交的更改内容...");
733+
git::get_last_commit_diff()?
734+
} else {
735+
get_staged_diff()?
736+
};
737+
730738
if diff.is_empty() {
731-
return Err(anyhow::anyhow!("没有已暂存的改动,请先使用 git add 添加改动"));
739+
if amend {
740+
return Err(anyhow::anyhow!("无法获取上一次提交的差异内容,可能没有足够的提交历史"));
741+
} else {
742+
return Err(anyhow::anyhow!("没有已暂存的改动,请先使用 git add 添加改动"));
743+
}
732744
}
733745

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

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

759-
println!("\n正在生成提交信息建议...");
771+
if amend {
772+
println!("\n正在基于上一次提交的更改生成新的提交信息...");
773+
// 显示原提交信息供参考
774+
if let Ok(original_msg) = git::get_last_commit_message() {
775+
println!("原提交信息:");
776+
println!("----------------------------------------");
777+
println!("{}", original_msg.trim());
778+
println!("----------------------------------------\n");
779+
}
780+
} else {
781+
println!("\n正在生成提交信息建议...");
782+
}
783+
760784
let mut message = translator.chat(&prompt, &diff).await?
761785
.trim_start_matches("[NO_TRANSLATE]")
762786
.trim_start_matches("、、、plaintext")
@@ -795,38 +819,62 @@ pub async fn generate_commit_message(
795819
}
796820

797821
// 预览生成的提交信息
798-
println!("\n生成的提交信息预览:");
822+
if amend {
823+
println!("\n生成的修改后提交信息预览:");
824+
} else {
825+
println!("\n生成的提交信息预览:");
826+
}
799827
println!("----------------------------------------");
800828
println!("{}", content);
801829
println!("----------------------------------------");
802830

803-
// 移除翻译相关的询问,直接询问用户是否确认提交
831+
// 询问用户是否确认提交
832+
let prompt_text = if amend {
833+
"是否使用此提交信息修改上一次提交?"
834+
} else {
835+
"是否使用此提交信息?"
836+
};
837+
804838
if !Confirm::with_theme(&dialoguer::theme::ColorfulTheme::default())
805-
.with_prompt("是否使用此提交信息?")
839+
.with_prompt(prompt_text)
806840
.default(true)
807841
.interact()?
808842
{
809-
println!("已取消提交");
843+
if amend {
844+
println!("已取消修改上一次提交");
845+
} else {
846+
println!("已取消提交");
847+
}
810848
return Ok(());
811849
}
812850

813851
// 执行git commit
814-
let status = Command::new("git")
815-
.current_dir(std::env::current_dir()?)
816-
.arg("commit")
817-
.arg("-m")
818-
.arg(content)
819-
.status()?;
852+
let mut cmd = Command::new("git");
853+
cmd.current_dir(std::env::current_dir()?);
854+
cmd.arg("commit");
855+
856+
if amend {
857+
cmd.arg("--amend");
858+
}
859+
860+
cmd.arg("-m").arg(content);
861+
862+
let status = cmd.status()?;
820863

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

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

829-
println!("提交成功!");
873+
if amend {
874+
println!("修改提交成功!");
875+
} else {
876+
println!("提交成功!");
877+
}
830878
Ok(())
831879
}
832880

src/git.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,36 @@ fn contains_chinese(text: &str) -> bool {
102102
text.chars().any(|c| c as u32 >= 0x4E00 && c as u32 <= 0x9FFF)
103103
}
104104

105-
pub fn wrap_text(text: &str, max_length: usize) -> String {
106-
fill(text, max_length)
105+
pub fn wrap_text(text: &str, width: usize) -> String {
106+
fill(text, width)
107+
}
108+
109+
/// 获取上一次提交的差异内容,用于 amend 模式
110+
pub fn get_last_commit_diff() -> anyhow::Result<String> {
111+
use std::process::Command;
112+
113+
let output = Command::new("git")
114+
.args(["diff", "HEAD~1..HEAD", "--no-prefix"])
115+
.output()?;
116+
117+
if !output.status.success() {
118+
return Err(anyhow::anyhow!("执行 git diff HEAD~1..HEAD --no-prefix 命令失败,可能没有足够的提交历史"));
119+
}
120+
121+
Ok(String::from_utf8(output.stdout)?)
122+
}
123+
124+
/// 获取上一次提交的信息
125+
pub fn get_last_commit_message() -> anyhow::Result<String> {
126+
use std::process::Command;
127+
128+
let output = Command::new("git")
129+
.args(["log", "-1", "--pretty=format:%s%n%n%b"])
130+
.output()?;
131+
132+
if !output.status.success() {
133+
return Err(anyhow::anyhow!("执行 git log 命令失败"));
134+
}
135+
136+
Ok(String::from_utf8(output.stdout)?)
107137
}

src/main.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ enum Commands {
8383
/// 自动添加所有已修改但未暂存的文件
8484
#[arg(short, long)]
8585
all: bool,
86+
/// 修改上一次提交信息
87+
#[arg(long)]
88+
amend: bool,
8689
/// 不翻译提交信息
8790
#[arg(long)]
8891
no_translate: bool,
@@ -413,13 +416,13 @@ async fn main() -> Result<()> {
413416
Err(e) => Err(e)
414417
}
415418
}
416-
Some(Commands::Commit { r#type, message, all, no_translate, only_chinese, only_english, no_influence, no_log, issues }) => {
419+
Some(Commands::Commit { r#type, message, all, amend, no_translate, only_chinese, only_english, no_influence, no_log, issues }) => {
417420
let issues_str = if issues.is_empty() {
418421
None
419422
} else {
420423
Some(issues.join(" "))
421424
};
422-
commit::generate_commit_message(r#type, message, all, cli.no_review, no_translate, only_chinese, only_english, no_influence, no_log, issues_str).await
425+
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
423426
}
424427
Some(Commands::AIReview { enable, disable, status }) => {
425428
let mut config = config::Config::load()?;

0 commit comments

Comments
 (0)