3 Commits

5 changed files with 36 additions and 18 deletions

View File

@@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.1.7] - 2026-02-14
### 🐞 错误修复
- 修复 `changelog` 命令默认覆盖文件的问题,现改为智能追加新版本条目到头部之后
### 🔧 其他变更
- 清理 `formatter.rs` 中未使用的函数(`format_commit_date``format_changelog_date``format_tag_name``truncate``format_markdown_list``format_changelog_section``format_git_config_key`
- 清理 `validators.rs` 中未使用的函数(`validate_ssh_key`
- 移除 `changelog` 命令的 `--prepend` 参数(默认行为已改为追加)
## [0.1.4] - 2026-02-01
### ✨ 新功能

View File

@@ -1,6 +1,6 @@
[package]
name = "quicommit"
version = "0.1.7"
version = "0.1.8"
edition = "2024"
authors = ["Sidney Zhang <zly@lyzhang.me>"]
description = "A powerful Git assistant tool with AI-powered commit/tag/changelog generation(alpha version)"

View File

@@ -162,8 +162,10 @@ impl ChangelogCommand {
if output_path.exists() {
let existing = std::fs::read_to_string(&output_path)?;
let new_content = if existing.is_empty() {
format!("# Changelog\n\n{}", changelog)
} else {
format!("{}{}", CHANGELOG_HEADER, changelog)
} else if existing.starts_with(CHANGELOG_HEADER) {
format!("{}{}", CHANGELOG_HEADER, changelog)
} else if existing.starts_with("# Changelog") {
let lines: Vec<&str> = existing.lines().collect();
let mut header_end = 0;
@@ -181,10 +183,12 @@ impl ChangelogCommand {
let rest = lines[header_end..].join("\n");
format!("{}\n{}\n{}", header, changelog, rest)
} else {
format!("{}{}", CHANGELOG_HEADER, changelog)
};
std::fs::write(&output_path, new_content)?;
} else {
let content = format!("# Changelog\n\n{}", changelog);
let content = format!("{}{}", CHANGELOG_HEADER, changelog);
std::fs::write(&output_path, content)?;
}

View File

@@ -31,7 +31,8 @@ impl ContentGenerator {
// Truncate diff if too long
let max_diff_len = 4000;
let truncated_diff = if diff.len() > max_diff_len {
format!("{}\n... (truncated)", &diff[..max_diff_len])
let boundary = diff.floor_char_boundary(max_diff_len);
format!("{}\n... (truncated)", &diff[..boundary])
} else {
diff.to_string()
};

View File

@@ -5,6 +5,15 @@ use std::collections::HashMap;
use std::fs;
use std::path::Path;
pub const CHANGELOG_HEADER: &str = r#"# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
"#;
/// Changelog generator
pub struct ChangelogGenerator {
format: ChangelogFormat,
@@ -109,9 +118,10 @@ impl ChangelogGenerator {
};
let new_content = if existing.is_empty() {
format!("# Changelog\n\n{}", entry)
} else {
// Find position after header
format!("{}{}", CHANGELOG_HEADER, entry)
} else if existing.starts_with(CHANGELOG_HEADER) {
format!("{}{}", CHANGELOG_HEADER, entry)
} else if existing.starts_with("# Changelog") {
let lines: Vec<&str> = existing.lines().collect();
let mut header_end = 0;
@@ -129,6 +139,8 @@ impl ChangelogGenerator {
let rest = lines[header_end..].join("\n");
format!("{}\n{}\n{}", header, entry, rest)
} else {
format!("{}{}", CHANGELOG_HEADER, entry)
};
fs::write(changelog_path, new_content)
@@ -378,16 +390,7 @@ pub fn init_changelog(path: &Path) -> Result<()> {
anyhow::bail!("Changelog already exists at {:?}", path);
}
let content = r#"# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
"#;
fs::write(path, content)
fs::write(path, CHANGELOG_HEADER)
.with_context(|| format!("Failed to create changelog: {:?}", path))?;
Ok(())