Skip to content

feat: Fork 会话分支功能 — 真正独立的图片分支#3

Merged
ONEGAYI merged 11 commits into
mainfrom
worktree-fork-session-branch
May 10, 2026
Merged

feat: Fork 会话分支功能 — 真正独立的图片分支#3
ONEGAYI merged 11 commits into
mainfrom
worktree-fork-session-branch

Conversation

@ONEGAYI
Copy link
Copy Markdown
Owner

@ONEGAYI ONEGAYI commented May 10, 2026

Summary

将 Fork 机制从"同一 session 内标记重新生成"改造为"创建新 session + 物理拷贝图片"的独立分支,类似 git branch 的语义。

  • 后端新增 POST /api/sessions/{id}/fork 端点,一次调用完成:创建新 session、数据库级拷贝图片记录、物理拷贝图片文件
  • 前端点击 Fork 按钮立即创建新 session 并自动切换,命名规则 原名 (Fork #N)
  • 移除旧的 fork_from / pendingForkFrom 逻辑

Changes

后端

  • storage.py: 新增 copy_session_images 方法(物理文件拷贝)
  • session.py: 新增 fork 方法(数据库拷贝 + 命名 + 文件编排),含 _extract_filename 辅助
  • sessions.py: 新增 Fork API 路由
  • generate.py: 移除 fork_from 字段和 _resolve_previous 的 fork 分支
  • 3 个新增测试用例:基本拷贝、编号递增、独立性验证

前端

  • api.ts: 新增 forkSession 函数
  • generationStore.ts: 移除 pendingForkFrom 状态
  • DetailPanel.tsx: Fork 按钮→直接 API 调用 + 自动切换 + Toast
  • InputArea.tsx: 移除 fork 提示条 UI
  • types/index.ts: 移除 fork_from
  • i18n: 新增 toast.sessionForked 翻译

Test plan

  • 后端 104 个测试全部通过(含 3 个新增 fork 测试)
  • 手动验证:点击 Fork 创建新 session 并自动切换
  • 手动验证:新 session 包含完整图片历史
  • 手动验证:删除原 session 不影响分支
  • 手动验证:多次 Fork 编号递增

🤖 Generated with Claude Code

Claude and others added 10 commits May 10, 2026 21:14
新增 Fork 功能设计 spec,将当前"同一 session 内 fork_from 标记"
改造为"真正创建新 session + 物理拷贝图片"的独立分支机制。

核心决策:点击即 Fork、数据库级拷贝保留完整历史、
物理拷贝文件保证独立性、保留 response_id 链。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
8 个 Task:后端 Storage/SessionManager/Fork API/清理旧逻辑,
前端 api.ts/types/generationStore/DetailPanel+InputArea/i18n。
TDD 流程,逐步提交。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
在 ImageStore 中添加 copy_session_images 方法,支持将指定图片文件
从源 session 目录物理拷贝到目标 session 目录,用于 Fork 分支功能。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- SessionManager.fork: 数据库级拷贝目标图片及之前所有记录
- 物理拷贝图片文件到新 session 目录
- 命名规则: 原名 (Fork #N),编号自动递增
- 保留 response_id 链和 step 顺序

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
接受 image_id 参数,调用 SessionManager.fork 创建独立分支

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Fork 功能已由独立的 POST /fork 端点替代,生成流程不再需要 fork_from 参数

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Fork 不再通过生成流程触发,改为独立的 API 调用

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- DetailPanel: 点击 Fork 立即创建新 session 并自动切换
- InputArea: 移除旧的 fork 提示条 UI
- 新增 toast.sessionForked 翻译
- Fork 按钮增加 loading 防重复点击

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- 提取 _extract_filename 辅助函数消除重复的 file_path 解析
- fork() 中 fork_count 查询改用 COUNT(*) 替代 fetchall
- 合并两次 db commit 为一次(session 创建 + 图片拷贝)
- copy_session_images 改用 try/except 消除 TOCTOU
- DetailPanel 提取 doFork 消除 handleFork/handleForkLast 重复

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

数据不一致风险

copy_session_images 方法中,如果源 session 中的某个图片文件在 fork 操作前已被删除,FileNotFoundError 异常被静默忽略(except FileNotFoundError: pass)。这会导致目标 session 的数据库记录指向不存在的文件,引发数据不一致。触发场景:磁盘故障或手动误删源 session 图片文件后,fork 操作创建的新 session 将缺少对应图片,但数据库仍记录其存在。

def copy_session_images(
    self,
    src_session_id: str,
    dst_session_id: str,
    file_names: list[str],
) -> None:
    """将源 session 中的指定图片文件物理拷贝到目标 session 目录"""
    src_dir = self._images_dir / src_session_id
    dst_dir = self._images_dir / dst_session_id
    dst_dir.mkdir(parents=True, exist_ok=True)
    for name in file_names:
        try:
            (dst_dir / name).write_bytes((src_dir / name).read_bytes())
        except FileNotFoundError:
            pass

避免 fork 后数据库记录指向不存在的文件导致数据不一致。
如果源文件缺失,整个 fork 操作将失败并回滚。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@ONEGAYI
Copy link
Copy Markdown
Owner Author

ONEGAYI commented May 10, 2026

/review -i

@github-actions
Copy link
Copy Markdown

Incremental PR Reviewer Guide 🔍

⏮️ Review for commits since previous PR-Agent review Starting from commit a650362.

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 1 🔵⚪⚪⚪⚪
🧪 PR contains tests
🔒 Security concerns

⚡ No major issues detected

@ONEGAYI ONEGAYI merged commit 6956ed2 into main May 10, 2026
2 checks passed
@ONEGAYI ONEGAYI deleted the worktree-fork-session-branch branch May 10, 2026 14:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant