Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,45 @@ macOS 使用独立进程组;Windows 在恢复挂起进程前把它加入作业
完整行解码后才脱敏;过长行整行省略并标记,解析所用原始输出超限则显式失败,
不能把截断内容继续当作完整 Git 结果解析。

### macOS 文件操作先发布本仓库状态,再恢复监听

GitService 的磁盘和命令工作由后台任务执行,界面状态由主线程模型发布。操作期间,工作区暂缓处理
文件监听事件,避免把 Git 中间状态送给项目树和项目服务;嵌套操作共用计数,只有最外层结束才恢复。

暂存、取消暂存、删除和回滚完成后,在恢复监听之前重读本次涉及的仓库,只替换已成功确认的根。
Commit 的行、勾选和对应 Worktree 状态先更新,Diff 再按已确认的根刷新;不重新发现无关仓库,
也不等待 Stash、历史或项目服务。后续文件监听沿用 WorkspaceFeatureModel 自己持有的合并任务,
仍更新项目树、搜索和项目服务;工作区关闭时取消这些任务,不另建脱离生命周期的刷新。

每根状态请求有独立身份,全工作区读取也检查状态版本。新操作开始和完成都会使较早结果失效,
同根操作以实际完成后的读取为准;工作区重置释放旧刷新等待者,旧任务不得结束或发布到新一轮刷新。
读不到状态时保留已知行与未确认的勾选,并显示本地化错误,不把“查询失败”当作“仓库干净”。
局部刷新只能清理对应根已经消失的目录展开状态,不能折叠其他仓库;Worktree 历史窗口和 cursor 保持不变。
同一批涉及多个根时,一个根被较新请求替代,仍须继续确认其他根。父模型与固定 checkout 模型各自维护展开状态;
等待子模型发布后,要按父模型此刻的展开集合列出内容,不能重新插回用户已经折叠的子项。

正确做法:回滚 A 仓库的文件后先确认 A 的状态,B 仓库即使状态读取很慢,也不能延迟 A 的行更新。
不要这样做:解冻后先等待项目重载和全部仓库扫描,再调用一次全量刷新才移除 A 的行。
这一顺序改善等待关系,不保证外部 Git 客户端与 Lithe 写入构成原子事务,也不能据组件测试宣称实机延迟数值。
对应回归见 `GitModuleTests` 的本地操作/竞争请求测试,以及 `LitheCoreLogicTests` 的嵌套解冻、延后刷新和重置测试;
真实磁盘与索引结果由 `GitStatusObservationTests` 使用临时仓库验证,不对用户仓库做破坏性复现。

### 打开的提交面板独立处理外部文件变化

外部新增、修改和删除文件时,Git 状态不能排在项目树、搜索索引或项目服务重载之后。
WorkspaceFeatureModel 为同一批文件事件分别调度 Git 和项目内容的合并刷新任务;两者各自取消与合并,
后续文件事件即使取消了尚未完成的项目重载,也不能丢失这批事件的 Git 刷新。Git 写操作结束后的
非等待式恢复同样调度两项任务,而不是因为存在项目路径就跳过 Git。

需要重新发现监听目录或完整扫描时,先确认监听配置和快照,再读取 Git,最后准备项目服务。
尚无快照的恢复批次由重建流程负责这次 Git 读取,避免在重建前后重复查询同一批状态。
在途 Git 刷新用独立请求身份和工作区代次标识所有者:旧工作区任务结束不能释放新工作区的刷新,
取消期间积累的请求仍由当前工作区持有的任务补读。关闭工作区或卸载模块必须取消这些任务。

正确做法:`pom.xml` 变化引起慢速项目导入时,Commit 仍能收到这次及后续源码编辑的状态。
不要这样做:只把 Git 子进程放到后台,却继续在项目重载返回后才调用 Git 刷新。
分开调度增加了一条有所有者的合并任务,但不引入额外 watcher 或定时轮询,也不保证两项视图在同一帧更新。

### 配置按来源解释,只在明确保存时持久化

可执行文件解析、能力探测和临时策略集中在共享执行入口。临时配置固定解析
Expand Down Expand Up @@ -195,6 +234,8 @@ stdout/stderr 分开,复制原始输出时不混入提示。没有完整变化
保留内存诊断历史,配置的持久化与日志分开。
- 所有 mutation 后的读取都使用独立清理期限:能忽略已取消请求以确认结果,
但会截短正常请求的剩余预算并屏蔽其取消;因此只为已经结束的请求使用。
- 把普通文件事件的 Git 刷新留在项目重载尾部:能少维护一条任务,但慢导入会阻塞已打开的提交面板,
后续事件取消重载时还会丢失刷新,因此分别使用已有的 Git 与项目内容合并任务。

## 后果

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ macOS 和 Windows 可以用不同的 UI 技术实现,但用户看到的交互
表格横向滚动处理,不挤掉提交说明。
- 如果尺寸需要在重启后保留,只在拖动结束时通过现有布局持久化机制保存
最终尺寸,不要在拖动过程中持续写入持久化存储。
- macOS 首次打开、尚无已保存尺寸的工作区,左侧栏默认宽度为 360pt,上半区默认占可用高度的
72%,让中文 Commit 的“修订提交(上一次)”保持一行,并减少初始底部工具窗占用。
默认值由 `WorkbenchLayout` 统一提供,主布局、浮层与功能模型不得各留一份数字。
这是初始布局,不是新的最小尺寸;已有工作区宽高和用户拖动结果优先,不迁移或覆盖旧配置。
- Windows 编辑器标签栏的滚轮处理和活动标签可见性判断必须使用内层可滚动
列表,不能使用包含导航按钮的外层工具栏。滚动直接更新 DOM,不写入应用
状态;手动处理滚轮时使用可取消的原生事件监听,避免浏览器再次应用水平
Expand Down Expand Up @@ -211,6 +215,10 @@ IDEA 的 [BranchesTreeComponent](https://github.com/JetBrains/intellij-community
关闭后重新打开也会挂回。
- `GitGraphInteractionTests.splitPaneBounds` 在两种方向、两种位置及折叠状态
验证原生子视图身份、可见尺寸和传入的确定尺寸,防止恢复为堆栈尺寸探测。
- `WorkbenchMavenLayoutTests.initialLayoutWidensTheSidebarWithoutOverwritingSavedDimensions` 验证新默认值及旧尺寸优先;
`CommitActionButtonStyleTests.defaultSidebarKeepsAmendOnOneLineBesideTheOtherActions` 验证中英文、明暗主题下的
单行高度、按钮对齐与互不重叠。带实际语言包、字体和图标的临时宿主另检查中文标签及原生截图,
普通 SwiftPM 几何测试不代替完整工作台视觉验收。
- `LitheSplitPaneCollapseTests.outerDragSuspendsRowChrome` 使用原生分隔条
事件和 69 行嵌套分支样式,检查拖动时右键覆盖层消失、祖先状态传播、行
内容保持挂载、鼠标松开后覆盖层恢复。测试计时仅作诊断,不代表真实帧率。
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ Git 的工作区、工作树、目录、分支、历史提交和 Stash/Shelf 比
所有仓库比较入口通过 `AppModel` 的共享标签动作进入 `EditorTabItem.repositoryDiff(UUID)`。
同一个仓库、文件和版本组合再次打开时切回已有标签;不同文件、不同提交以及不同类型的比较可以并存。
工作区文件身份不包含暂存状态,暂存或后台刷新不会额外产生标签。仓库路径参与身份,避免嵌套仓库同名文件互相覆盖。
Commit 右键“在新标签页中显示差异”是明确例外:即使已存在同一文件的比较,也创建独立 ID 和会话。
普通“显示差异”和单击仍按比较身份复用,不因新增入口破坏去重。

插件 VCS 的独立比较也使用同一编辑标签与分屏生命周期,但内容来自所属 Provider(版本控制插件后端),
不能为 SVN 等插件激活 Git 或把内容放入 Git 会话。先创建加载中的标签,再异步读取基线;
返回时只填充原标签,不抢回用户已经切走的焦点。标签所有者保存每个读取任务,关闭标签或工作区即取消并移除,
迟到的成功或失败不能复活标签或发布旧错误。隐藏的比较宿主继续保留滚动状态,但不接收命中或辅助功能访问。

每个标签由 `GitRepositoryDiffSession` 单独拥有比较内容、加载状态、文件列表、空白符选项和请求代次。
`GitFeatureModel` 仍共享 Git 服务、监听和写入工作流,不为标签复制整套功能模型。
Expand Down Expand Up @@ -78,6 +85,8 @@ Esc、来源卸载和取消均清理面板;无效落点不改布局。焦点
- 用 SwiftUI 位移移动整张标签:会受标签栏裁剪且参与连续布局;保留现有原生浮动预览。
- 一个可复用的 Diff 预览标签:不能同时对照多个文件与版本,用户明确要求多标签,因此拆分比较会话而不是复用一个缓冲区。
- 每标签复制整个 Git 功能模型:会重复仓库监听、服务和写入状态;只拆分比较内容和加载生命周期。
- 插件比较另开一套覆盖层或借用 Git 的比较模型:会绕过普通标签清理或引入错误的仓库事实;
复用标签身份和原生内容宿主,只由 Provider 返回比较数据。

## 后果

Expand All @@ -96,6 +105,9 @@ Windows 的既有分栏实现不受此次 macOS 呈现改动影响,完整两
- `./scripts/agent-notes/verify-agent-notes.sh`
- 原生事件检查右侧、底部半区、释放提交、Esc 取消、重排、关闭与焦点;实机预览另检查真实字体资源、代码输入、灰色浮动标签及分隔器调整。
- `EditorTabOrderFeatureModelTests` 对工作区、目录、分支/引用、历史、保存更改、冲突与行标记入口在深浅主题下挂载原生编辑分组,检查普通标签、切换保留、分屏与共享关闭;`GitModuleTests` 检查独立会话并发加载、关闭一个会话、刷新及迟到结果隔离。组件验证不替代完整产品与 Windows 实机验收。
- `EditorTabOrderFeatureModelTests.explicitNewDiffTabKeepsAnIndependentSessionWhileOrdinaryOpenReusesItsPreview`
验证同文件显式新标签与普通去重共存;`VcsProviderAppModelTests.providerDiffTabsOwnTheirPendingRequestsWithoutStealingFocus`
用可控 Provider 覆盖返回、关闭标签、关闭工作区的时序与资源释放,不使用真实网络等待。

## 适用范围

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
- 目录 diff 遇到无法导出的文件(例如名字含 `:`,路径校验会拒绝)时,整个 diff 报错,不能跳过。Shelve 保存补丁后会把整个目录清掉,跳过的文件就会被删掉而且没有备份。逐文件操作时,这类文件会被路径校验直接拒绝,所以以前不会出问题。
- macOS 的 Shelve 必须区分"读不到补丁"和"补丁为空":`workingDiffPatch` / `stagedDiffPatch` 读不到时返回 nil,任何一条读不到,整个搁置就中止,不保存也不清理。以前把读取失败当成空补丁跳过,接着照样清理这条变更。
- `discardAll` 能把 `dir/` 识别为未跟踪路径,用 `git clean` 删除,而不是对它执行 `git restore`。
- `discardAll` 的状态查询只传本次路径,不能在每个回滚文件上重复执行全库 `--untracked-files=all`。
复用 porcelain v2 解析器消费重命名源路径的 NUL 记录,避免把以 `?? ` 开头的源文件名误当未跟踪文件。
查询和清理按现有路径参数预算分批,状态、恢复与清理都采用字面路径语义,保护方括号等特殊文件名的邻居。

**macOS 端:**

Expand All @@ -39,6 +42,8 @@
- 逐条执行的写操作(Rollback、Shelve)先去掉同一批里被汇总覆盖的子项。否则同一个文件会在搁置补丁里写两次,恢复时 `git apply` 失败;或者汇总被清理后,子项的 `git restore` 报错并中断。
- 把汇总移到 ChangeList 后,ChangeList 只记录 `dir/` 这一个键,目录下的文件继承它的归属。Core 的提交范围检查(`PathScope`)只按字面路径比较,所以 `commitScope` 会把继承归属的文件逐个列出。否则在该 ChangeList 中提交会被拒,而默认列表的提交会把这些文件一起带走。
- 刷新在等待目录内容时,用户可能折叠或展开目录。列出结果后,如果展开集合变了,就按当前集合重建结果(已经读到的列表直接复用),不能用刷新开始时的旧集合覆盖用户的操作。只有本次读取一开始就请求过、但结果里已经没有的汇总,才会被忘掉。Windows 的 `listExpandedUntrackedDirectories` 遵循同样的规则。
- macOS 文件操作后的局部状态刷新只确认本次仓库;其他根的展开集合和已列出的内容保持不变。
等待子项返回时还要检查状态请求身份,较早读取不能借清理展开集合来折叠较新状态。
- `GitChangeSectionsCache.rows` 把仓库标题、ChangeList 标题和每一条变更拍平成一个行数组,`ForEach` 直接放在 `LazyVStack` 中。

**Windows 端:**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ LSP 设置页离开或切换文件快照时,页面应立即结束等待,下
- `./scripts/macos/verify/verify-runtime-bundle-immutability.sh`
- 用有界 gate 暂停并忽略旧扫描取消,验证新请求和旧消费方都能在释放 gate 前结束。
原生挂载测试保持同一个 LSP 页面,依次应用新增、重命名和删除后的快照。
- 命令行测试没有持续的 AppKit 原生事件循环;挂载测试用单调时钟限定等待,驱动非阻塞绘制轮次,
再检查页面任务实际生成的摘要。不能只等摘要通知,也不能依赖可选截图顺带触发绘制来通过测试。

## 适用范围

Expand Down
Loading
Loading