Files
opencode/command/auto-commit.md
2026-01-12 17:39:49 +08:00

241 lines
11 KiB
Markdown

---
description: Auto-generate commit message, commit and create tag
agent: build
---
# auto-commit
Auto-generate commit message for staged files, commit to local repository.
## Features
- **Create tag**: Automatically generate version number and create tag by default
- **Skip tag**: Skip creating tag when user inputs "skip" or "skip tag"
> Version number update is **consistent** with git tag: AI will automatically update version number based on project type and changes, and create tag with the same version number.
## Steps
### 1. Check Staging Area
Run `git diff --cached --name-only` to check if there are files in staging area.
**If staging area is empty**:
- Output prompt: "No files in staging area, please use `git add` to add files first."
- **Terminate command execution**, do not continue
### 2. Collect Information (Execute in parallel)
- Run `git status` to view current status
- Run `git diff --cached` to view specific changes in staging area
- Run `git log --oneline -10` to view recent commit history, understand project's commit style
- Run `git tag --list | sort -V | tail -5` to view recent tags
- Read `AGENTS.md` file (if exists), understand project type, structure and **version update rules**
### 3. Detect Repository Type
**Detect repository type (polyrepo or monorepo)**:
- Check if `AGENTS.md` file indicates **monorepo**, if `AGENTS.md` doesn't exist or doesn't clearly indicate, default to **polyrepo**
**If monorepo, analyze change scope**:
- Based on changed files from step 1, analyze if changes only affect a specific subproject
- If only single subproject is affected, record subproject name (e.g., extract `user-service` from path `packages/user-service/src/index.ts`)
### 4. Detect Project Type and Determine Version Number
**Prioritize reading version update rules from AGENTS.md**:
If `AGENTS.md` defines version update rules (such as version file path, version field name, etc.), prioritize using that rule.
**Auto-detect project type** (when AGENTS.md is not defined):
AI needs to intelligently identify project type and determine version file, common project types include but not limited to:
| Project Type | Version File | Version Field/Location |
| --- | --- | --- |
| iOS | `*.xcodeproj/project.pbxproj` | `MARKETING_VERSION` |
| npm/Node.js | `package.json` | `version` |
| Android (Groovy) | `app/build.gradle` | `versionName` |
| Android (Kotlin DSL) | `app/build.gradle.kts` | `versionName` |
| Python (pyproject) | `pyproject.toml` | `[project] version` or `[tool.poetry] version` |
| Python (setup) | `setup.py` | `version` parameter |
| Rust | `Cargo.toml` | `[package] version` |
| Go | Usually only uses git tag | - |
| Flutter | `pubspec.yaml` | `version` |
| .NET | `*.csproj` | `<Version>` or `<PackageVersion>` |
> AI should determine project type based on files that actually exist in repository, can check multiple possible version files if necessary.
**Read current version number**:
1. Read current version number from identified version file
2. Parse as `major.minor.patch`:
- If parsing fails or doesn't exist: treat as `0.1.0`
- If current version only has `major.minor` format, auto-complete to `major.minor.0`
**Calculate new version number** (based on change type):
Version number uses **semantic versioning format**: `0.1.0`, `0.2.0`, ..., `0.9.0`, `1.0.0`, `1.1.0`, `1.1.1`...
- **Default starting version**: `0.1.0`
- **Increment rules**:
- **Major/breaking changes**: `1.2.3` -> `2.0.0` (major +1, minor and patch reset to zero)
- **New feature (feat)**: `1.2.3` -> `1.3.0` (minor +1, patch reset to zero)
- **Bug fix (fix)**: `1.2.3` -> `1.2.4` (patch +1)
**Determine if version number update is needed**:
> Core principle: **Version number reflects "user-perceivable changes"**. Ask yourself: Has the product that users download/use changed?
**Need to update version number** (packaged into final product, user-perceivable):
| commit type | version change | description |
| --- | --- | --- |
| `feat` | minor +1 | new feature |
| `fix` | patch +1 | user-perceivable bug fix |
| `perf` | patch +1 | performance optimization (user-perceivable improvement) |
| breaking change (`!`) | major +1 | API/protocol incompatible changes |
**No need to update version number** (doesn't affect final product, user-imperceptible):
| commit type | description | example |
| --- | --- | --- |
| `chore` | miscellaneous/toolchain | build scripts, CI config, dependency updates |
| `ci` | CI/CD config | `.github/workflows/*.yml`, `release.mjs` |
| `docs` | documentation | README, comments, API docs |
| `test` | test code | unit tests, E2E tests |
| `refactor` | refactoring | code reorganization without changing external behavior |
| `style` | code style | formatting, spaces, semicolons |
| `build` | build config | `tsconfig.json`, `biome.json`, `webpack.config.js` |
**Judgment tips**:
1. **Will the file be packaged into final product?**
- `scripts/`, `.github/`, `*.config.js` -> No -> Don't update version
- `src/`, `lib/`, `app/` -> Yes -> May need to update version
2. **Does the change only affect developers?**
- Dev tool config, CI scripts, build process -> Only affects developers -> Don't update version
- Feature code, UI, API -> Affects users -> Update version
3. **If project type cannot be identified or no version file** -> Only create git tag, don't update version file
### 5. Generate Commit Message
Based on changes in staging area, **analyze and generate meaningful commit message by AI**:
- Analyze changed code content, understand the purpose and intent of this modification
- Reference project's commit history style
- Use [Conventional Commits](https://www.conventionalcommits.org/) specification
- Commit message should concisely but accurately describe "why" rather than just "what"
- Common types: `feat` (new feature), `fix` (fix), `docs` (documentation), `refactor` (refactoring), `chore` (miscellaneous), `test` (test), etc.
- **Language selection**:
- **Default (macOS/Linux)**: Use Chinese (中文) for commit messages
- **Windows**: Use English due to encoding issues with Cursor Shell tool
- **If monorepo and this commit only affects single subproject, include subproject name in commit message**:
- Format: `<type>(<scope>): <description>`, where `<scope>` is subproject name
- Example (Chinese): `feat(ios): 支持 OGG Opus 上传` or `fix(electron): 修复剪贴板注入失败`
- Example (English): `feat(ios): support OGG Opus upload` or `fix(electron): fix clipboard injection failure`
- If affecting multiple subprojects or entire repository, no need to add scope
### 6. Update Project Version Number
> Only execute when step 4 determines version number update is needed and version file is identified
**Execution steps**:
1. Based on version file and field identified in step 4, update version number to calculated new version
2. Add version file to staging area: `git add <version file>`
3. **Verify staging area**: Run `git diff --cached --name-only` to confirm version file is in staging area
### 7. Execute Commit
Execute commit with generated commit message (staging area now includes user's changes and version number update).
**Commit message language by platform:**
**macOS/Linux** (use Chinese commit messages):
```bash
# Single line commit
git commit -m "feat(android): 添加新功能"
# Multi-line commit (recommended)
git commit -m "$(cat <<'EOF'
feat(android): 添加新功能
- 详细说明 1
- 详细说明 2
EOF
)"
```
**Windows** (use English commit messages):
Due to Cursor's Shell tool encoding issues on Windows, **must use English** commit messages.
```powershell
# Single line commit
git commit -m "feat(android): add new feature"
# Multi-line commit (use --message multiple times)
git commit --message="fix(android): fix code review issues" --message="- Fix syntax error" --message="- Use JSONObject instead of manual JSON"
```
**Windows prohibited methods** (will cause garbled text):
- No Chinese commit messages - Cursor Shell tool encoding error when passing Chinese parameters
- No `Out-File -Encoding utf8` - writes UTF-8 with BOM
- No Write tool to write temp files - encoding uncontrollable
- No PowerShell here-string `@"..."@` - newline parsing issues
### 8. Create Tag
> **Executed by default**. Only skip this step when user explicitly inputs "skip" or "skip tag".
> Only create tag when step 4 determines version number update is needed (docs/chore types don't create tag).
**Tag annotation content requirements**:
- **Use the same content as commit message for tag annotation**
- Tag annotation will be used as Release notes by CI/CD scripts, should include detailed change content
- If commit message has multiple lines, tag annotation should also be multi-line
**polyrepo**:
```bash
git tag -a "<version>" -m "<commit title>" -m "" -m "<commit body line 1>" -m "<commit body line 2>" ...
```
**monorepo**:
```bash
git tag -a "<subproject>-<version>" -m "<commit title>" -m "" -m "<commit body line 1>" -m "<commit body line 2>" ...
```
Examples (single line commit):
- polyrepo: `git tag -a "1.2.0" -m "feat: add user authentication"`
- monorepo: `git tag -a "android-1.2.0" -m "feat(android): add user authentication"`
Examples (multi-line commit, more recommended):
- polyrepo:
```bash
git tag -a "1.2.1" -m "fix: resolve bluetooth connection timeout" -m "" -m "- Increase connection timeout to 30s" -m "- Add retry mechanism for failed connections" -m "- Improve error messages"
```
- monorepo:
```bash
git tag -a "android-1.2.1" -m "fix(android): resolve bluetooth connection timeout" -m "" -m "- Increase connection timeout to 30s" -m "- Add retry mechanism for failed connections" -m "- Improve error messages"
```
## Notes
- **Staging area check first**: Must check if staging area has files first, if not, terminate immediately, don't execute any subsequent operations.
- **AGENTS.md priority**: If `AGENTS.md` defines version update rules, prioritize using that rule; otherwise AI auto-detects project type.
- **Smart detection**: AI should intelligently determine project type and version file location based on files that actually exist in repository.
- **Version number and tag consistency**: Project version number and git tag use the same version number, ensure consistency.
- **Version number format**: Use `major.minor.patch` semantic versioning format (e.g., `0.1.0`, `1.1.0`, `1.1.1`), default starting `0.1.0`.
- **Create tag by default**: Unless user inputs "skip" or "skip tag", create tag by default.
- **Update version before commit**: First determine version number and modify version file, then commit at once, avoid using `--amend`.
- **Version file must be verified**: After updating version number and `git add`, must run `git diff --cached --name-only` to confirm version file is in staging area before executing commit.
- **Commit message language**: Default use Chinese (macOS/Linux); Windows must use English due to Cursor Shell tool encoding issues.
- **monorepo scope**: If staging area only affects single subproject, commit message should have scope; if affecting multiple subprojects, no scope needed.
- **monorepo tag format**: Use `<subproject>-<version>` format (e.g., `ios-0.1.0`, `android-1.1.0`).
- **No version file case**: If project type cannot be identified or no version file (like pure Go project), only create git tag, don't update any files.