571 lines
15 KiB
Markdown
571 lines
15 KiB
Markdown
# QuiCommit
|
|
|
|
English | [中文文档](README_zh.md)
|
|
|
|
A powerful AI-powered Git assistant for generating conventional commits, tags, and changelogs. Manage multiple Git profiles for different work contexts.
|
|
|
|
[Still in early development, some features may not be complete. Feedback and contributions are welcome.]
|
|
|
|
> ⚠️ **Important Notice**: QuiCommit now uses system keyring to store API keys securely. This change may cause breaking changes to your existing configuration. If you encounter issues after updating, please run `quicommit config reset --force` to reset your configuration, then reconfigure your settings.
|
|
|
|

|
|

|
|

|
|
|
|
|
|
## Features
|
|
|
|
- **AI-Powered Generation**: Generate commits, tags, and changelogs using LLM APIs (Ollama, OpenAI, Anthropic, Kimi, DeepSeek, OpenRouter) or local models
|
|
- **Conventional Commits**: Full support for Conventional Commits and commitlint formats
|
|
- **Profile Management**: Manage multiple Git identities with SSH keys and GPG signing support
|
|
- **Smart Tagging**: Semantic version bumping with AI-generated release notes
|
|
- **Changelog Generation**: Automatic changelog generation in Keep a Changelog format
|
|
- **Security**: Use system keyring to store API keys securely
|
|
- **Interactive UI**: Beautiful CLI with previews and confirmations
|
|
- **Multi-language Support**: Output in 7 languages (English, Chinese, Japanese, Korean, Spanish, French, German)
|
|
- **Config Export/Import**: Backup and restore configuration with optional encryption
|
|
|
|
## Installation
|
|
|
|
### Cargo Install
|
|
|
|
The cargo-installed version may temporarily lag behind the source code progress.
|
|
|
|
```bash
|
|
cargo install quicommit
|
|
```
|
|
|
|
### Install from Source
|
|
|
|
```bash
|
|
git clone https://git.lyz.one/SidneyZhang/QuiCommit.git
|
|
cd QuiCommit
|
|
cargo build --release
|
|
cargo install --path .
|
|
```
|
|
|
|
Requirements: Rust 1.70+, Git 2.0+
|
|
|
|
## Quick Start
|
|
|
|
### Initialize
|
|
|
|
```bash
|
|
quicommit init
|
|
```
|
|
|
|
### Generate Commit
|
|
|
|
```bash
|
|
# AI-generated commit (default)
|
|
quicommit commit
|
|
|
|
# Manual commit
|
|
quicommit commit --manual -t feat -m "add new feature"
|
|
|
|
# Stage all and commit (skips .gitignore-matched files automatically)
|
|
quicommit commit -a
|
|
|
|
# Skip confirmation
|
|
quicommit commit --yes
|
|
|
|
# Use date-based commit message
|
|
quicommit commit --date
|
|
|
|
# Enable LLM thinking/reasoning mode for this commit
|
|
quicommit commit --think
|
|
|
|
# Push after committing
|
|
quicommit commit --push
|
|
```
|
|
|
|
When staging changes (auto-stage or `--all`), files matched by `.gitignore` rules are skipped and any ignored files already in the index are removed; the skipped list is printed for review.
|
|
|
|
### Create Tag
|
|
|
|
```bash
|
|
# Auto-detect version bump
|
|
quicommit tag
|
|
|
|
# Auto-detect version from Cargo.toml/pyproject.toml, fall back to commit analysis
|
|
quicommit tag --auto
|
|
|
|
# Specify bump type
|
|
quicommit tag --bump minor
|
|
|
|
# Custom tag name
|
|
quicommit tag -n v1.0.0
|
|
|
|
# AI-generate tag message
|
|
quicommit tag --generate
|
|
|
|
# Create tag and push to remote
|
|
quicommit tag --push
|
|
```
|
|
|
|
### Generate Changelog
|
|
|
|
```bash
|
|
# Generate for unreleased changes (auto-detects --from from the highest version in the existing changelog)
|
|
quicommit changelog
|
|
|
|
# Generate for specific version
|
|
quicommit changelog --version 1.0.0
|
|
|
|
# Generate from a specific tag
|
|
quicommit changelog --from v0.9.0
|
|
|
|
# AI-generate changelog
|
|
quicommit changelog --generate
|
|
|
|
# Initialize new changelog file
|
|
quicommit changelog --init
|
|
|
|
# Specify output file
|
|
quicommit changelog -o RELEASE_NOTES.md
|
|
```
|
|
|
|
### Manage Profiles
|
|
|
|
```bash
|
|
# Add new profile
|
|
quicommit profile add
|
|
|
|
# List profiles
|
|
quicommit profile list
|
|
|
|
# Show profile details
|
|
quicommit profile show
|
|
|
|
# Switch profile
|
|
quicommit profile switch
|
|
|
|
# Set default profile
|
|
quicommit profile set-default personal
|
|
|
|
# Set profile for current repo
|
|
quicommit profile set-repo personal
|
|
|
|
# Apply profile to current repo
|
|
quicommit profile apply
|
|
|
|
# Apply profile globally
|
|
quicommit profile apply --global
|
|
|
|
# Copy profile
|
|
quicommit profile copy personal work
|
|
|
|
# Edit profile
|
|
quicommit profile edit personal
|
|
|
|
# Remove profile
|
|
quicommit profile remove old-profile
|
|
|
|
# Check profile
|
|
quicommit profile check
|
|
|
|
# View usage statistics
|
|
quicommit profile stats
|
|
|
|
# Manage profile tokens
|
|
quicommit profile token
|
|
```
|
|
|
|
### Git Credential Helper
|
|
|
|
QuiCommit can act as a Git credential helper to securely store and retrieve
|
|
Personal Access Tokens (PATs) via the system keyring. The `credential` command
|
|
is hidden from `--help` because it is invoked automatically by Git, not by end
|
|
users.
|
|
|
|
#### Setup
|
|
|
|
Register QuiCommit as a credential helper for Git:
|
|
|
|
```bash
|
|
# Use the default QuiCommit config
|
|
git config --global credential.helper quicommit
|
|
|
|
# Or specify a custom config file
|
|
git config --global credential.helper "quicommit --config /path/to/config.toml"
|
|
```
|
|
|
|
You can also limit the helper to a specific host:
|
|
|
|
```bash
|
|
git config --global credential.https://github.com.helper quicommit
|
|
```
|
|
|
|
#### How It Works
|
|
|
|
When Git needs credentials (e.g. pushing to a remote), it calls the helper
|
|
following the [gitcredentials protocol](https://git-scm.com/docs/gitcredentials):
|
|
|
|
1. **`get`** — Git asks QuiCommit for a stored PAT matching the requested host.
|
|
QuiCommit searches all configured profiles in the keyring and returns the
|
|
PAT (plus username) if found.
|
|
2. **`store`** — After a successful authentication (e.g. you entered a PAT in
|
|
the Git prompt), Git asks QuiCommit to save it. The PAT is stored in the
|
|
system keyring, bound to the matching profile.
|
|
3. **`erase`** — Git asks QuiCommit to delete a stored PAT for the given host.
|
|
|
|
Host names are mapped to canonical service names (`github.com` → `github`,
|
|
`gitlab.com` → `gitlab`, `bitbucket.org` → `bitbucket`, etc.). Unknown hosts
|
|
are used as-is.
|
|
|
|
#### Removing Stored Credentials
|
|
|
|
To remove a stored PAT, you can either use Git's built-in mechanism:
|
|
|
|
```bash
|
|
echo "protocol=https
|
|
host=github.com" | git credential reject
|
|
```
|
|
|
|
Or remove it via the profile token management command:
|
|
|
|
```bash
|
|
quicommit profile token
|
|
```
|
|
|
|
### Configure LLM
|
|
|
|
```bash
|
|
# Configure Ollama (local)
|
|
quicommit config set-llm ollama
|
|
quicommit config set-llm ollama --base-url http://localhost:11434 --model llama2
|
|
|
|
# Configure OpenAI
|
|
quicommit config set-llm openai
|
|
quicommit config set-api-key YOUR_API_KEY
|
|
|
|
# Configure Anthropic Claude
|
|
quicommit config set-llm anthropic
|
|
quicommit config set-api-key YOUR_API_KEY
|
|
|
|
# Configure Kimi (Moonshot AI)
|
|
quicommit config set-llm kimi
|
|
quicommit config set-api-key YOUR_API_KEY
|
|
quicommit config set-llm kimi --base-url https://api.moonshot.cn/v1 --model moonshot-v1-8k
|
|
|
|
# Configure DeepSeek
|
|
quicommit config set-llm deepseek
|
|
quicommit config set-api-key YOUR_API_KEY
|
|
quicommit config set-llm deepseek --base-url https://api.deepseek.com/v1 --model deepseek-chat
|
|
|
|
# Configure OpenRouter
|
|
quicommit config set-llm openrouter
|
|
quicommit config set-api-key YOUR_API_KEY
|
|
quicommit config set-llm openrouter --base-url https://openrouter.ai/api/v1 --model openai/gpt-4
|
|
|
|
# Set commit format
|
|
quicommit config set-commit-format conventional
|
|
|
|
# Set version prefix
|
|
quicommit config set-version-prefix v
|
|
|
|
# Set changelog path
|
|
quicommit config set-changelog-path CHANGELOG.md
|
|
|
|
# Set output language (en, zh, ja, ko, es, fr, de)
|
|
quicommit config set-language en
|
|
|
|
# Set keep commit types in English
|
|
quicommit config set-keep-types-english true
|
|
|
|
# Set keep changelog types in English
|
|
quicommit config set-keep-changelog-types-english true
|
|
|
|
# Test LLM connection
|
|
quicommit config test-llm
|
|
|
|
# Check keyring availability
|
|
quicommit config check-keyring
|
|
|
|
# Show config file path
|
|
quicommit config path
|
|
|
|
# Export configuration (with optional encryption)
|
|
quicommit config export -o config-backup.toml
|
|
quicommit config export -o config-backup.enc --password
|
|
|
|
# Import configuration
|
|
quicommit config import -i config-backup.toml
|
|
quicommit config import -i config-backup.enc --password
|
|
|
|
# Reset configuration to defaults
|
|
quicommit config reset --force
|
|
```
|
|
|
|
## Command Reference
|
|
|
|
| Command | Alias | Description |
|
|
|---------|-------|-------------|
|
|
| `quicommit init` | `i` | Initialize configuration |
|
|
| `quicommit commit` | `c` | Generate and create commit |
|
|
| `quicommit tag` | `t` | Generate and create tag |
|
|
| `quicommit changelog` | `cl` | Generate changelog |
|
|
| `quicommit profile` | `p` | Manage Git profiles |
|
|
| `quicommit config` | `cfg` | Manage settings |
|
|
| `quicommit credential` | — | Git credential helper (hidden, invoked by Git) |
|
|
|
|
### Commit Options
|
|
|
|
| Option | Description |
|
|
|--------|-------------|
|
|
| `--commit-type` | Commit type (feat, fix, etc.) |
|
|
| `-s, --scope` | Commit scope |
|
|
| `-m, --message` | Commit description |
|
|
| `--body` | Commit body |
|
|
| `-b, --breaking` | Mark as breaking change |
|
|
| `-d, --date` | Use date-based commit message |
|
|
| `--manual` | Manual input, skip AI |
|
|
| `-a, --all` | Stage all changes (skips `.gitignore`-matched files) |
|
|
| `-S, --sign` | GPG sign commit |
|
|
| `--amend` | Amend previous commit |
|
|
| `--dry-run` | Show without committing |
|
|
| `--conventional` | Use Conventional Commits format |
|
|
| `--commitlint` | Use commitlint format |
|
|
| `--no-verify` | Skip commit message verification |
|
|
| `-t, --think` | Enable LLM thinking/reasoning mode (overrides config) |
|
|
| `-y, --yes` | Skip confirmation |
|
|
| `--push` | Push after committing |
|
|
| `--remote` | Specify remote repository (default: origin) |
|
|
|
|
### Tag Options
|
|
|
|
| Option | Description |
|
|
|--------|-------------|
|
|
| `-n, --name` | Tag name |
|
|
| `-b, --bump` | Version bump (major/minor/patch) |
|
|
| `-A, --auto` | Auto-detect version from Cargo.toml/pyproject.toml, fall back to commit analysis (conflicts with `--bump`) |
|
|
| `-m, --message` | Tag message |
|
|
| `-g, --generate` | AI-generate message |
|
|
| `-S, --sign` | GPG sign tag |
|
|
| `-l, --lightweight` | Create lightweight tag |
|
|
| `-f, --force` | Force overwrite existing tag |
|
|
| `-p, --push` | Push to remote |
|
|
| `-r, --remote` | Specify remote repository (default: origin) |
|
|
| `--dry-run` | Dry run |
|
|
| `-t, --think` | Enable LLM thinking/reasoning mode (overrides config) |
|
|
| `-y, --yes` | Skip confirmation |
|
|
|
|
### Changelog Options
|
|
|
|
| Option | Description |
|
|
|--------|-------------|
|
|
| `-o, --output` | Output file path |
|
|
| `--version` | Generate for specific version |
|
|
| `-f, --from` | Generate from specific tag (auto-detected from existing changelog if omitted) |
|
|
| `-t, --to` | Generate to specific ref (default: HEAD) |
|
|
| `-i, --init` | Initialize new changelog file |
|
|
| `-g, --generate` | AI-generate changelog |
|
|
| `--include-hashes` | Include commit hashes |
|
|
| `--include-authors` | Include authors |
|
|
| `--format` | Format (keep-a-changelog, github-releases) |
|
|
| `--dry-run` | Dry run (output to stdout) |
|
|
| `--think` | Enable LLM thinking/reasoning mode (overrides config) |
|
|
| `-y, --yes` | Skip confirmation |
|
|
|
|
## Configuration File
|
|
|
|
Location:
|
|
- Linux: `~/.config/quicommit/config.toml`
|
|
- macOS: `~/Library/Application Support/quicommit/config.toml`
|
|
- Windows: `%APPDATA%\quicommit\config.toml`
|
|
|
|
```toml
|
|
version = "1"
|
|
default_profile = "personal"
|
|
|
|
[profiles.personal]
|
|
name = "personal"
|
|
user_name = "Your Name"
|
|
user_email = "your.email@example.com"
|
|
description = "Personal projects"
|
|
is_work = false
|
|
|
|
[profiles.work]
|
|
name = "work"
|
|
user_name = "Your Name"
|
|
user_email = "your.name@company.com"
|
|
description = "Work projects"
|
|
is_work = true
|
|
organization = "Your Company"
|
|
|
|
[profiles.work.ssh]
|
|
private_key_path = "/home/user/.ssh/id_rsa_work"
|
|
agent_forwarding = true
|
|
|
|
[profiles.work.gpg]
|
|
key_id = "YOUR_GPG_KEY_ID"
|
|
program = "gpg"
|
|
use_agent = true
|
|
|
|
[llm]
|
|
provider = "ollama"
|
|
model = "llama2"
|
|
# base_url = "http://localhost:11434"
|
|
max_tokens = 500
|
|
temperature = 0.7
|
|
timeout = 30
|
|
api_key_storage = "keyring"
|
|
thinking_enabled = false
|
|
|
|
[commit]
|
|
format = "conventional"
|
|
auto_generate = true
|
|
|
|
[tag]
|
|
version_prefix = "v"
|
|
auto_generate = true
|
|
|
|
[changelog]
|
|
path = "CHANGELOG.md"
|
|
auto_generate = true
|
|
|
|
[repo_profiles]
|
|
"/path/to/work/project" = "work"
|
|
"/path/to/personal/project" = "personal"
|
|
```
|
|
|
|
## Environment Variables
|
|
|
|
| Variable | Description |
|
|
|----------|-------------|
|
|
| `QUICOMMIT_CONFIG` | Configuration file path |
|
|
| `EDITOR` | Default editor |
|
|
| `NO_COLOR` | Disable colored output |
|
|
|
|
## Troubleshooting
|
|
|
|
```bash
|
|
# View current configuration
|
|
quicommit config show
|
|
|
|
# Edit configuration file
|
|
quicommit config edit
|
|
|
|
# Set configuration value
|
|
quicommit config set llm.provider ollama
|
|
|
|
# Get configuration value
|
|
quicommit config get llm.provider
|
|
|
|
# Set API key (stored in system keyring)
|
|
quicommit config set-api-key YOUR_API_KEY
|
|
|
|
# Delete API key from keyring
|
|
quicommit config delete-api-key
|
|
|
|
# Test LLM connection
|
|
quicommit config test-llm
|
|
|
|
# List available models
|
|
quicommit config list-models
|
|
|
|
# Check keyring availability
|
|
quicommit config check-keyring
|
|
|
|
# Show config file path
|
|
quicommit config path
|
|
|
|
# Export configuration (with optional encryption)
|
|
quicommit config export -o config-backup.toml
|
|
quicommit config export -o config-backup.enc --password
|
|
|
|
# Import configuration
|
|
quicommit config import -i config-backup.toml
|
|
quicommit config import -i config-backup.enc --password
|
|
|
|
# Reset configuration
|
|
quicommit config reset --force
|
|
```
|
|
|
|
## Contributing
|
|
|
|
Contributions are welcome! Please follow these steps:
|
|
|
|
### Submit a Pull Request
|
|
|
|
1. Fork the repository
|
|
2. Create a feature branch: `git checkout -b feature/your-feature`
|
|
3. Commit changes: `git commit -m 'feat: add new feature'`
|
|
4. Push branch: `git push origin feature/your-feature`
|
|
5. Open a Pull Request
|
|
|
|
### Development Setup
|
|
|
|
```bash
|
|
# Clone repository
|
|
git clone https://git.lyz.one/SidneyZhang/QuiCommit.git
|
|
cd QuiCommit
|
|
|
|
# Fetch dependencies
|
|
cargo fetch
|
|
|
|
# Run in development mode
|
|
cargo run -- commit --help
|
|
|
|
# Run tests
|
|
cargo test
|
|
|
|
# Code quality checks
|
|
cargo clippy
|
|
cargo fmt --check
|
|
```
|
|
|
|
### Code Standards
|
|
|
|
- Follow Rust formatting (run `cargo fmt`)
|
|
- Use Conventional Commits for commit messages
|
|
- Add tests for new features
|
|
- Ensure `cargo clippy` passes with no warnings
|
|
|
|
### Project Structure
|
|
|
|
```
|
|
src/
|
|
├── commands/ # CLI command implementations
|
|
│ ├── commit.rs
|
|
│ ├── tag.rs
|
|
│ ├── changelog.rs
|
|
│ ├── profile.rs
|
|
│ ├── config.rs
|
|
│ └── init.rs
|
|
├── config/ # Configuration management
|
|
│ ├── manager.rs
|
|
│ └── profile.rs
|
|
├── generator/ # AI content generation
|
|
├── git/ # Git operations
|
|
│ ├── commit.rs
|
|
│ ├── tag.rs
|
|
│ └── changelog.rs
|
|
├── llm/ # LLM provider implementations
|
|
│ ├── ollama.rs
|
|
│ ├── openai.rs
|
|
│ ├── anthropic.rs
|
|
│ ├── kimi.rs
|
|
│ ├── deepseek.rs
|
|
│ └── openrouter.rs
|
|
├── i18n/ # Internationalization support
|
|
│ ├── messages.rs
|
|
│ └── translator.rs
|
|
├── utils/ # Utility functions
|
|
│ ├── validators.rs
|
|
│ ├── formatter.rs
|
|
│ ├── crypto.rs
|
|
│ └── editor.rs
|
|
└── main.rs # Program entry point
|
|
```
|
|
|
|
## License
|
|
|
|
MIT License
|
|
|
|
## Acknowledgments
|
|
|
|
- [Conventional Commits](https://www.conventionalcommits.org/) specification
|
|
- [Keep a Changelog](https://keepachangelog.com/) format
|
|
- [Ollama](https://ollama.ai/) for local LLM support
|