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
18 changes: 14 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ git-commit-helper translate /path/to/existing/file # 文件路径

| 命令 | 说明 | 示例 |
|------|------|------|
| config | 配置 AI 服务 | `git-commit-helper config [--set-only-chinese <true\|false>]` |
| config | 配置 AI 服务 | `git-commit-helper config [--set-only-chinese <true\|false>/--set-only-english <true\|false>]` |
| show | 显示当前配置 | `git-commit-helper show` |
| install | 安装 Git Hook | `git-commit-helper install [-f]` |
| ai add | 添加 AI 服务 | `git-commit-helper ai add` |
Expand All @@ -189,7 +189,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]` |
| commit | 生成提交信息 | `git-commit-helper commit [-t 类型] [-m 描述] [-a] [--no-review/--only-chinese/--only-english]` |
| ai-review | 管理 AI 代码审查 | `git-commit-helper ai-review [--enable/--disable/--status]` |

### 提交类型
Expand Down Expand Up @@ -235,9 +235,11 @@ git-commit-helper commit [选项]
-a, --all 自动添加所有已修改但未暂存的文件
--no-review 禁用当前提交的代码审查功能
--only-chinese 仅保留中文提交信息
--only-english 仅保留英文提交信息
```

示例:

```bash
# 生成提交信息
git-commit-helper commit
Expand All @@ -256,10 +258,18 @@ git-commit-helper commit --type fix --message "修复内存泄漏" -a

# 设置默认使用中文
git-commit-helper config --set-only-chinese true # 默认仅使用中文
git-commit-helper config --set-only-chinese false # 默认使用中英双语

# 设置默认使用英文
git-commit-helper config --set-only-english true # 默认仅使用英文

# 设置默认使用中英双语
git-commit-helper config --set-only-chinese false --set-only-english false # 默认使用中英双语

# 单次提交使用中文
git-commit-helper commit --type feat --message "添加新功能" --only-chinese

# 单次提交使用英文
git-commit-helper commit --type feat --message "Add new functions" --only-english
```

### AI 代码审查功能
Expand Down Expand Up @@ -305,7 +315,7 @@ git-commit-helper https://gerrit.example.com/c/project/+/123456
```

输出格式:
```
```txt
标题:<原始标题>
中文翻译:<标题翻译>

Expand Down
241 changes: 138 additions & 103 deletions src/commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,130 @@ use regex::Regex;
use crate::ai_service;
use crate::config;

// 语言模式枚举
#[derive(Debug, Clone, Copy)]
enum LanguageMode {
ChineseOnly,
EnglishOnly,
Bilingual,
}

// 提示词模板常量
const ENGLISH_PROMPT_TEMPLATE: &str = r#"Please analyze the git diff content and generate a commit message in English only:
1. First line: type: message (under 50 characters)
2. Empty line after the title
3. Detailed explanation in English (what was changed and why)
4. Type must be one of: feat/fix/docs/style/refactor/test/chore
5. Focus on both WHAT changed and WHY it was necessary
6. Include any important technical details or context
7. DO NOT include any Chinese content
8. DO NOT wrap the response in any markdown or code block markers

Example response format:
feat: add user authentication module

1. Implement JWT-based authentication system
2. Add user login and registration endpoints
3. Include password hashing with bcrypt
4. Set up token refresh mechanism

Please respond with ONLY the commit message following this format,
DO NOT end commit titles with any punctuation."#;

const CHINESE_PROMPT_TEMPLATE: &str = r#"请分析以下 git diff 内容,并按照以下格式生成提交信息:
1. 第一行为标题:type: message(不超过50个字符)
2. 标题下方空一行
3. 详细的中文说明(解释做了什么改动以及为什么需要这些改动)
4. type 必须是以下之一:feat/fix/docs/style/refactor/test/chore
5. 关注点:变更内容(做了什么)和变更原因(为什么)
6. 包含重要的技术细节或上下文
7. 不要使用任何 markdown 或代码块标记
8. 标题结尾不要使用标点符号

示例格式:
feat: 添加用户认证模块

1. 实现基于 JWT 的认证系统
2. 添加用户登录和注册端点
3. 包含使用 bcrypt 的密码哈希处理
4. 设置令牌刷新机制"#;

const BILINGUAL_PROMPT_TEMPLATE: &str = r#"Please analyze the git diff content and generate a detailed bilingual commit message with:
1. First line in English: type: message (under 50 characters)
2. Empty line after the title
3. Detailed explanation in English (what was changed and why)
4. Empty line after English explanation
5. Chinese title and explanation (translate the English content)
6. Type must be one of: feat/fix/docs/style/refactor/test/chore
7. Focus on both WHAT changed and WHY it was necessary
8. Include any important technical details or context
9. DO NOT wrap the response in any markdown or code block markers

Example response format:
feat: add user authentication module

1. Implement JWT-based authentication system
2. Add user login and registration endpoints
3. Include password hashing with bcrypt
4. Set up token refresh mechanism

feat: 添加用户认证模块

1. 实现基于 JWT 的认证系统
2. 添加用户登录和注册端点
3. 包含使用 bcrypt 的密码哈希处理
4. 设置令牌刷新机制

Please respond with ONLY the commit message following this format,
DO NOT end commit titles with any punctuation."#;

impl LanguageMode {
fn determine(only_chinese: bool, only_english: bool) -> Self {
if only_english {
Self::EnglishOnly
} else if only_chinese {
Self::ChineseOnly
} else {
Self::Bilingual
}
}

fn template(&self) -> &'static str {
match self {
Self::EnglishOnly => ENGLISH_PROMPT_TEMPLATE,
Self::ChineseOnly => CHINESE_PROMPT_TEMPLATE,
Self::Bilingual => BILINGUAL_PROMPT_TEMPLATE,
}
}
}

// 统一的提示词构建函数
fn build_prompt(mode: LanguageMode, user_message: Option<&str>) -> String {
let mut prompt = String::from(mode.template());

if let Some(msg) = user_message {
match mode {
LanguageMode::ChineseOnly => {
prompt.push_str(&format!("\n\n用户描述:\n{}\n\n变更内容:\n", msg));
}
_ => {
prompt.push_str(&format!("\n\nUser Description:\n{}\n\nChanges:\n", msg));
}
}
} else {
match mode {
LanguageMode::ChineseOnly => {
prompt.push_str("\n\n变更内容:\n");
}
_ => {
prompt.push_str("\n\nHere are the changes:\n");
}
}
}

prompt
}

pub struct CommitMessage {
pub title: String,
pub body: Option<String>,
Expand Down Expand Up @@ -104,13 +228,23 @@ pub async fn generate_commit_message(
no_review: bool,
no_translate: bool,
mut only_chinese: bool,
mut only_english: bool,
) -> anyhow::Result<()> {
// 加载配置,如果指定了参数则使用参数值,否则使用配置中的默认值
if let Ok(config) = config::Config::load() {
if !only_chinese {
if !only_chinese && !only_english {
only_chinese = config.only_chinese;
only_english = config.only_english;
}
}

// 处理语言选项冲突:only_english 优先级最高
if only_english {
only_chinese = false;
} else if only_chinese {
only_english = false;
}

// 如果指定了 -a 参数,先执行 git add -u
if auto_add {
info!("自动添加已修改的文件...");
Expand Down Expand Up @@ -146,108 +280,9 @@ pub async fn generate_commit_message(
// 设置环境变量标记跳过后续的代码审查
std::env::set_var("GIT_COMMIT_HELPER_SKIP_REVIEW", "1");

let prompt = match (message, only_chinese) {
(Some(msg), true) => format!(
"请分析以下 git diff 内容,并按照以下格式生成提交信息:\
1. 第一行为标题:type: message(不超过50个字符)\
2. 标题下方空一行\
3. 详细的中文说明(解释做了什么改动以及为什么需要这些改动)\
4. type 必须是以下之一:feat/fix/docs/style/refactor/test/chore\
5. 关注点:变更内容(做了什么)和变更原因(为什么)\
6. 包含重要的技术细节或上下文\
7. 不要使用任何 markdown 或代码块标记\
8. 标题结尾不要使用标点符号\
\n\n示例格式:\
feat: 添加用户认证模块\n\
1. 实现基于 JWT 的认证系统\n\
2. 添加用户登录和注册端点\n\
3. 包含使用 bcrypt 的密码哈希处理\n\
4. 设置令牌刷新机制
\n\n用户描述:\n{}\n\n变更内容:\n",
msg
),
(None, true) => format!(
"请分析以下 git diff 内容,并按照以下格式生成提交信息:\
1. 第一行为标题:type: message(不超过50个字符)\
2. 标题下方空一行\
3. 详细的中文说明(解释做了什么改动以及为什么需要这些改动)\
4. type 必须是以下之一:feat/fix/docs/style/refactor/test/chore\
5. 关注点:变更内容(做了什么)和变更原因(为什么)\
6. 包含重要的技术细节或上下文\
7. 不要使用任何 markdown 或代码块标记\
8. 标题结尾不要使用标点符号\
\n\n示例格式:\
feat: 添加用户认证模块\n\
1. 实现基于 JWT 的认证系统\n\
2. 添加用户登录和注册端点\n\
3. 包含使用 bcrypt 的密码哈希处理\n\
4. 设置令牌刷新机制
\n\n变更内容:\n"
),
(Some(msg), false) => format!(
"Please analyze the git diff content and generate a detailed bilingual commit message with:
1. First line in English: type: message (under 50 characters)
2. Empty line after the title
3. Detailed explanation in English (what was changed and why)
4. Empty line after English explanation
5. Chinese title and explanation (translate the English content)
6. Type must be one of: feat/fix/docs/style/refactor/test/chore
7. Focus on both WHAT changed and WHY it was necessary
8. Include any important technical details or context
9. DO NOT wrap the response in any markdown or code block markers

Example response format:
feat: add user authentication module

1. Implement JWT-based authentication system
2. Add user login and registration endpoints
3. Include password hashing with bcrypt
4. Set up token refresh mechanism

feat: 添加用户认证模块

1. 实现基于 JWT 的认证系统
2. 添加用户登录和注册端点
3. 包含使用 bcrypt 的密码哈希处理
4. 设置令牌刷新机制

Please respond with ONLY the commit message following this format,
DO NOT end commit titles with any punctuation.
\n\nUser Description:\n{}\n\nChanges:\n",
msg
),
(None, false) => format!(
"Please analyze the git diff content and generate a detailed bilingual commit message with:
1. First line in English: type: message (under 50 characters)
2. Empty line after the title
3. Detailed explanation in English (what was changed and why)
4. Empty line after English explanation
5. Chinese title and explanation (translate the English content)
6. Type must be one of: feat/fix/docs/style/refactor/test/chore
7. Focus on both WHAT changed and WHY it was necessary
8. Include any important technical details or context
9. DO NOT wrap the response in any markdown or code block markers

Example response format:
feat: add user authentication module

1. Implement JWT-based authentication system
2. Add user login and registration endpoints
3. Include password hashing with bcrypt
4. Set up token refresh mechanism

feat: 添加用户认证模块

1. 实现基于 JWT 的认证系统
2. 添加用户登录和注册端点
3. 包含使用 bcrypt 的密码哈希处理
4. 设置令牌刷新机制

Please respond with ONLY the commit message following this format,
DO NOT end commit titles with any punctuation.
\n\nHere are the changes:\n"
)
};
// 确定语言模式并构建提示词
let language_mode = LanguageMode::determine(only_chinese, only_english);
let prompt = build_prompt(language_mode, message.as_deref());

debug!("生成的提示信息:\n{}", prompt);

Expand Down
10 changes: 10 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,19 @@ pub struct Config {
pub gerrit: Option<GerritConfig>, // Gerrit 配置
#[serde(default = "default_only_chinese")]
pub only_chinese: bool, // 是否默认只使用中文
#[serde(default = "default_only_english")]
pub only_english: bool, // 是否默认只使用英文
}

// 添加默认值函数
fn default_only_chinese() -> bool {
false
}

fn default_only_english() -> bool {
false
}

#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct GerritConfig {
pub username: Option<String>,
Expand Down Expand Up @@ -82,6 +88,7 @@ impl Config {
max_tokens: default_max_tokens(),
gerrit: None,
only_chinese: false, // 默认关闭
only_english: false, // 默认关闭
}
}

Expand Down Expand Up @@ -279,6 +286,7 @@ impl Config {
max_tokens: default_max_tokens(),
gerrit: None,
only_chinese: false, // 默认关闭
only_english: false, // 默认关闭
};

// 确保配置目录存在
Expand Down Expand Up @@ -307,6 +315,7 @@ impl Config {
max_tokens: config.max_tokens,
gerrit: None,
only_chinese: false,
only_english: false,
};
let translator = ai_service::create_translator(&test_config).await?;
match translator.translate("这是一个测试消息,用于验证翻译功能是否正常。").await {
Expand Down Expand Up @@ -480,6 +489,7 @@ impl Config {
max_tokens: self.max_tokens,
gerrit: None,
only_chinese: false,
only_english: false,
};
let translator = ai_service::create_translator(&test_config).await?;
let text = "这是一个测试消息,用于验证翻译功能是否正常。";
Expand Down
Loading
Loading