Skip to content
Merged
Changes from 3 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
92 changes: 92 additions & 0 deletions src/commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,30 @@ pub async fn generate_commit_message(
eprintln!("警告: 解析 issues 参数失败: {}", e);
}
}
} else if amend {
// 在 amend 模式下且未提供新的 issues 参数时,从原提交中保留所有标记字段
// (Change-Id 由 append_change_id 单独处理,此处跳过)
if let Some(ref orig_msg) = original_message {
let orig_commit = CommitMessage::parse(orig_msg);
// 只添加新内容中尚未包含的标记(排除 Change-Id,它由 append_change_id 处理)
let marks_to_add: Vec<String> = orig_commit.marks.iter()
.filter(|mark| {
let mark_key = mark.split(':').next().unwrap_or("").trim().to_lowercase();
mark_key != "change-id" && !content.lines().any(|line| {
line.trim().split(':').next()
.map_or(false, |k| k.trim().to_lowercase() == mark_key)
})
})
.cloned()
.collect();
if !marks_to_add.is_empty() {
if !content.ends_with('\n') {
content.push('\n');
}
content.push('\n');
content.push_str(&marks_to_add.join("\n"));
}
}
}

// 在 amend 模式下,如果原提交有 Change-Id,保留它
Expand Down Expand Up @@ -1154,4 +1178,72 @@ mod tests {
// Change-Id 应该在最后
assert!(result.ends_with("Change-Id: I1234567890abcdef1234567890abcdef12345678"));
}

// 测试从原提交消息中提取所有需保留的标记(排除 Change-Id)
#[test]
fn test_extract_issue_marks_from_original_commit() {
let original = "fix: some bug\n\nDescription here\n\nFixes: #123\nPMS: BUG-456\nLog: Fix critical bug\nChange-Id: Iabc123\n";
let orig_commit = CommitMessage::parse(original);
let marks_to_preserve: Vec<String> = orig_commit.marks.iter()
.filter(|mark| {
let mark_key = mark.split(':').next().unwrap_or("").trim().to_lowercase();
mark_key != "change-id"
})
.cloned()
.collect();
assert_eq!(marks_to_preserve.len(), 3);
assert!(marks_to_preserve.contains(&"Fixes: #123".to_string()));
assert!(marks_to_preserve.contains(&"PMS: BUG-456".to_string()));
assert!(marks_to_preserve.contains(&"Log: Fix critical bug".to_string()));
// Change-Id 不应被保留(由 append_change_id 单独处理)
assert!(!marks_to_preserve.iter().any(|m| m.to_lowercase().starts_with("change-id:")));
}

// 测试 amend 时新内容已包含标记时不重复添加
#[test]
fn test_amend_no_duplicate_issue_marks() {
let original = "fix: some bug\n\nFixes: #123\nLog: Fix bug\n";
let orig_commit = CommitMessage::parse(original);

// 新内容已包含 Fixes: 和 Log:
let new_content = "fix: improved bug fix\n\nBetter description\n\nFixes: #123\nLog: Fix bug";
let marks_to_add: Vec<String> = orig_commit.marks.iter()
.filter(|mark| {
let mark_key = mark.split(':').next().unwrap_or("").trim().to_lowercase();
mark_key != "change-id" && !new_content.lines().any(|line| {
line.trim().split(':').next()
.map_or(false, |k| k.trim().to_lowercase() == mark_key)
})
})
.cloned()
.collect();
// 不应重复添加
assert!(marks_to_add.is_empty());
}

// 测试 amend 时新内容不含标记时正确添加所有标记
#[test]
fn test_amend_preserves_issue_marks_when_missing() {
let original = "fix: some bug\n\nFixes: #123\nPMS: BUG-456\nLog: Fix critical bug\nChange-Id: Iabc123\n";
let orig_commit = CommitMessage::parse(original);

// 新内容不含任何标记
let new_content = "fix: improved bug fix\n\nBetter description";
let marks_to_add: Vec<String> = orig_commit.marks.iter()
.filter(|mark| {
let mark_key = mark.split(':').next().unwrap_or("").trim().to_lowercase();
mark_key != "change-id" && !new_content.lines().any(|line| {
line.trim().split(':').next()
.map_or(false, |k| k.trim().to_lowercase() == mark_key)
})
})
.cloned()
.collect();
assert_eq!(marks_to_add.len(), 3);
assert!(marks_to_add.contains(&"Fixes: #123".to_string()));
assert!(marks_to_add.contains(&"PMS: BUG-456".to_string()));
assert!(marks_to_add.contains(&"Log: Fix critical bug".to_string()));
// Change-Id 不应被包含(由 append_change_id 处理)
assert!(!marks_to_add.iter().any(|m| m.to_lowercase().starts_with("change-id:")));
}
}