commit-push-sync

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Commit, Smart Sync, and Push Workflow

提交、智能同步与推送工作流

Automates the complete workflow of committing local changes, syncing with remote using a context-aware pull strategy, and pushing updates.
自动化执行提交本地更改、使用上下文感知的拉取策略与远程同步、推送更新的完整工作流。

Purpose

目的

Handle the full git workflow in a single command:
  1. Stage and commit changes (following commit skill best practices)
  2. Fetch and evaluate remote state
  3. Sync with remote using the safest strategy for the situation
  4. Push local commits to remote
用单个命令处理完整的git工作流:
  1. 暂存并提交更改(遵循commit技能最佳实践)
  2. 获取并评估远程状态
  3. 采用适合当前场景的最安全策略与远程同步
  4. 将本地commit推送到远程

When to Use

适用场景

Trigger this skill when the user requests:
  • "commit and push"
  • "commit push"
  • "sync changes"
  • "push changes" (after uncommitted work detected)
  • "commit and sync"
  • "update remote"
Do NOT use when:
  • User only wants to commit (use
    /commit
    skill)
  • User only wants to push existing commits (use direct
    git push
    )
  • Working on a branch that shouldn't be pushed yet
  • Conflicts are expected (handle manually)
当用户提出以下请求时触发此技能:
  • "commit and push"
  • "commit push"
  • "sync changes"
  • "push changes"(检测到未提交的工作后)
  • "commit and sync"
  • "update remote"
禁止使用的场景:
  • 用户仅想要提交(使用
    /commit
    技能)
  • 用户仅想要推送已有的commit(直接使用
    git push
  • 工作在尚不应该推送的分支上
  • 预期会出现冲突(手动处理)

Workflow

工作流

Step 1: Fetch and Evaluate State

步骤1:获取并评估状态

CRITICAL: Fetch first. The local tracking ref (
@{u}
) is stale until you fetch. Without fetching,
git log ..@{u}
uses cached data and can miss remote changes.
First, check if upstream tracking exists and determine the correct remote:
bash
UPSTREAM_REF=$(git rev-parse --abbrev-ref @{u} 2>/dev/null)
If no upstream tracking branch (
UPSTREAM_REF
is empty):
Skip to Step 2 (commit), then push with
-u origin <branch>
in Step 4.
If upstream exists, extract the remote name and fetch it:
bash
UPSTREAM_REMOTE=$(echo "$UPSTREAM_REF" | cut -d/ -f1)  # e.g., "origin" from "origin/main"
git fetch "$UPSTREAM_REMOTE"  # MUST succeed — abort entire workflow on failure
IMPORTANT: Always fetch the remote that
@{u}
actually points to, not hardcoded
origin
. A branch may track
upstream/main
or another remote — fetching the wrong remote leaves
@{u}
stale and causes incorrect state classification.
If fetch fails (network error, auth failure, etc.), stop the entire workflow and notify the user. Do not proceed with stale data.
If upstream exists, gather state (run in parallel):
bash
git status                          # Uncommitted changes and branch info
git log @{u}.. --oneline            # Local-only commits (ahead count)
git log ..@{u} --oneline            # Remote-only commits (behind count)
git log @{u}.. --merges --oneline   # Merge commits in local history
Classify the state using the Smart Pull Decision Tree:
After git fetch origin:
+-- Local ahead, remote has nothing     -> just push (no pull needed)
+-- Local behind, no local commits      -> git pull --ff-only
+-- Diverged:
|   +-- Local has merge commits?        -> git pull --no-rebase (merge)
|   +-- >20 local commits to replay?    -> git pull --no-rebase (merge)
|   +-- Few commits, no merges          -> git pull --rebase
|   +-- Any pull fails?                 -> abort, show state, ask user
+-- @{u} not configured                 -> commit, git push -u origin <branch>
Principle: rebase only when cheap and safe (few commits, no merges). Otherwise merge. Never rebase merge commits — rebase drops them and replays their individual commits, causing massive conflicts.
关键:优先执行fetch 本地跟踪引用(
@{u}
)在执行fetch之前是过期的。如果不执行fetch,
git log ..@{u}
会使用缓存数据,可能遗漏远程更改。
首先,检查是否存在上游跟踪分支,并确定正确的远程仓库:
bash
UPSTREAM_REF=$(git rev-parse --abbrev-ref @{u} 2>/dev/null)
如果没有上游跟踪分支(
UPSTREAM_REF
为空):
跳转到步骤2(提交),然后在步骤4中使用
-u origin <branch>
推送。
如果存在上游分支,提取远程仓库名称并执行fetch:
bash
UPSTREAM_REMOTE=$(echo "$UPSTREAM_REF" | cut -d/ -f1)  # 例如,从"origin/main"中提取"origin"
git fetch "$UPSTREAM_REMOTE"  # 必须执行成功——失败则中止整个工作流
重要提示: 始终fetch
@{u}
实际指向的远程仓库,不要硬编码
origin
。一个分支可能跟踪
upstream/main
或其他远程仓库——fetch错误的远程仓库会导致
@{u}
仍然过期,造成状态分类错误。
如果fetch失败(网络错误、认证失败等),立即中止整个工作流并通知用户。不要使用过期数据继续执行。
如果存在上游分支,收集状态信息(并行执行):
bash
git status                          # 未提交的更改和分支信息
git log @{u}.. --oneline            # 仅存在于本地的commit(超前数量)
git log ..@{u} --oneline            # 仅存在于远程的commit(落后数量)
git log @{u}.. --merges --oneline   # 本地历史中的merge commit
使用智能拉取决策树对状态进行分类:
执行git fetch origin后:
+-- 本地超前,远程无新提交     -> 直接推送(无需拉取)
+-- 本地落后,无本地commit      -> git pull --ff-only
+-- 分支分叉:
|   +-- 本地存在merge commit?        -> git pull --no-rebase(merge)
|   +-- 需要重放的本地commit超过20个?    -> git pull --no-rebase(merge)
|   +-- 少量commit,无merge          -> git pull --rebase
|   +-- 任何拉取操作失败?                 -> 中止,展示状态,询问用户
+-- 未配置@{u}                 -> 提交,执行git push -u origin <branch>
原则:仅在成本低且安全的情况下使用rebase(少量commit,无merge)。其他情况使用merge。绝对不要对merge commit执行rebase——rebase会丢弃merge commit并重放其包含的单个commit,导致大量冲突。

Step 2: Commit Changes (if needed)

步骤2:提交更改(如需要)

If uncommitted changes exist, follow the commit skill workflow:
  1. Gather context (run in parallel):
    bash
    git status              # See untracked files (NEVER use -uall flag)
    git diff --staged       # See staged changes
    git diff                # See unstaged changes
    git log -10 --oneline   # Recent commits for style reference
  2. Draft commit message:
    • Summarize nature of changes (feature/fix/refactor/docs/etc.)
    • Focus on "why" rather than "what"
    • Match repository's commit style (from git log)
    • Keep concise (1-2 sentences)
  3. Stage and commit (run sequentially):
    bash
    git add [specific files]  # Prefer specific files over "git add -A"
    
    # Sandbox-safe commit (NEVER use heredoc — sandbox blocks /tmp)
    # For multi-line messages:
    mkdir -p "$TMPDIR" && printf '%s\n' "subject line" "" "Body details here" > "$TMPDIR/commit_msg.txt" && git commit -F "$TMPDIR/commit_msg.txt"
    
    # For single-line messages:
    git commit -m "subject line"
    
    git status  # Verify commit succeeded
Important commit rules (from CLAUDE.md):
  • NEVER skip hooks (no
    --no-verify
    )
  • NEVER use
    git add -A
    or
    git add .
    (specify files to avoid secrets)
  • NEVER commit secrets (.env, credentials.json, etc.)
  • NEVER use heredoc (
    <<EOF
    ) in commit commands (sandbox blocks
    /tmp
    )
  • If pre-commit hook fails, create NEW commit after fixing (never
    --amend
    )
如果存在未提交的更改,遵循commit技能工作流:
  1. 收集上下文(并行执行):
    bash
    git status              # 查看未跟踪文件(绝对不要使用-uall参数)
    git diff --staged       # 查看已暂存的更改
    git diff                # 查看未暂存的更改
    git log -10 --oneline   # 最近的commit,用于参考提交风格
  2. 草拟commit信息
    • 总结更改的性质(功能/修复/重构/文档等)
    • 重点说明“为什么”而非“做了什么”
    • 匹配仓库的commit风格(参考git log)
    • 保持简洁(1-2句话)
  3. 暂存并提交(顺序执行):
    bash
    git add [specific files]  # 优先指定具体文件,而非使用"git add -A"
    
    # 沙箱安全提交(绝对不要使用heredoc——沙箱会阻止/tmp访问)
    # 多行信息的提交方式:
    mkdir -p "$TMPDIR" && printf '%s\n' "subject line" "" "Body details here" > "$TMPDIR/commit_msg.txt" && git commit -F "$TMPDIR/commit_msg.txt"
    
    # 单行信息的提交方式:
    git commit -m "subject line"
    
    git status  # 验证提交成功
重要提交规则(来自CLAUDE.md):
  • 绝对不要跳过钩子(不要加
    --no-verify
  • 绝对不要使用
    git add -A
    git add .
    (指定文件避免提交机密信息)
  • 绝对不要提交机密文件(.env、credentials.json等)
  • 绝对不要在提交命令中使用heredoc(
    <<EOF
    )(沙箱会阻止/tmp访问)
  • 如果pre-commit钩子失败,修复后创建新的commit(绝对不要用
    --amend

Step 3: Sync with Remote (if needed)

步骤3:与远程同步(如需要)

Based on the state classification from Step 1, choose the appropriate strategy:
基于步骤1的状态分类,选择合适的策略:

Case A: Local strictly ahead (no remote-only commits)

场景A:本地完全超前(无远程独有commit)

Skip this step entirely. Go straight to Step 4 (push). This is the most common case.
完全跳过此步骤 直接进入步骤4(推送)。这是最常见的场景。

Case B: Local behind, no local commits (fast-forward)

场景B:本地落后,无本地commit(快进)

bash
git pull --ff-only
This cannot fail with conflicts. If it fails, something unexpected happened — abort and ask user.
bash
git pull --ff-only
此操作不会出现冲突失败。如果失败,说明发生了意外情况——中止并询问用户。

Case C: Diverged — local has merge commits OR >20 local commits

场景C:分支分叉——本地存在merge commit 或 本地commit超过20个

Use merge (not rebase) to preserve merge commits and avoid replaying a large number of commits:
bash
git pull --no-rebase
Why not rebase here:
git rebase
drops merge commits by default and replays their individual commits. A merge commit containing N upstream commits would expand into N individual replays, each potentially conflicting. This is how the 81-commit rebase disaster happens.
If merge conflicts occur:
  1. Immediately abort:
    git merge --abort
  2. Show the user the conflicting state:
    git status
  3. Explain what diverged: show
    git log @{u}.. --oneline
    and
    git log ..@{u} --oneline
  4. Ask the user how to proceed — do NOT auto-resolve
使用merge(而非rebase) 来保留merge commit,避免重放大量commit:
bash
git pull --no-rebase
为什么不使用rebase:
git rebase
默认会丢弃merge commit,并重放其包含的单个commit。一个包含N个上游commit的merge commit会被展开为N次独立重放,每次都可能出现冲突。这就是81个commit重放灾难的成因。
如果出现merge冲突:
  1. 立即中止
    git merge --abort
  2. 向用户展示冲突状态:
    git status
  3. 说明分叉原因:展示
    git log @{u}.. --oneline
    git log ..@{u} --oneline
  4. 询问用户如何处理——不要自动解决

Case D: Diverged — few local commits (<= 20), no merge commits

场景D:分支分叉——少量本地commit(<=20),无merge commit

Rebase is safe here — small, linear history is easy to replay:
bash
git pull --rebase
If rebase conflicts occur:
  1. Immediately abort:
    git rebase --abort
  2. Show the user the conflicting state:
    git status
  3. Explain what diverged
  4. Ask the user how to proceed — do NOT auto-resolve
此时使用rebase是安全的——小型线性历史便于重放:
bash
git pull --rebase
如果出现rebase冲突:
  1. 立即中止
    git rebase --abort
  2. 向用户展示冲突状态:
    git status
  3. 说明分叉原因
  4. 询问用户如何处理——不要自动解决

General conflict handling

通用冲突处理规则

  • NEVER attempt automatic conflict resolution — always abort and ask user
  • NEVER continue a rebase/merge with unresolved conflicts
  • Show conflicting files with
    git status
  • Provide guidance:
    • For rebase: resolve,
      git add
      ,
      git rebase --continue
      , or
      git rebase --abort
    • For merge: resolve,
      git add
      ,
      git commit
      , or
      git merge --abort
  • 绝对不要尝试自动解决冲突——始终中止并询问用户
  • 绝对不要带着未解决的冲突继续rebase/merge
  • 使用
    git status
    展示冲突文件
  • 提供指导:
    • 对于rebase:解决冲突,执行
      git add
      git rebase --continue
      ,或
      git rebase --abort
    • 对于merge:解决冲突,执行
      git add
      git commit
      ,或
      git merge --abort

Step 4: Push to Remote

步骤4:推送到远程

Push commits to remote:
bash
git push
If no upstream tracking branch:
bash
git push -u origin <branch-name>
Ask user to confirm branch name before pushing.
Handle push failures:
ErrorCauseSolution
rejected (non-fast-forward)
Remote updated after our fetchRe-fetch, re-evaluate state, sync again
no upstream branch
New branch never pushed
git push -u origin <branch>
(confirm with user)
protected branch
Branch has push restrictionsNotify user (need PR or permissions)
Force push guidance:
  • NEVER suggest
    git push --force
    for main/master — warn the user if they request it
  • For other branches, only suggest after explicit user request
  • Always use
    --force-with-lease
    over
    --force
    — it checks that the remote hasn't been updated by someone else since your last fetch
  • See
    references/force-push-guidelines.md
    for detailed guidance
  • Warn: "Force push will overwrite remote history.
    --force-with-lease
    provides a safety check."
将commit推送到远程:
bash
git push
如果没有上游跟踪分支:
bash
git push -u origin <branch-name>
推送前请用户确认分支名称。
处理推送失败:
错误原因解决方案
rejected (non-fast-forward)
我们fetch后远程有更新重新fetch,重新评估状态,再次同步
no upstream branch
新分支从未推送过
git push -u origin <branch>
(与用户确认)
protected branch
分支有推送限制通知用户(需要提交PR或申请权限)
强制推送指导:
  • 绝对不要建议对main/master分支使用
    git push --force
    ——如果用户要求需要发出警告
  • 对于其他分支,仅在用户明确要求后建议
  • 始终优先使用
    --force-with-lease
    而非
    --force
    ——它会检查自你上次fetch后远程是否被其他人更新过
  • 详细指导参考
    references/force-push-guidelines.md
  • 警告提示:"强制推送会覆盖远程历史。
    --force-with-lease
    提供了安全校验。"

Step 5: Verify Success

步骤5:验证成功

After successful push:
bash
git status            # Should show "Your branch is up to date with 'origin/<branch>'"
git log -3 --oneline  # Show recent commits for confirmation
Output summary:
  • "Committed: [commit message]" (if committed)
  • "Synced: [N] commits from remote via [merge/rebase/fast-forward]" (if synced)
  • "Pushed: [N] commits to origin/<branch>"
推送成功后:
bash
git status            # 应该显示"Your branch is up to date with 'origin/<branch>'"
git log -3 --oneline  # 展示最近的commit供确认
输出总结:
  • "已提交:[commit信息]"(如果执行了提交)
  • "已同步:通过[merge/rebase/fast-forward]从远程同步了[N]个commit"(如果执行了同步)
  • "已推送:[N]个commit到origin/<branch>"

Stash Workflow (Alternative Pattern)

Stash工作流(可选模式)

For users with unstaged changes who prefer stash over committing. Only use when remote actually has commits to pull (check after fetch).
WARNING:
.claude/settings*.json
files cannot be stashed — the sandbox denies write/unlink on these files. If the working tree has dirty settings files:
  1. Fallback: commit the non-settings dirty files first, then push directly
  2. Or: just push if local is strictly ahead (stash is unnecessary)
bash
git fetch origin
适用于有未暂存更改、偏好使用stash而非提交的用户。仅在远程确实有需要拉取的commit时使用(fetch后检查)。
警告:
.claude/settings*.json
文件无法被stash——沙箱会禁止对这些文件的写入/删除操作。如果工作树中有修改的设置文件:
  1. 备选方案:先提交非设置类的修改文件,然后直接推送
  2. 或者:如果本地完全超前则直接推送(不需要stash)
bash
git fetch origin

Only if
git log ..@{u} --oneline
shows remote commits:

仅当
git log ..@{u} --oneline
显示有远程commit时执行:

LOCAL_MERGES=$(git log @{u}.. --merges --oneline | wc -l) LOCAL_COUNT=$(git log @{u}.. --oneline | wc -l)
git stash
if [ "$LOCAL_MERGES" -gt 0 ] || [ "$LOCAL_COUNT" -gt 20 ]; then git pull --no-rebase # Preserve merge commits else git pull --rebase # Safe for small linear history fi
git stash pop

**Handle stash pop conflicts**:
- Notify user about conflicts after stash pop
- Show conflicting files
- Provide guidance: resolve conflicts, then `git add [files]`
- No `git stash drop` until conflicts resolved
LOCAL_MERGES=$(git log @{u}.. --merges --oneline | wc -l) LOCAL_COUNT=$(git log @{u}.. --oneline | wc -l)
git stash
if [ "$LOCAL_MERGES" -gt 0 ] || [ "$LOCAL_COUNT" -gt 20 ]; then git pull --no-rebase # 保留merge commit else git pull --rebase # 适用于小型线性历史 fi
git stash pop

**处理stash pop冲突:**
- 通知用户stash pop后出现冲突
- 展示冲突文件
- 提供指导:解决冲突,然后执行`git add [files]`
- 冲突解决前不要执行`git stash drop`

Edge Cases

边缘场景

Case 1: Detached HEAD

场景1:分离HEAD状态

bash
undefined
bash
undefined

Check if detached

检查是否处于分离HEAD状态

git symbolic-ref -q HEAD || echo "Detached HEAD"

If detached, notify user: "Cannot push from detached HEAD. Create a branch first: `git checkout -b <branch-name>`"
git symbolic-ref -q HEAD || echo "Detached HEAD"

如果处于分离状态,通知用户:"无法从分离HEAD状态推送。请先创建分支:`git checkout -b <branch-name>`"

Case 2: No Remote Tracking Branch

场景2:无远程跟踪分支

Handled in Step 1 (detected by
git rev-parse --abbrev-ref @{u}
) and Step 4 (push with
-u
).
在步骤1中处理(通过
git rev-parse --abbrev-ref @{u}
检测)和步骤4中处理(使用
-u
推送)。

Case 3: Diverged Branches with Merge Commits

场景3:带有merge commit的分叉分支

This is the critical case that motivated the smart pull strategy. When local history contains merge commits (e.g., from
git merge upstream/main
):
  • NEVER rebase — rebase drops the merge commit and replays all N individual commits from the merged branch
  • Always merge
    git pull --no-rebase
    preserves the merge commit intact
  • Show the user:
    git log @{u}.. --merges --oneline
    to explain why merge was chosen
这是智能拉取策略的核心适配场景。当本地历史包含merge commit时(例如执行过
git merge upstream/main
):
  • 绝对不要执行rebase——rebase会丢弃merge commit,并重放被合并分支的所有N个单个commit
  • 始终使用merge——
    git pull --no-rebase
    会完整保留merge commit
  • 向用户展示:
    git log @{u}.. --merges --oneline
    ,解释选择merge的原因

Case 4: Nothing to Commit or Push

场景4:无内容可提交或推送

bash
git status                 # "nothing to commit, working tree clean"
git log @{u}.. --oneline   # No output = no unpushed commits
Notify user: "No changes to commit or push. Working tree is clean and up to date."
bash
git status                 # "nothing to commit, working tree clean"
git log @{u}.. --oneline   # 无输出 = 无未推送的commit
通知用户:"无需要提交或推送的更改。工作树干净且与远程保持同步。"

Case 5: Fetch Fails

场景5:Fetch失败

If
git fetch origin
fails:
  • Abort the entire workflow — do not proceed with stale tracking refs
  • Show the error to the user
  • Common causes: network issues, auth expired, remote renamed/deleted
如果
git fetch origin
失败:
  • 中止整个工作流——不要使用过期的跟踪引用继续执行
  • 向用户展示错误信息
  • 常见原因:网络问题、认证过期、远程仓库被重命名/删除

Common Mistakes to Avoid

需要避免的常见错误

Don't:
  • Run
    git add -A
    or
    git add .
    (risk committing secrets)
  • Use
    --no-verify
    to skip hooks
  • Force push to main/master without explicit request
  • Auto-resolve merge conflicts (always involve user)
  • Amend commits after hook failures
  • Skip verification steps
  • Use heredoc (
    <<EOF
    ) in commit commands (sandbox blocks
    /tmp
    )
  • Rebase when local history contains merge commits
  • Rebase >20 commits without warning the user
  • Use
    --force
    when
    --force-with-lease
    is available
Do:
  • Stage specific files by name
  • Choose pull strategy based on local history (merge commits? commit count?)
  • Let hooks run (respect pre-commit checks)
  • Create new commits after hook failures
  • Use
    $TMPDIR
    for commit message files
  • Verify success with
    git status
  • Handle errors gracefully with clear user guidance
  • Use
    --force-with-lease
    over
    --force
    when force push is needed
禁止操作:
  • 执行
    git add -A
    git add .
    (有提交机密信息的风险)
  • 使用
    --no-verify
    跳过钩子
  • 没有明确要求就对main/master分支强制推送
  • 自动解决merge冲突(始终需要用户介入)
  • 钩子失败后amend commit
  • 跳过验证步骤
  • 在提交命令中使用heredoc(
    <<EOF
    )(沙箱会阻止/tmp访问)
  • 本地历史包含merge commit时执行rebase
  • 未警告用户就对超过20个commit执行rebase
  • 可以使用
    --force-with-lease
    时使用
    --force
推荐操作:
  • 按名称暂存具体文件
  • 根据本地历史选择拉取策略(是否有merge commit?commit数量?)
  • 让钩子正常执行(遵守pre-commit检查)
  • 钩子失败后创建新的commit
  • 使用
    $TMPDIR
    存储commit信息文件
  • 使用
    git status
    验证操作成功
  • 优雅处理错误,为用户提供清晰的指导
  • 需要强制推送时优先使用
    --force-with-lease
    而非
    --force

Integration with Rules

规则集成

This skill follows the smart pull strategy from
rules/safety-and-git.md
:
Context-aware pull strategy (not unconditional rebase):
  • Rebase only when cheap and safe (few commits, no merges)
  • Merge when local has merge commits or many commits
  • Fast-forward when local has no work
  • Skip pull entirely when local is strictly ahead
Git Safety Protocol:
  • Never update git config
  • Never run destructive commands (--force push to main)
  • Never skip hooks
  • Always create new commits (not amend after failures)
  • Prefer specific file staging
Sandbox-safe commits:
  • Use
    printf
    +
    git commit -F
    for multi-line messages
  • Use
    -m
    for single-line messages
  • Never use heredoc (
    <<EOF
    ) in commit commands
此技能遵循
rules/safety-and-git.md
中的智能拉取策略:
上下文感知的拉取策略(而非无条件rebase):
  • 仅在成本低且安全的情况下使用rebase(少量commit,无merge)
  • 本地有merge commit或大量commit时使用merge
  • 本地无工作时使用快进
  • 本地完全超前时完全跳过拉取
Git安全协议:
  • 绝对不要修改git配置
  • 绝对不要执行破坏性命令(向main分支强制推送)
  • 绝对不要跳过钩子
  • 始终创建新commit(失败后不要amend)
  • 优先指定具体文件暂存
沙箱安全提交:
  • 多行信息使用
    printf
    +
    git commit -F
  • 单行信息使用
    -m
  • 绝对不要在提交命令中使用heredoc(
    <<EOF

Additional Resources

额外资源

Reference Files

参考文件

For detailed guidance:
  • references/conflict-resolution.md
    - Handling merge conflicts during rebase or merge
  • references/force-push-guidelines.md
    - When and how to force push safely
详细指导参考:
  • references/conflict-resolution.md
    - 处理rebase或merge过程中的冲突
  • references/force-push-guidelines.md
    - 何时以及如何安全执行强制推送

Related Skills

相关技能

  • /commit
    - Just commit workflow (no push)
  • Standard git commands for manual control
  • /commit
    - 仅提交工作流(无推送)
  • 标准git命令用于手动控制

Quick Command Reference

快速命令参考

bash
undefined
bash
undefined

ALWAYS fetch the correct remote first (matches @{u})

始终优先fetch正确的远程仓库(与@{u}匹配)

UPSTREAM_REMOTE=$(git rev-parse --abbrev-ref @{u} 2>/dev/null | cut -d/ -f1) git fetch "${UPSTREAM_REMOTE:-origin}"
UPSTREAM_REMOTE=$(git rev-parse --abbrev-ref @{u} 2>/dev/null | cut -d/ -f1) git fetch "${UPSTREAM_REMOTE:-origin}"

Check state AFTER fetch

fetch后检查状态

git status git log @{u}.. --oneline # Unpushed local commits git log ..@{u} --oneline # Remote-only commits to pull git log @{u}.. --merges --oneline # Merge commits in local history
git status git log @{u}.. --oneline # 未推送的本地commit git log ..@{u} --oneline # 需要拉取的远程独有commit git log @{u}.. --merges --oneline # 本地历史中的merge commit

Decision tree:

决策树:

Local strictly ahead (no remote-only commits) — just push

本地完全超前(无远程独有commit)——直接推送

git push
git push

Local behind only (no local commits) — fast-forward

仅本地落后(无本地commit)——快进

git pull --ff-only && git push
git pull --ff-only && git push

Diverged with merge commits or >20 local commits — merge

分叉且有merge commit或超过20个本地commit——merge

git pull --no-rebase && git push
git pull --no-rebase && git push

Diverged with few commits, no merges — rebase

分叉且少量commit,无merge——rebase

git pull --rebase && git push
git pull --rebase && git push

No upstream tracking — set it

无上游跟踪——设置上游

git push -u origin <branch>
git push -u origin <branch>

Sandbox-safe commit (multi-line)

沙箱安全提交(多行)

mkdir -p "$TMPDIR" && printf '%s\n' "subject" "" "body" > "$TMPDIR/commit_msg.txt" && git commit -F "$TMPDIR/commit_msg.txt"
mkdir -p "$TMPDIR" && printf '%s\n' "subject" "" "body" > "$TMPDIR/commit_msg.txt" && git commit -F "$TMPDIR/commit_msg.txt"

Verify success

验证成功

git status # Should show "up to date with origin/<branch>" git log -3 --oneline
undefined
git status # 应该显示"up to date with origin/<branch>" git log -3 --oneline
undefined

Success Criteria

成功标准

A successful commit-push-sync completes when:
  1. All changes are committed (if any uncommitted work existed)
  2. Remote changes are synced using the appropriate strategy (if any remote updates existed)
  3. Local commits are pushed to remote
  4. git status
    shows "Your branch is up to date with 'origin/<branch>'"
  5. No conflicts or errors remain unresolved
  6. Merge commits in local history are preserved (not flattened by rebase)
If any step fails, provide clear guidance and stop — don't proceed to next step until user resolves the issue.
一次成功的commit-push-sync需要满足:
  1. 所有更改都已提交(如果存在未提交的工作)
  2. 远程更改已使用合适的策略同步(如果存在远程更新)
  3. 本地commit已推送到远程
  4. git status
    显示"Your branch is up to date with 'origin/<branch>'"
  5. 没有未解决的冲突或错误
  6. 本地历史中的merge commit被保留(没有被rebase扁平化)
如果任何步骤失败,提供清晰的指导并停止——在用户解决问题前不要进入下一步。