git-best-practices
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGit Best Practices
Git最佳实践
Always Active Principles
始终遵循的原则
When this skill is loaded, follow these directives for all git operations:
- Discover before acting — run branch discovery to determine the repo's default and production branches before branching, merging, or opening PRs
- Conventional commits — every commit uses format
type(scope): description - Stage explicitly — add files by name so only intended changes are committed
- Protect shared history — use for force pushes; confirm with the user before any force push
--force-with-lease
当启用此技能时,所有Git操作需遵循以下准则:
- 先探索再操作 — 在进行分支创建、合并或发起PR前,先执行分支探测以确定仓库的默认分支和生产分支
- 约定式提交 — 每个提交均使用 格式
type(scope): description - 显式暂存 — 通过文件名添加文件,确保仅提交预期的更改
- 保护共享历史 — 强制推送时使用 ;任何强制推送前需与用户确认
--force-with-lease
Agent Git Workflow
Agent Git工作流
Follow this sequence when performing git operations:
- Check state — run and
git status; output: working tree and unstaged/staged deltagit diff HEAD - Discover branches — identify and store default/current/(optional) production branch names (see Branch Discovery)
- Stage by name — for each file; verify with
git add path/to/filegit status - Write a conventional commit — with optional body
type(scope): description - Push safely — use regular push by default; use only for rewritten history and only after user confirmation
git push --force-with-lease origin {branch}
执行Git操作时请遵循以下步骤:
- 检查状态 — 运行 和
git status;输出:工作区状态及未暂存/已暂存的差异git diff HEAD - 探测分支 — 识别并存储默认/当前/(可选)生产分支的名称(详见分支探测)
- 按名称暂存 — 对每个文件执行 ;通过
git add path/to/file验证git status - 编写约定式提交 — 使用 格式,可选择性添加提交正文
type(scope): description - 安全推送 — 默认使用常规推送;仅在重写历史且获得用户确认后,使用
git push --force-with-lease origin {branch}
Checkpoint Commits
检查点提交
Agents may create WIP checkpoint commits during long-running tasks. These are development artifacts, cleaned up before PR.
- Prefix with or use standard conventional commit format
wip: - Keep changes logically grouped even in WIP state
- Run before opening a PR to craft a clean narrative
/rewrite-history
在执行长时间任务时,Agent可创建WIP(工作中)检查点提交。这些是开发产物,需在发起PR前清理。
- 前缀使用 或采用标准约定式提交格式
wip: - 即使在WIP状态下,也需将更改进行逻辑分组
- 发起PR前运行 以生成清晰的提交历史
/rewrite-history
Commit Discipline
提交规范
- Stage files explicitly by name:
git add src/auth.ts src/auth.test.ts - Verify staged content with before committing
git status - Keep secrets, files, credentials, and large binaries out of commits — warn the user if staged files look sensitive
.env - Target one logical change per commit in final PR-ready state
- 按名称显式暂存文件:
git add src/auth.ts src/auth.test.ts - 提交前通过 验证已暂存内容
git status - 禁止提交密钥、文件、凭证及大型二进制文件 — 若暂存文件看起来包含敏感信息,需向用户发出警告
.env - 在最终可提交PR的状态下,每个提交仅对应一个逻辑更改
Force Push
强制推送
Use exclusively to protect against overwriting upstream changes:
--force-with-leasebash
git push --force-with-lease origin feat/my-branchAlways confirm with the user before any force push, regardless of branch.
仅使用 以防止覆盖上游更改:
--force-with-leasebash
git push --force-with-lease origin feat/my-branch无论分支类型,任何强制推送前均需与用户确认。
Conventional Commits
约定式提交
Format:
type(scope): descriptionSubject line rules:
- Lowercase, imperative mood, no trailing period
- Under 72 characters
- Scope is optional but preferred when a clear subsystem exists
Common types:
| Type | Use for |
|---|---|
| New functionality |
| Bug fix |
| Documentation only |
| Restructuring without behavior change |
| Performance improvement |
| Maintenance, dependencies, tooling |
| Adding or updating tests |
| CI/CD pipeline changes |
| Build system changes |
| Formatting, whitespace (no logic change) |
格式:
type(scope): description主题行规则:
- 小写、祈使语气、无句末句号
- 长度不超过72个字符
- 作用域(scope)为可选,但在存在清晰子系统时建议添加
常见类型:
| 类型 | 适用场景 |
|---|---|
| 新增功能 |
| 修复Bug |
| 仅修改文档 |
| 重构(无行为变更) |
| 性能优化 |
| 维护、依赖更新、工具配置 |
| 添加或更新测试 |
| CI/CD流水线变更 |
| 构建系统变更 |
| 格式调整、空白字符修改(无逻辑变更) |
Commit Bodies
提交正文
Body is optional — only add one when the change is genuinely non-obvious. The subject line carries the "what"; the body explains "why."
Add a body when:
- The motivation or tradeoff is non-obvious
- Multi-part changes benefit from a bullet list
- External context is needed (links, issue references, root cause)
正文为可选内容 — 仅当更改确实不直观时才添加。主题行说明“做了什么”;正文解释“为什么这么做”。
在以下场景添加正文:
- 动机或权衡方案不直观
- 多部分变更适合用项目符号列表呈现
- 需要外部上下文(链接、问题引用、根本原因)
Examples
示例
<examples>
<example name="simple-fix">
Single-line fix, no body needed:
</example>
<example name="scoped-with-body">
Non-obvious fix with body explaining root cause:
</example>
<example name="multi-part-feature">
Feature with bullet-list body for multi-part changes:
</example>
<example name="ticket-linked">
Monorepo commit with ticket reference in branch and scope:
</example>
<example name="submodule-bump">
Submodule update with downstream commit info:
</example>
</examples>
fix(shell): restore Alt+F terminal navigationfix(shell): use HOMEBREW_PREFIX to avoid path_helper breaking plugins in login shells
macOS path_helper reorders PATH in login shells, putting /usr/local/bin
before /opt/homebrew/bin. This caused `brew --prefix` to resolve the stale
Intel Homebrew, so fzf, zsh-autosuggestions, and zsh-syntax-highlighting
all silently failed to load in Ghostty (which spawns login shells).
Use the HOMEBREW_PREFIX env var (set by brew shellenv in .zshenv) instead
of calling `brew --prefix` — it survives path_helper and is faster.feat(install): add claude bootstrap runtime management
- migrate Claude defaults to declarative files under claude/defaults
- add claude-bootstrap check/fix/uninstall with backup-first migration
- stop stowing full claude/codex runtime trees and tighten drift checksfix(pool-party): handle stale settlement state on reconnect
PoolSettlement contract stays in pending state when the participant
disconnects mid-settlement. Check settlement timestamp and expire
stale entries on reconnect.
Fixes SEND-718chore(submodule): update claude-code
Bump claude-code to 88d0c75 (feat(skills): add tiltup, specalign, and e2e skills).For trivial bumps, or is acceptable.
</example>
<example name="breaking-change">
Breaking change using `!` suffix:
bumpbump claude-code submodulerefactor(api)!: change auth endpoint response format
The /auth/token endpoint now returns { access_token, expires_in }
instead of { token, expiry }. All clients must update their parsers.<examples>
<example name="simple-fix">
单行修复,无需正文:
</example>
<example name="scoped-with-body">
不直观的修复,正文解释根本原因:
</example>
<example name="multi-part-feature">
多部分功能变更,正文使用项目符号列表:
</example>
<example name="ticket-linked">
包含工单引用的单体仓库提交(分支和作用域中均有体现):
</example>
<example name="submodule-bump">
包含下游提交信息的子模块更新:
</example>
</examples>
fix(shell): restore Alt+F terminal navigationfix(shell): use HOMEBREW_PREFIX to avoid path_helper breaking plugins in login shells
macOS path_helper reorders PATH in login shells, putting /usr/local/bin
before /opt/homebrew/bin. This caused `brew --prefix` to resolve the stale
Intel Homebrew, so fzf, zsh-autosuggestions, and zsh-syntax-highlighting
all silently failed to load in Ghostty (which spawns login shells).
Use the HOMEBREW_PREFIX env var (set by brew shellenv in .zshenv) instead
of calling `brew --prefix` — it survives path_helper and is faster.feat(install): add claude bootstrap runtime management
- migrate Claude defaults to declarative files under claude/defaults
- add claude-bootstrap check/fix/uninstall with backup-first migration
- stop stowing full claude/codex runtime trees and tighten drift checksfix(pool-party): handle stale settlement state on reconnect
PoolSettlement contract stays in pending state when the participant
disconnects mid-settlement. Check settlement timestamp and expire
stale entries on reconnect.
Fixes SEND-718chore(submodule): update claude-code
Bump claude-code to 88d0c75 (feat(skills): add tiltup, specalign, and e2e skills).对于简单的版本升级,使用或格式即可接受。
</example>
<example name="breaking-change">
使用`!`后缀标记破坏性变更:
bumpbump claude-code submodulerefactor(api)!: change auth endpoint response format
The /auth/token endpoint now returns { access_token, expires_in }
instead of { token, expiry }. All clients must update their parsers.Branch Discovery
分支探测
Before branching or opening a PR, discover the repo's branch topology. Run these commands and store the results:
bash
undefined在创建分支或发起PR前,需探测仓库的分支拓扑。运行以下命令并存储结果:
bash
undefinedDefault branch (PR target for most repos)
默认分支(大多数仓库的PR目标分支)
gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name'
gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name'
Current branch
当前分支
git branch --show-current
git branch --show-current
Production branch (if different from default)
生产分支(若与默认分支不同)
git branch -r --list 'origin/main' 'origin/master' 'origin/production'
**Fallback when `gh` is unavailable or the repo has no remote:**
```bashgit branch -r --list 'origin/main' 'origin/master' 'origin/production'
**当`gh`不可用或仓库无远程仓库时的 fallback 方案:**
```bashInfer default branch from local refs
从本地引用推断默认分支
git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@'
git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@'
Last resort: check local branches and fail loudly if unknown
最后手段:检查本地分支,若未知则报错
if git rev-parse --verify main >/dev/null 2>&1; then
echo main
elif git rev-parse --verify master >/dev/null 2>&1; then
echo master
else
echo "ERROR: unable to determine default branch (main/master not found)." >&2
exit 1
fi
Store the discovered branch name and reference it throughout. Use the actual branch name in all subsequent commands.if git rev-parse --verify main >/dev/null 2>&1; then
echo main
elif git rev-parse --verify master >/dev/null 2>&1; then
echo master
else
echo "ERROR: unable to determine default branch (main/master not found)." >&2
exit 1
fi
存储探测到的分支名称,并在后续操作中引用。在所有后续命令中使用实际分支名称。Branch Naming
分支命名
Use repository branch naming conventions first. If no convention is documented, use:
Format:
type/description-TICKET-IDExamples:
feat/add-login-SEND-77fix/pool-party-stall-SEN-68chore/update-depshotfix/auth-bypass
Include the ticket ID when an issue exists. Omit when there is no ticket.
优先使用仓库的分支命名规范。若无文档记录的规范,使用以下格式:
格式:
type/description-TICKET-ID示例:
feat/add-login-SEND-77fix/pool-party-stall-SEN-68chore/update-depshotfix/auth-bypass
若存在对应工单,需包含工单ID。无工单时可省略。
Branch Flow
分支流
Use repository branch flow policy first. If policy is undocumented, a common baseline is:
{production-branch} (production deploys)
└── {default-branch} (staging/testnet deploys, PR target)
├── feat/add-feature-TICKET
├── fix/bug-description-TICKET
└── hotfix/* (branches off production branch for hotfixes)- Feature and fix branches start from the default branch
- Hotfix branches start from the production branch
- PRs target the default branch unless the repo uses a single-branch flow
- When default branch and production branch are the same, all PRs target that branch directly
优先使用仓库的分支流策略。若无文档记录的策略,以下为通用基线:
{production-branch}(生产环境部署分支)
└── {default-branch}(预发布/测试网部署分支,PR目标分支)
├── feat/add-feature-TICKET
├── fix/bug-description-TICKET
└── hotfix/*(从生产分支创建的热修复分支)- 功能分支和修复分支从默认分支创建
- 热修复分支从生产分支创建
- PR默认目标为默认分支,除非仓库使用单分支流
- 若默认分支与生产分支为同一分支,所有PR直接目标该分支
Merge Strategy
合并策略
Use repository merge policy first (required in many organizations).
If no policy exists, these defaults are reasonable:
| PR target | Strategy | Rationale |
|---|---|---|
| Feature → default branch | Squash merge | Clean history, one commit per feature |
| Default → production | Merge commit | Preserves the release boundary; visible deploy points |
| Hotfix → production | Squash merge | Single atomic fix on production |
优先使用仓库的合并策略(许多组织强制要求)。
若无相关策略,以下默认方案较为合理:
| PR目标分支 | 策略 | 理由 |
|---|---|---|
| 功能分支 → 默认分支 | Squash Merge(压缩合并) | 历史清晰,每个功能对应一个提交 |
| 默认分支 → 生产分支 | Merge Commit(合并提交) | 保留发布边界;部署节点可见 |
| 热修复分支 → 生产分支 | Squash Merge(压缩合并) | 生产环境上的单个原子性修复 |
PR Workflow
PR工作流
Sizing
大小评估
Pragmatic sizing over arbitrary limits. Each commit tells a clear story regardless of PR size. A PR should be reviewable as a coherent unit — if a reviewer cannot hold the full change in their head, consider splitting.
注重实际可评审性而非任意限制。无论PR大小,每个提交都应讲述清晰的故事。PR应作为一个连贯的单元可被评审 — 若评审者无法完全理解所有更改,考虑拆分PR。
PR Creation
PR创建
Use repo-native PR tooling (, GitLab CLI, or web UI) with:
gh pr create- Short title under 70 characters
- Summary section with 1-3 bullet points
- Test plan as a bulleted checklist
使用仓库原生的PR工具(、GitLab CLI或网页端),并包含:
gh pr create- 不超过70个字符的简短标题
- 包含1-3个项目符号的摘要部分
- 以项目符号清单形式呈现的测试计划
History Rewriting Before PR
PR前的历史重写
For branches with messy WIP history, use to:
/rewrite-history- Backup the branch
- Reset to the base branch tip
- Recommit changes as a clean narrative sequence
- Verify byte-for-byte match with backup
- Confirm with the user before force-pushing rewritten history
- Open PR with link to backup branch
Each rewritten commit introduces one coherent idea, building on the previous — like a tutorial teaching the reader how the feature was built.
对于包含混乱WIP历史的分支,使用命令:
/rewrite-history- 备份分支
- 重置到基准分支的最新提交
- 以清晰的叙事顺序重新提交更改
- 验证与备份分支的字节级一致性
- 重写历史后强制推送前需与用户确认
- 发起PR时附上备份分支链接
每个重写后的提交都应引入一个连贯的想法,基于前一个提交构建 — 就像教程向读者展示功能是如何逐步构建的。