Carry の Blog Carry の Blog
首页
  • Nginx
  • Prometheus
  • Iptables
  • Systemd
  • Firewalld
  • Docker
  • Sshd
  • DBA工作笔记
  • MySQL
  • Redis
  • TiDB
  • Elasticsearch
  • OpenClaw
  • Hermes Agent
  • Claude Code
  • MySQL8-SOP手册
  • MySQL实战45讲学习笔记
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Carry の Blog

好记性不如烂键盘
首页
  • Nginx
  • Prometheus
  • Iptables
  • Systemd
  • Firewalld
  • Docker
  • Sshd
  • DBA工作笔记
  • MySQL
  • Redis
  • TiDB
  • Elasticsearch
  • OpenClaw
  • Hermes Agent
  • Claude Code
  • MySQL8-SOP手册
  • MySQL实战45讲学习笔记
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • OpenClaw

  • Hermes-Agent

  • Claude-Code

    • Claude Code 概述
    • Claude Code 实战 01|装好之后的第一天:CLI 心智模型与权限体系
    • Claude Code 实战 02|用 CLAUDE.md 做「活文档」,给 Agent 一个稳定的上下文
    • Claude Code 实战 03|让 Claude Code 驾驭 CLI 工具:安装、认证与稳定调用
    • Claude Code 实战 04|把 Git 全流程交给 Agent:rebase 保补丁、抹历史密钥、worktree 灰度
      • 1. 落后上游几十个提交,本地补丁怎么不丢
      • 2. 为什么"记状态"是 Git 自动化的胜负手
      • 3. 四个高频 Git 场景的标准姿势
        • 3.1 rebase 保留本地补丁,安全 force push
        • 3.2 用 git-filter-repo 抹掉误提交的历史密钥
        • 3.3 用 worktree 隔离大版本升级,做灰度
        • 3.4 cherry-pick 跟进 + 关闭"上游已独立修复"的重复 PR
      • 4. 把 Git 交给 Agent 最容易栽的三个坑
        • 坑 1:CLOSED 当成了 Merged
        • 坑 2:rebase / 重写历史后,虚拟环境或路径失效
        • 坑 3:用 --force 而不是 --force-with-lease
      • 5. 可复用要点
      • 6. Agent 可直接解析的元数据块
    • Claude Code 实战 05|会话即资产:transcript 考古与误删恢复
    • Claude Code 实战 06|权限与安全护栏:开了自动权限,怎么保证不翻车
    • Claude Code 实战 07|用 MCP / 自定义工具给 Agent 接外部能力
    • Claude Code 实战 08|子 Agent 与编排:让一个 Agent 变成一支小队
    • Claude Code 实战 09|远程与浏览器:让 Agent 伸手到别人的主机和网页里
    • Claude Code 实战 10|端到端:用 Agent 搭一条博客自动化发布流水线
    • Claude Code 实战 11|Agent 当"运维值班员":多云资产 / DBA / 监控巡检复盘
    • Claude Code 实战 12|盘点跨交易所资产:CLI 包装、私钥安全与金融防错规范
  • AI-Agent
  • Claude-Code
Carry の Blog
2026-07-28
目录

Claude Code 实战 04|把 Git 全流程交给 Agent:rebase 保补丁、抹历史密钥、worktree 灰度原创

# Claude Code 实战 04|把 Git 全流程交给 Agent:rebase 保补丁、抹历史密钥、worktree 灰度

Git 是所有开发流里最不容出错、也最容易被 AI 帮上大忙的一环。它记得住每个提交哈希、每条 reflog、每个远程的名字——这些恰恰是人脑最容易记岔的东西。但 Git 又是"一条 push --force 写错就抹掉历史"的高危工具,所以把它交给 Agent,重点从来不是"会不会 rebase",而是怎么让每一步都可回退、force push 之前必有护栏。

# 1. 落后上游几十个提交,本地补丁怎么不丢

一个常见的开源协作场景:你 fork 了一个上游仓库,在本地分支上打了几个自定义补丁。过了阵子上游往前走了几十个提交,你要把补丁接到最新的上游之上,同时一个都不能丢。

手动做,你得记住:本地那几个提交的哈希是哪些、哪个远程叫 upstream 哪个叫 fork、rebase 之后要用什么姿势 push 才不会把别人的提交冲掉。任何一步记岔,轻则冲突一堆,重则一条 git push --force 把远端历史覆盖掉。

Claude Code 在这里的价值很实在:它把这些易错的"状态记忆"接管了。你说"把我的补丁 rebase 到最新上游、保留全部本地修改",它会先 git status 确认干净、git log 记下本地提交哈希、git remote -v 认清远程拓扑,再动手——每一步都留痕,出了岔子能顺着 reflog 回退。

# 2. 为什么"记状态"是 Git 自动化的胜负手

Git 的绝大多数事故,根因不是命令写错,而是对当前状态的判断错了:

  • 以为工作区干净,其实有未提交改动,rebase 直接把它们卷进冲突;
  • 以为某个提交还没合进上游,催着合并,结果上游早已独立修复;
  • 以为 push --force 推的是自己的分支,其实覆盖了同事刚推的提交。

人会累会忘,Agent 不会——只要你要求它"动手前先核对状态",它就能把 diff、哈希、远程、CI 状态一次性摊清楚再决策。这正是它比"凭记忆敲命令"稳的地方。下面四个高频场景,逐一走一遍。

# 3. 四个高频 Git 场景的标准姿势

# 3.1 rebase 保留本地补丁,安全 force push

# 准备:确认干净 + 记住本地补丁哈希 + 认清远程
git status                      # 必须 "working tree clean"
git log --oneline origin/main..HEAD   # 本地领先上游的提交,就是要保留的补丁
git remote -v                   # 分清 upstream / origin / fork

# 执行:把本地补丁接到最新上游之上
git fetch upstream
git rebase upstream/main

# 验证:补丁数量对得上、内容没丢
git log --oneline upstream/main..HEAD   # 提交数应与 rebase 前一致(哈希已变)

# 推送:用 --force-with-lease,不用 --force
git push --force-with-lease fork my-fix-branch
1
2
3
4
5
6
7
8
9
10
11
12
13
14

关键:force push 一律用 --force-with-lease 而非 --force。 前者会在"远端分支自你上次 fetch 后被别人动过"时拒绝推送,是防止覆盖他人提交的最后一道保险;后者不问青红皂白直接覆盖。

# 3.2 用 git-filter-repo 抹掉误提交的历史密钥

密钥一旦被 commit,就算下一个提交删掉它,它依然躺在历史里,git log -p 一翻就能翻出来。只删文件不够,必须重写历史:

# 用 git-filter-repo(比老的 filter-branch 快且安全)
pip install git-filter-repo

# 把某个文件从全部历史中彻底抹除
git filter-repo --path config/secrets.yaml --invert-paths

# 或按内容替换:把匹配到的密钥串替换成占位符
echo 'AKIA1234567890==>REDACTED' > replacements.txt
git filter-repo --replace-text replacements.txt
1
2
3
4
5
6
7
8
9

做完必须做两件事:① 到密钥的签发方吊销并轮换这个凭证——历史里可能已被别人克隆走,重写历史不等于对方看不到;② 因为历史被重写,需要 --force-with-lease 强推,并通知所有协作者重新 clone。

# 3.3 用 worktree 隔离大版本升级,做灰度

要试一个可能翻车的大改动(比如升级一个跨版本的依赖),别在主工作区里直接搞——用 git worktree 开一个并存的独立工作目录,同一个仓库、不同分支、互不干扰:

# 从主工作区旁边开一个隔离工作树
git worktree add ../repo-upgrade upgrade/major-bump
cd ../repo-upgrade
# 在这里放手折腾升级、跑测试;主工作区保持随时可用

# 验证通过后合回主线,再删掉工作树
git worktree remove ../repo-upgrade
1
2
3
4
5
6
7

好处:主分支始终是"随时能发布"的干净状态;升级实验彻底隔离,成了就合、砸了就删,不留污染。

# 3.4 cherry-pick 跟进 + 关闭"上游已独立修复"的重复 PR

给上游提了 PR 后,要定期核对它是不是已经被合并、或者被上游用另一个提交独立修复了。判断"合没合"不能只看状态字:

# 列出自己的 PR 及其真实合并状态
gh pr list --author @me --state all
gh pr view <PR号> --json state,mergedAt   # state=CLOSED 且 mergedAt=null → 是被关,不是被合

# 判断上游是否已独立修复:diff 关键文件
git fetch upstream
git log --oneline -- path/to/changed_file   # 看上游有没有等价提交
1
2
3
4
5
6
7

如果确认上游已独立修复,优雅的做法是:在 PR 里评论指向上游那个提交,然后 gh pr close,同时把本地对应的临时补丁 drop 掉——否则下次 rebase 会和上游的等价修复撞车。如果只是想把上游某个已合并的提交拿到自己分支,用 git cherry-pick <commit> 单独摘过来即可。

# 4. 把 Git 交给 Agent 最容易栽的三个坑

# 坑 1:CLOSED 当成了 Merged

  • 症状:让 Agent 核对 PR 状态,它看到 state: CLOSED 就报"已合并",实际是被拒绝关闭。
  • 原因:GitHub 里 CLOSED 同时涵盖"被合并"和"被拒绝关闭"两种,光看状态字分不出。
  • 解药:严格以 mergedAt 字段为准——mergedAt 为 null 就是没合并,无论状态字是什么。把这条写进给 Agent 的判断规则。

# 坑 2:rebase / 重写历史后,虚拟环境或路径失效

  • 症状:rebase 完直接跑命令,报 .venv/bin/activate: no such file or directory 或依赖找不到。
  • 原因:历史重写可能改动了目录结构或依赖清单,旧的环境状态对不上了。
  • 解药:把"重写历史后立即重建/校验环境"当成流程的固定收尾步——该重装依赖就重装,别假设环境还在。

# 坑 3:用 --force 而不是 --force-with-lease

  • 症状:force push 覆盖掉了协作者刚推上去的提交,对方的工作凭空消失。
  • 原因:--force 无条件覆盖远端,完全不检查远端是否已被他人更新。
  • 解药:一切 force push 默认 --force-with-lease;远端有变更时它会拒绝推送,逼你先 fetch 核对。把裸 --force 直接写进第一篇讲的 deny 列表更稳。

# 5. 可复用要点

  • 动手前先核对状态:git status / git log / git remote -v / CI 状态先摊清楚,Git 事故绝大多数是状态判断错,不是命令写错。
  • force push 只用 --force-with-lease:这是防止覆盖他人提交的底线;裸 --force 进 deny 列表。
  • 删密钥必须重写历史 + 轮换凭证:git-filter-repo 抹历史,同时到签发方吊销——历史可能已被克隆,重写不等于对方失明。
  • 大改动用 worktree 隔离:主工作区永远保持可发布,实验成了就合、砸了就删。
  • PR 合并判断以 mergedAt 为准:CLOSED ≠ Merged;上游已独立修复的补丁要及时 drop,避免 rebase 撞车。

# 6. Agent 可直接解析的元数据块

{
  "_meta": {
    "doc_version": "2026-07-28",
    "article_id": "claude-code-04-git",
    "profile_context": "any",
    "estimated_setup_time": "25min"
  },
  "quick_start": {
    "step_1": "动手前核对状态:git status(须 clean)+ git log --oneline upstream/main..HEAD + git remote -v",
    "step_2": "rebase 保补丁:git fetch upstream && git rebase upstream/main,验证提交数一致",
    "step_3": "推送用 git push --force-with-lease,禁止裸 --force"
  },
  "safety_rules": [
    "一切 force push 必须使用 --force-with-lease,禁止裸 git push --force",
    "PR 是否合并以 mergedAt 字段为准,state=CLOSED 且 mergedAt=null 视为未合并",
    "删除历史中的密钥必须用 git-filter-repo 重写历史,并到签发方吊销/轮换该凭证",
    "重写历史后必须重建/校验虚拟环境与依赖,不假设旧环境仍可用"
  ],
  "verification": {
    "check_1": "rebase 后 git log --oneline upstream/main..HEAD 的提交数与 rebase 前一致",
    "check_2": "git-filter-repo 后 git log -p | grep <密钥片段> 无任何命中",
    "check_3": "gh pr view <PR> --json state,mergedAt 返回的 mergedAt 决定合并判断"
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

AI Agent 使用指南:

  • 当用户说"把我的补丁同步到最新上游" → 按 quick_start 三步执行,push 阶段强制 --force-with-lease。
  • 当用户说"这个密钥不小心提交了" → 执行 git-filter-repo 重写历史(verification.check_2 验证),并提醒用户吊销轮换凭证。
  • 当用户说"我的 PR 合并了吗" → 以 mergedAt 判断,若上游已独立修复则建议关闭并 drop 本地补丁。

上一篇:Claude Code 实战 03|让 Claude Code 驾驭 CLI 工具:安装、认证与稳定调用 下一篇:Claude Code 实战 05|会话即资产:transcript 考古与误删恢复

#Claude Code#AI Agent#Git#rebase#git-filter-repo
上次更新: 7/29/2026

← Claude Code 实战 03|让 Claude Code 驾驭 CLI 工具:安装、认证与稳定调用 Claude Code 实战 05|会话即资产:transcript 考古与误删恢复→

最近更新
01
单表数据同步方案选型:为什么不该用 mysqldump 做「实时同步」 原创
07-29
02
MySQL 性能压测:Sysbench 1.0 实战 原创
07-29
03
MySQL Router 实现读写分离 原创
07-29
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式