commit-push-pr

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Commit, Push & PR Skill

Commit、Push与PR技能

Automates the git workflow of committing changes, pushing to GitHub, and opening a PR with intelligent handling of edge cases.
自动化提交变更、推送到GitHub并创建PR的Git工作流,同时智能处理各种边缘情况。

Required Reading

必读内容

Before executing, internalize the git workflow standards: @.claude/rules/git_workflow.md
Key rules:
  • Use Conventional Commits format:
    type(scope): description
  • NEVER attribute Claude in commits or PRs (no co-author, no mentions)
  • NEVER skip pre-commit hooks (no
    --no-verify
    )

执行前,请熟悉Git工作流标准: @.claude/rules/git_workflow.md
核心规则:
  • 使用Conventional Commits格式:
    type(scope): description
  • 绝对不要在提交或PR中提及Claude(不要添加共同作者,不要提及)
  • 绝对不要跳过pre-commit钩子(不要使用
    --no-verify

Execution Workflow

执行流程

Step 1: Assess Git State

步骤1:评估Git状态

Run these commands to understand the current state:
bash
undefined
运行以下命令了解当前状态:
bash
undefined

Detect the default branch (main, master, etc.)

检测默认分支(main、master等)

DEFAULT_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@')
DEFAULT_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@')

Fallback if symbolic-ref fails (e.g., shallow clone or missing HEAD)

当symbolic-ref失败时的备选方案(如浅克隆或缺少HEAD)

if [ -z "$DEFAULT_BRANCH" ]; then DEFAULT_BRANCH=$(git remote show origin 2>/dev/null | grep 'HEAD branch' | awk '{print $NF}') fi
if [ -z "$DEFAULT_BRANCH" ]; then DEFAULT_BRANCH=$(git remote show origin 2>/dev/null | grep 'HEAD branch' | awk '{print $NF}') fi

Final fallback to 'main' if detection fails

若检测失败,最终默认使用'main'

DEFAULT_BRANCH=${DEFAULT_BRANCH:-main}
DEFAULT_BRANCH=${DEFAULT_BRANCH:-main}

Get current branch

获取当前分支

BRANCH=$(git branch --show-current)
BRANCH=$(git branch --show-current)

Check for uncommitted changes

检查是否有未提交的变更

git status --porcelain
git status --porcelain

Check for unpushed commits (if branch has upstream)

检查是否有未推送的提交(如果分支有上游跟踪)

git log origin/$DEFAULT_BRANCH..HEAD --oneline 2>/dev/null || echo "No upstream or no commits ahead"
git log origin/$DEFAULT_BRANCH..HEAD --oneline 2>/dev/null || echo "无上游分支或无超前提交"

Check if branch has upstream tracking

检查分支是否有上游跟踪

git rev-parse --abbrev-ref @{upstream} 2>/dev/null || echo "No upstream"

Determine the state:
- `HAS_CHANGES`: Are there uncommitted changes (staged, unstaged, or untracked)?
- `HAS_UNPUSHED`: Are there commits ahead of origin/$DEFAULT_BRANCH?
- `ON_DEFAULT_BRANCH`: Is current branch the default branch ($DEFAULT_BRANCH)?
- `HAS_UPSTREAM`: Does the branch track a remote?
git rev-parse --abbrev-ref @{upstream} 2>/dev/null || echo "无上游分支"

确定当前状态:
- `HAS_CHANGES`:是否存在未提交的变更(已暂存、未暂存或未跟踪文件)?
- `HAS_UNPUSHED`:是否有超前于origin/$DEFAULT_BRANCH的提交?
- `ON_DEFAULT_BRANCH`:当前分支是否为默认分支($DEFAULT_BRANCH)?
- `HAS_UPSTREAM`:分支是否跟踪远程分支?

Step 2: Handle "Nothing to Do" Case

步骤2:处理“无操作可执行”场景

If
!HAS_CHANGES && !HAS_UNPUSHED
:
Inform user: "No changes to commit and no unpushed commits. Nothing to do."
Exit gracefully.
如果
!HAS_CHANGES && !HAS_UNPUSHED
告知用户:"没有需要提交的变更,也没有未推送的提交。无需执行任何操作。"
优雅退出。

Step 3: Handle "No Changes But Unpushed Commits" Case

步骤3:处理“无变更但有未推送提交”场景

If
!HAS_CHANGES && HAS_UNPUSHED
:
  1. Check if PR already exists:
bash
gh pr list --head "$(git branch --show-current)" --json number,url,title
  1. If PR exists:
    • Offer to push updates to the existing PR
    • Report the PR URL
  2. If no PR:
    • Offer to push and create a new PR
    • Proceed to Step 7
如果
!HAS_CHANGES && HAS_UNPUSHED
  1. 检查PR是否已存在:
bash
gh pr list --head "$(git branch --show-current)" --json number,url,title
  1. 若PR已存在:
    • 提供将更新推送到现有PR的选项
    • 告知PR的URL
  2. 若PR不存在:
    • 提供推送并创建新PR的选项
    • 继续执行步骤7

Step 4: Branch Management (if HAS_CHANGES)

步骤4:分支管理(若存在未提交变更)

If on default branch ($DEFAULT_BRANCH):
  1. Inform user that changes need to go on a feature branch
  2. Stage changes first to analyze them:
bash
git add -A
git diff --staged --stat
  1. Generate a conventional commit message based on the changes (see Step 5)
  2. Derive branch name from commit message:
    • feat(cli): add project list
      feat-cli-add-project-list
    • fix: resolve memory leak
      fix-resolve-memory-leak
    • Rules: lowercase, replace spaces/special chars with hyphens, max 50 chars
  3. Create and checkout the new branch:
bash
git checkout -b <branch-name>
If already on feature branch:
  • Continue with the existing branch
  • Check if PR exists for context
若当前在默认分支($DEFAULT_BRANCH):
  1. 告知用户变更需要提交到特性分支
  2. 先暂存变更以进行分析:
bash
git add -A
git diff --staged --stat
  1. 根据变更生成符合规范的提交信息(见步骤5)
  2. 从提交信息派生分支名称:
    • feat(cli): add project list
      feat-cli-add-project-list
    • fix: resolve memory leak
      fix-resolve-memory-leak
    • 规则:小写,将空格/特殊字符替换为连字符,最长50个字符
  3. 创建并切换到新分支:
bash
git checkout -b <branch-name>
若当前已在特性分支:
  • 继续使用现有分支
  • 检查是否存在相关PR以获取上下文

Step 5: Stage Changes and Generate Commit Message

步骤5:暂存变更并生成提交信息

  1. Stage all changes:
bash
git add -A
  1. Analyze the staged changes:
bash
git diff --staged --stat
git diff --staged
  1. Generate a conventional commit message based on:
    • Files changed (infer scope from directory)
    • Nature of changes (feat/fix/refactor/docs/test/chore)
    • Summarize the "why" not just the "what"
  2. Present the commit message to the user. Example format:
Proposed commit message:

  feat(cli): add project listing command

  Adds a new 'lf project list' command that displays all projects
  in the current workspace with their status.

Do you want to use this message, modify it, or provide your own?
  1. 暂存所有变更:
bash
git add -A
  1. 分析已暂存的变更:
bash
git diff --staged --stat
git diff --staged
  1. 根据以下内容生成符合规范的提交信息:
    • 变更的文件(从目录推断范围)
    • 变更类型(feat/fix/refactor/docs/test/chore)
    • 总结变更的“原因”而非仅“内容”
  2. 向用户展示提交信息示例:
建议的提交信息:

  feat(cli): add project listing command

  Adds a new 'lf project list' command that displays all projects
  in the current workspace with their status.

是否使用此信息、修改它,还是自行提供?

Step 5.5: Quality Check

步骤5.5:质量检查

Skip if:
--quick
flag was passed.
Run quality checks on staged changes before committing.
若传入--quick参数则跳过此步骤
在提交前对已暂存的变更执行质量检查。

1. Auto-fix trivial issues (no prompt needed)

1. 自动修复小问题(无需提示)

Search for and remove debug statements:
bash
undefined
查找并移除调试语句:
bash
undefined

Find files with debug statements

查找包含调试语句的文件

git diff --staged --name-only | xargs grep -l -E "(console.(log|debug|info)|debugger|print()" 2>/dev/null

For each file found:
- Remove `console.log(...)`, `console.debug(...)`, `console.info(...)` statements
- Remove `debugger;` statements
- Remove `print(...)` statements (Python)
- Re-stage the file after fixes

Report: "Auto-fixed: Removed N debug statements from M files"
git diff --staged --name-only | xargs grep -l -E "(console.(log|debug|info)|debugger|print()" 2>/dev/null

对每个找到的文件:
- 移除`console.log(...)`、`console.debug(...)`、`console.info(...)`语句
- 移除`debugger;`语句
- 移除`print(...)`语句(Python)
- 修复后重新暂存文件

告知用户:"自动修复:从M个文件中移除了N条调试语句"

2. Check for issues requiring attention

2. 检查需要关注的问题

Scan staged diff for:
IssueSeverityAction
Hardcoded secrets (API keys, passwords)BLOCKCannot auto-fix - user must remove
Command injection (
shell=True
,
os.system
)
BLOCKCannot auto-fix - user must refactor
Empty catch/except blocksPROPOSESuggest adding error logging
Duplicate code patternsPROPOSESuggest extraction
Unused importsPROPOSESuggest removal
TODO/FIXME commentsWARNNote but allow proceed
扫描已暂存的变更以查找:
问题严重程度操作
硬编码密钥(API密钥、密码)阻止无法自动修复 - 用户必须手动移除
命令注入(
shell=True
os.system
阻止无法自动修复 - 用户必须重构
空的catch/except块建议建议添加错误日志
重复代码模式建议建议提取重构
未使用的导入建议建议移除
TODO/FIXME注释警告仅提示但允许继续

3. Handle blocking issues

3. 处理阻止级问题

If BLOCK issues found:
  • List each issue with file:line reference
  • Stop the workflow
  • User must fix manually and re-run
若发现阻止级问题:
  • 列出每个问题的文件和行号
  • 终止工作流
  • 用户必须手动修复后重新运行

4. Handle proposable fixes

4. 处理建议修复的问题

For each PROPOSE issue:
  • Show: file, line, problem, suggested fix
  • Ask: "Apply this fix? (y/n/all/skip)"
  • If approved: apply edit, re-stage
  • If skipped: continue without fix
对每个建议修复的问题:
  • 展示:文件、行号、问题、建议修复方案
  • 询问:"是否应用此修复?(y/n/all/skip)"
  • 若批准:应用修改并重新暂存
  • 若跳过:不修复继续执行

5. Handle warnings

5. 处理警告级问题

For WARN issues:
  • Display summary
  • Continue without blocking

对警告级问题:
  • 显示摘要
  • 不阻止继续执行

Step 6: Create the Commit

步骤6:创建提交

Create the commit with the approved message:
bash
git commit -m "$(cat <<'EOF'
type(scope): short description

Optional longer description explaining the change.
EOF
)"
Important:
  • Use HEREDOC for multi-line messages
  • Never add co-author or Claude attribution
  • Let pre-commit hooks run (never use
    --no-verify
    )
If commit fails due to pre-commit hook:
  • Report the failure to the user
  • Show the hook output
  • Do NOT retry with
    --no-verify
  • Ask user how to proceed (fix issues or abort)
使用已确认的信息创建提交:
bash
git commit -m "$(cat <<'EOF'
type(scope): short description

Optional longer description explaining the change.
EOF
)"
重要提示:
  • 对多行信息使用HEREDOC格式
  • 绝对不要添加共同作者或提及Claude
  • 让pre-commit钩子正常运行(绝对不要使用
    --no-verify
若提交因pre-commit钩子失败:
  • 向用户报告失败
  • 展示钩子的输出
  • 不要使用
    --no-verify
    重试
  • 询问用户如何处理(修复问题或终止)

Step 7: Push to Remote

步骤7:推送到远程仓库

  1. Check if branch has upstream:
bash
git rev-parse --abbrev-ref @{upstream} 2>/dev/null
  1. If no upstream, push with
    -u
    :
bash
git push -u origin $(git branch --show-current)
  1. If has upstream, regular push:
bash
git push
If push fails due to conflicts:
  • Inform user about the conflict
  • Suggest:
    git pull --rebase origin $DEFAULT_BRANCH
    or
    git merge origin/$DEFAULT_BRANCH
  • Do NOT force push
  1. 检查分支是否有上游跟踪:
bash
git rev-parse --abbrev-ref @{upstream} 2>/dev/null
  1. 若无上游分支,使用
    -u
    参数推送:
bash
git push -u origin $(git branch --show-current)
  1. 若已有上游分支,直接推送:
bash
git push
若推送因冲突被拒绝:
  • 告知用户存在冲突
  • 建议执行:
    git pull --rebase origin $DEFAULT_BRANCH
    git merge origin/$DEFAULT_BRANCH
  • 绝对不要强制推送

Step 8: Create or Report PR

步骤8:创建或报告PR

  1. Check if PR already exists:
bash
gh pr list --head "$(git branch --show-current)" --json number,url,title
  1. If PR exists:
    • Report: "Changes pushed to existing PR: <URL>"
    • Show PR title and number
  2. If no PR exists:
    • Generate PR title from commit message (first line)
    • Generate PR body with summary of changes
    • Create PR:
bash
gh pr create --title "type(scope): description" --body "$(cat <<'EOF'
  1. 检查PR是否已存在:
bash
gh pr list --head "$(git branch --show-current)" --json number,url,title
  1. 若PR已存在:
    • 告知:"变更已推送到现有PR:<URL>"
    • 展示PR的标题和编号
  2. 若PR不存在:
    • 从提交信息生成PR标题(第一行)
    • 生成包含变更摘要的PR正文
    • 创建PR:
bash
gh pr create --title "type(scope): description" --body "$(cat <<'EOF'

Summary

Summary

  • Brief description of changes
  • Brief description of changes

Changes

Changes

  • List of key changes made
  • List of key changes made

Test Plan

Test Plan

  • How to verify these changes work EOF )"

4. Report the new PR URL to the user

---
  • How to verify these changes work EOF )"

4. 向用户告知新PR的URL

---

Branch Name Generation

分支名称生成规则

Convert commit message to valid branch name:
InputOutput
feat(cli): add project list command
feat-cli-add-project-list-command
fix: resolve memory leak in cache
fix-resolve-memory-leak-in-cache
refactor(server): simplify auth flow
refactor-server-simplify-auth-flow
Algorithm:
  1. Take the commit message (first line only)
  2. Lowercase everything
  3. Remove the colon after type/scope
  4. Replace
    (
    and
    )
    with
    -
  5. Replace spaces and special characters with
    -
  6. Collapse multiple hyphens to single hyphen
  7. Trim to max 50 characters at word boundary
  8. Remove trailing hyphens

将提交信息转换为有效的分支名称:
输入输出
feat(cli): add project list command
feat-cli-add-project-list-command
fix: resolve memory leak in cache
fix-resolve-memory-leak-in-cache
refactor(server): simplify auth flow
refactor-server-simplify-auth-flow
算法:
  1. 仅取提交信息的第一行
  2. 全部转换为小写
  3. 移除类型/范围后的冒号
  4. (
    )
    替换为
    -
  5. 将空格和特殊字符替换为
    -
  6. 将多个连续的
    -
    合并为一个
  7. 在单词边界处截断至最长50个字符
  8. 移除末尾的
    -

Error Handling

错误处理

ErrorAction
Pre-commit hook failsShow output, ask user to fix, do NOT bypass
Push rejected (conflicts)Suggest rebase/merge, do NOT force push
PR creation failsShow error, suggest manual creation
Not a git repoInform user, exit
gh CLI not installedInform user how to install
Not authenticated to GitHubSuggest
gh auth login

错误操作
Pre-commit钩子执行失败展示输出,让用户修复,绝对不要绕过
推送被拒绝(冲突)建议执行变基/合并,绝对不要强制推送
PR创建失败展示错误,建议手动创建
当前目录不是Git仓库告知用户,退出
未安装gh CLI告知用户安装方法
未登录GitHub建议执行
gh auth login

Output Format

输出格式

On success, report:
Committed: feat(cli): add project list command
Branch: feat-cli-add-project-list-command
Pushed to: origin/feat-cli-add-project-list-command
PR: https://github.com/owner/repo/pull/123

执行成功后,输出:
已提交:feat(cli): add project list command
分支:feat-cli-add-project-list-command
已推送到:origin/feat-cli-add-project-list-command
PR:https://github.com/owner/repo/pull/123

Notes for the Agent

给Agent的注意事项

  1. Never mention Claude - No co-author lines, no "generated by Claude" in PR descriptions
  2. Respect hooks - Pre-commit hooks exist for a reason, never skip them
  3. Be informative - Tell the user what's happening at each step
  4. Handle errors gracefully - Don't leave the repo in a broken state
  5. Ask when uncertain - If the commit message isn't clear, ask the user
  6. Keep it simple - One commit per invocation, clear linear workflow
  1. 绝对不要提及Claude - 不要添加共同作者,不要在PR描述中出现“由Claude生成”的内容
  2. 尊重钩子 - Pre-commit钩子存在是有原因的,绝对不要跳过
  3. 信息透明 - 在每个步骤告知用户正在执行的操作
  4. 优雅处理错误 - 不要让仓库处于损坏状态
  5. 不确定时询问 - 若提交信息不明确,询问用户
  6. 保持简洁 - 每次调用只创建一个提交,使用清晰的线性工作流