一、一个让你"少加班"的故事
周六下午,小张在调试一个订单系统。他和 Claude Code 已经聊了40轮------从用户模块改到支付接口,Claude 记住了他偏好的错误处理模式、项目目录结构,甚至连上次踩过的坑都门儿清。
老板突然发消息:"订单超时补偿逻辑改成每5分钟轮询一次,别再用消息队列了。"
"可我们明明讨论过消息队列才是最佳实践啊!"小张内心在咆哮。以前他只能硬着头皮做下去,要么就推倒重来,重新给新会话讲解30分钟项目背景。
但小张微微一笑,输入:
text
/branch mq-vs-polling
一瞬间,当前会话的所有记忆------40轮对话、代码修改记录、上下文信息------被完整"克隆"了一份。新会话在分支中诞生,原会话完好无损。他在分支里放心地测试轮询方案,满意后把改动同步回主分支。
这个故事的核心秘密就是 /branch------Claude Code 中最被低估的会话分叉命令。
二、从"一碗面"到"两碗面":理解会话与分叉
2.1 什么是"会话"?
想象你在一家面馆点了一碗面,服务员记住了你的口味(少盐、加辣、不要香菜)。这个"服务员记住的你的偏好 + 你们之间的所有对话"就是一个会话(Session) 。
在 Claude Code 中,会话就是你与 AI 从启动到退出的所有互动总和,包括:
- 你们的每一轮对话(用户提问 + AI 回答)
- AI 执行过的所有工具调用(读文件、写代码、跑测试、git 操作)
- Claude 积累的所有上下文和中间推理过程
Claude Code 会把这一切以 JSONL 格式(每行一个 JSON 对象的文本文件)保存在本地硬盘上,路径大致是:
bash
~/.claude/projects/<项目路径编码>/<会话UUID>.jsonl
每一个 .jsonl 文件就代表一个独立会话。
2.2 会话 ID:每个会话的"身份证"
每个会话有一个唯一的 Session ID(通常是 UUID 格式),就像身份证号一样。你可以用这些命令来管理会话:
bash
# 开启新会话
claude
# 继续上一次会话
claude --continue
# 恢复指定的命名会话
claude --resume auth-refactor
# 恢复时顺便提个新问题
claude -r auth-refactor "Finish this PR"
如果不指定名称,--resume 会弹出一个交互式选择器让你选。
2.3 /branch 的本质:会话的"复制粘贴"
/branch 的核心原理就是"会话分叉(fork)" ------在交互会话中输入 /branch [可选名称],Claude Code 会:
- 读取当前会话的完整状态:包括所有历史对话、代码修改记录、上下文信息
- 生成一个新的 Session ID:新会话会获得一个全新的"身份证号"
- 复制所有历史消息:新会话的 JSONL 文件会包含原会话的所有历史记录
- 后续对话写入新文件:你在分支中的任何操作,都只写入新会话的文件,原文件纹丝不动
用代码思维来理解,它的行为大致等价于:
python
# 伪代码:/branch 的实现原理示意
def handle_branch_command(current_session_id, branch_name):
# 1. 读取当前会话的完整记录
original_session = load_session_jsonl(current_session_id)
# 2. 生成全新的会话ID(不会覆盖原文件)
new_session_id = generate_uuid()
# 3. 创建新的JSONL文件,复制原会话的所有历史
create_session_jsonl(
session_id=new_session_id,
history=original_session.messages, # 复制所有历史消息
context=original_session.context, # 复制上下文
parent_session_id=current_session_id # 记录父会话(便于追溯)
)
# 4. 将用户切换到新会话
switch_to_session(new_session_id)
# 5. 提示用户分叉成功
print(f"✅ 已创建分支会话: {branch_name or new_session_id}")
print("原会话保持不变,现在你在新分支中工作")
这就是 /branch 背后底层的 --fork-session 机制 ------在 CLI 层面,你可以通过 claude --resume 原会话名 --fork-session 实现同样的效果。
2.4 原会话 vs 分支会话:关系图
text
┌─────────────────────────────────────────────────────────────────┐
│ 会话时间线 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 原会话 ──┬── 消息1 ── 消息2 ── 消息3 ── 消息4 ── 消息5 ──────→ │
│ │ │
│ └── 🍴 /branch [名称] │
│ │ │
│ ▼ │
│ 分支会话 ────────────────────────── 消息5' ── 消息6 ── 消息7 → │
│ ↑ │
│ (继承所有历史) │
│ │
└─────────────────────────────────────────────────────────────────┘
关键点:
- 分支会话继承了原会话的完整历史,所以 Claude 知道你之前讨论的所有内容
- 分支会话的后续对话写入新文件,原会话不受任何影响
- 原会话之后的所有操作,与分支会话完全隔离
三、时序图:/branch 的完整调用过程
下面我们用 Mermaid 时序图 来展示从输入命令到分叉完成的完整流程:
时序图的几个关键节点解析:
- 阶段一(正常交互) :每轮对话都会实时追加到当前会话的 JSONL 文件中,保证会话状态持久化。
- 阶段二(分支创建) :Claude Code 执行的核心操作------读取 → 复制 → 创建新文件 → 切换会话。新会话继承了原会话的所有历史,但获得了一个全新的 Session ID。
- 阶段三(独立演进) :两个会话从此"分道扬镳",后续对话各自写入各自的文件,互不干扰。
四、文件系统视角:会话是如何存储的
理解 /branch 之后,你会发现 Claude Code 的整个会话管理就是一套以文件系统为核心的状态存储机制。
4.1 存储目录结构
bash
~/.claude/
├── projects/ # 所有项目的会话数据
│ ├── my-project_encoded/ # 项目A(路径编码后的目录名)
│ │ ├── 550e8400-e29b-41d4-a716-446655440000.jsonl # 原会话
│ │ ├── a1b2c3d4-e5f6-7890-1234-567890abcdef.jsonl # 分支会话
│ │ └── f9e8d7c6-b5a4-3210-9876-543210fedcba.jsonl # 另一个分支
│ └── another-project_encoded/ # 项目B
│ └── ...
├── CLAUDE.md # 项目级记忆文件
└── config.json # 全局配置
4.2 JSON文件内部格式
每个 .json 文件记录了完整对话,大致是这样的:
json
{"type":"user","uuid":"abc-1","message":"帮我写个登录接口","timestamp":"2026-04-08T10:00:00Z"}
{"type":"assistant","uuid":"abc-2","message":"好的,我来写登录接口...","tool_calls":["read_file","write_file"]}
{"type":"user","uuid":"abc-3","message":"把密码改成bcrypt加密","timestamp":"2026-04-08T10:01:00Z"}
{"type":"assistant","uuid":"abc-4","message":"已修改,使用bcrypt...","tool_calls":["write_file"]}
{"type":"tool_result","uuid":"abc-5","tool":"write_file","result":"success"}
每一行都是一个独立的 JSON 对象,代表一次交互(用户消息、AI 回复或工具执行结果)。
分叉的本质就是 :把原会话的 JSON 文件逐行复制到一个新文件中,然后新会话的所有后续操作只追加到新文件。
4.3 内存中的会话表示
在运行时,Claude Code 会在内存中维护当前会话的完整状态,大致可以理解为:
python
class Session:
def __init__(self, session_id: str, project_path: str):
self.id = session_id
self.project_path = project_path
self.messages: List[Message] = [] # 历史消息列表
self.context: Dict[str, Any] = {} # 上下文缓存
self.model = "claude-sonnet-4-20260514"
self.tools_enabled = True
self.memory = Memory() # CLAUDE.md 记忆体系
def load(self):
"""从 JSONL 文件加载历史"""
filepath = f"~/.claude/projects/{encode_path(self.project_path)}/{self.id}.jsonl"
with open(filepath, 'r') as f:
for line in f:
self.messages.append(json.loads(line))
def append_message(self, msg: Message):
"""追加消息并持久化"""
self.messages.append(msg)
self._persist_to_jsonl(msg)
当你执行 /branch 时,Claude Code 会创建一个新的 Session 实例 ,并将其 messages 初始化为当前会话 messages 的深拷贝(在文件层面表现为复制 JSONL 文件)。
五、最佳用法:实战技巧
5.1 用法一:方案 PK ------ A/B Test 两开花
场景:你正在实现一个支付系统,有两种方案:Stripe 还是 PayPal。
text
# 在原会话中讨论完背景后,创建两个分支
/branch stripe-solution
/branch paypal-solution
# 切换到 stripe-solution 分支,让 Claude 实现 Stripe 方案
# 然后 /resume 回到原会话,再 /resume paypal-solution,实现 PayPal 方案
最后两个分支各自有了完整实现,你可以对比选择,再把选中的分支合并回去。再也不用复制粘贴整个对话了。
5.2 用法二:并行探索 ------ 多线程实验
场景:重构一个复杂模块,不确定哪种架构最好。
text
# 从同一个起点,分叉出三个分支,同时探索三种不同路径
/branch arch-event-driven
/branch arch-command-pattern
/branch arch-strategy-pattern
# 在每个分支里分别实验,Claude 会记住该分支的所有上下文
5.3 用法三:安全实验 ------ 试错不怕翻车
场景:想让 Claude 尝试一个风险较高的改动,比如大规模重命名 API。
text
# 先创建分支保护原会话
/branch experiment-api-rename
# 在分支里放心让 Claude 折腾
# 如果结果满意,记下改动然后同步回主分支
# 如果不满意,直接关闭分支,原会话完好无损
5.4 用法四:多任务隔离 ------ 切换上下文不丢失
场景:正在开发功能 A,老板让你紧急修 Bug B。
text
# 原会话保持功能 A 的上下文
# 创建分支修复 Bug
/branch hotfix-payment-bug
# 修复完成后,/resume 回到原会话继续功能 A 的开发
# 每个会话的上下文都保持纯净,互不污染
5.5 ⚠️ 注意事项
- 每次分叉都有成本 :新会话会复制所有历史消息,如果你在一个超长会话(上百轮对话)上执行
/branch,新会话的初始 token 消耗会比较高。 - 提示缓存可能失效:Claude Code 的提示缓存 TTL 约为 5 分钟,分叉操作可能使原有缓存失效。
- 分支会话数量建议:单项目同时维护 3-5 个活跃分支会话最为合适,太多了会带来管理负担。
- 及时清理 :用完后记得清理不用的分支会话,可以通过
~/.claude/projects/目录手动删除对应的 JSONL 文件。
5.6 相关命令对比
六、总结
| 视角 | 一句话概括 |
|---|---|
| 本质 | /branch = 会话的"Ctrl+C / Ctrl+V",基于 --fork-session 机制实现 |
| 原理 | 复制当前会话的 JSONL 历史文件 → 生成新 Session ID → 后续操作写入新文件 |
| 存储 | ~/.claude/projects/<项目>/<UUID>.jsonl,每行一个 JSON 对象代表一轮交互 |
| 最佳用法 | 方案对比、并行实验、安全试错、多任务隔离 |
| 核心价值 | 让你敢试、敢改、敢折腾,AI 辅助开发的"后悔药"和"平行宇宙" |
一句话记忆 :/branch 就是给 Claude Code 会话装上了"平行宇宙切换器"------原宇宙完好无损,新宇宙随便折腾,折腾完还能回来继续搬砖,真正的"敢试错,才敢创新"。
祝你和 Claude Code 的每一次会话都能"分叉愉快" 🍴