SVN Cleanup 命令详解:作用、用法与常见问题
摘要:
Subversion (SVN) 作为一款集中式版本控制系统,在软件开发和文档管理领域有着广泛的应用。在使用 SVN 的过程中,工作副本 (Working Copy) 的状态至关重要。然而,由于各种原因(如网络中断、客户端崩溃、用户误操作等),工作副本有时会进入一种不一致或锁定的状态,导致后续的 SVN 操作(如 update
, commit
, switch
等)无法正常进行。svn cleanup
命令正是为了解决这类问题而设计的关键工具。本文将深入探讨 svn cleanup
命令的作用机制、详细的命令行与图形界面用法、执行该命令时可能遇到的常见问题及其解决方案,并提供一些最佳实践建议,旨在帮助用户更有效地维护其 SVN 工作副本的健康状态。
目录:
- 引言:SVN 与工作副本的重要性
svn cleanup
的核心作用与工作机制- 2.1 解锁工作副本
- 2.2 完成中断的操作
- 2.3 恢复工作副本的一致性
- 2.4 清理临时文件与日志
svn cleanup
的详细用法- 3.1 命令行接口 (CLI) 用法
- 基本语法
- 常用选项详解 (
--remove-unversioned
,--remove-ignored
,--vacuum-pristines
,--include-externals
等) - 使用示例
- 3.2 图形用户界面 (GUI) 用法 (以 TortoiseSVN 为例)
- 操作步骤
- 选项对应关系
- 3.1 命令行接口 (CLI) 用法
- 常见问题与解决方案 (FAQ)
- 4.1 何时需要执行
svn cleanup
?(常见错误提示) - 4.2
svn cleanup
执行失败或无法解决问题怎么办? - 4.3 “Working copy ‘…’ locked” 错误的具体原因与处理
- 4.4 遇到 “Checksum mismatch” 错误时
cleanup
有用吗? - 4.5
svn cleanup
是否会删除我的本地修改或未版本化的文件? - 4.6
svn cleanup
与svn update
/svn resolve
的关系? - 4.7
cleanup
命令执行缓慢的原因及优化
- 4.1 何时需要执行
- 使用
svn cleanup
的最佳实践 - 总结
1. 引言:SVN 与工作副本的重要性
Subversion (SVN) 是一款成熟且广泛使用的版本控制系统(Version Control System, VCS)。它允许开发者或团队协同工作,追踪文件和目录的历史变更,并能在需要时恢复到之前的版本。SVN 采用集中式模型,即存在一个中央仓库 (Repository) 存储所有版本化的数据,用户通过客户端与仓库交互。
用户在本地计算机上进行工作的基础是 工作副本 (Working Copy)。这是一个包含项目文件特定版本的本地目录树,其中还包含一个特殊的管理区域(通常是名为 .svn
的隐藏子目录),用于存储工作副本的状态信息、元数据以及文件的“原始”副本(pristine copies),以便进行比较和恢复。
工作副本的健康状态直接影响到所有本地 SVN 操作的成败。当工作副本由于某些异常情况(如操作被强制中断)而导致其内部状态与中央仓库或其自身的元数据不一致时,就会出现问题。这时,用户可能会遇到诸如 “Working copy locked”、”Previous operation has not finished” 等错误,无法执行 commit
、update
等关键操作。svn cleanup
命令就是 SVN 提供的用于修复这些工作副本层面问题的“急救箱”。
2. svn cleanup
的核心作用与工作机制
svn cleanup
命令的主要目标是 将一个处于混乱或锁定状态的工作副本恢复到可用、一致的状态。它的工作机制可以概括为以下几个方面:
2.1 解锁工作副本
SVN 在执行某些可能修改工作副本管理区域(.svn
目录)或涉及多个步骤的操作(如 update
, commit
, switch
, merge
)时,为了保证操作的原子性和一致性,会在工作副本的特定目录或整个工作副本上设置 锁 (lock)。这些锁本质上是在 .svn
目录中创建的一些标记文件或数据库条目。正常情况下,操作成功完成后,这些锁会自动被移除。
然而,如果操作过程中发生意外中断(例如:用户强制终止了 SVN 客户端、网络连接突然断开、系统崩溃、磁盘空间不足等),这些锁可能未能被正确清理,从而遗留在工作副本中。这种残留的锁会阻止后续的 SVN 命令对相应区域进行操作,表现为 “Working copy locked” 或类似错误。
svn cleanup
的首要任务就是 检测并移除这些过时或无效的锁。它会递归地扫描指定路径(默认为当前目录)及其子目录下的 .svn
管理区域,查找并删除不再需要的锁标记,从而让工作副本重新变得“自由”,可以接受新的 SVN 命令。
2.2 完成中断的操作
除了移除锁之外,svn cleanup
还会尝试 完成那些被中断的操作所遗留下来的未尽事宜。例如:
- 更新操作 (Update): 如果一次
svn update
在下载完文件、更新完元数据之前被中断,cleanup
会尝试完成这些剩余的步骤,比如应用属性更改、记录新的版本信息等。 - 提交操作 (Commit): 虽然提交的核心部分是原子性的(要么成功要么失败回滚),但客户端在提交前后也可能有一些状态更新。如果中断发生在此类阶段,
cleanup
可能有助于整理状态。 - 切换操作 (Switch) / 合并操作 (Merge): 这些复杂操作涉及大量的文件和元数据变更,中断后更容易留下不一致的状态。
cleanup
会努力使工作副本的元数据与实际文件状态相匹配,并完成挂起的日志记录等。
它通过检查 .svn
目录中记录的操作日志(通常存储在 wc.db
这个 SQLite 数据库文件中)来判断是否有未完成的操作,并尝试根据日志继续执行。
2.3 恢复工作副本的一致性
工作副本的 .svn
目录存储着关于每个文件和目录的大量元数据,包括它们的版本号、URL、属性、最后修改时间戳、以及一份原始的基线副本(pristine copy)的校验和等。cleanup
会检查这些元数据的一致性。虽然它不能修复所有类型的损坏(例如文件内容的物理损坏),但它可以解决一些常见的元数据不一致问题,确保 .svn
内部记录的状态信息是自洽的。
2.4 清理临时文件与日志
在执行操作时,SVN 客户端可能会生成一些临时文件。如果操作未能正常结束,这些临时文件可能残留下来。cleanup
也会负责清理这些不再需要的临时文件。此外,它还会整理 .svn
内部的操作日志,移除已完成或无效的条目。
总结来说,svn cleanup
像是一个工作副本的“维护程序”,它扫描问题区域,修复锁、完成中断的任务、验证并修正元数据、清理垃圾,最终目标是让工作副本回到一个干净、一致、可以正常工作的状态。
3. svn cleanup
的详细用法
svn cleanup
命令可以通过命令行接口 (CLI) 或集成到各种图形用户界面 (GUI) 客户端(如 TortoiseSVN)中使用。
3.1 命令行接口 (CLI) 用法
基本语法
bash
svn cleanup [PATH...] [OPTIONS]
[PATH...]
: 可选参数,指定要执行清理操作的一个或多个工作副本路径。如果省略,cleanup
命令默认在当前工作目录 (.
) 下执行。可以指定多个目录,用空格隔开。该命令会递归地清理指定路径下的所有子目录。
常用选项详解
虽然 svn cleanup
最常用的形式是不带任何选项,但了解其可用选项对于处理特定问题或实现特定目标很有帮助:
--remove-unversioned
:- 作用: 递归地删除工作副本中所有 未版本化 (unversioned) 的文件和目录。未版本化的项是指那些存在于工作副本目录中,但从未被
svn add
命令添加到版本控制的文件或目录。 - 警告: 这是一个具有破坏性的选项! 使用前请务必确认这些未版本化的文件确实是不需要的。它会永久删除这些文件,且无法通过 SVN 恢复。建议先使用
svn status
查看带有?
标记的文件,确认无误后再使用此选项。
- 作用: 递归地删除工作副本中所有 未版本化 (unversioned) 的文件和目录。未版本化的项是指那些存在于工作副本目录中,但从未被
--remove-ignored
:- 作用: 递归地删除工作副本中所有被 忽略 (ignored) 的文件和目录。忽略的项是指那些虽然存在于工作副本中,但通过
svn:ignore
属性或全局忽略设置被告知 SVN 应忽略它们的文件或目录(通常是编译输出、日志文件、临时文件等)。 - 警告: 同样具有破坏性! 确保这些被忽略的文件确实可以安全删除。使用
svn status --no-ignore
可以看到被忽略的项(标记为I
)。
- 作用: 递归地删除工作副本中所有被 忽略 (ignored) 的文件和目录。忽略的项是指那些虽然存在于工作副本中,但通过
--vacuum-pristines
:- 作用: 清理工作副本中存储的 原始副本 (pristine copies)。SVN 在
.svn/pristine/
目录下存储了工作副本中每个版本化文件的基准版本(即从仓库下载时的原始内容)。这使得本地比较(svn diff
)和恢复(svn revert
)操作可以离线快速进行。然而,随着时间的推移和项目的增长,这些原始副本可能会占用大量磁盘空间,并且可能包含一些不再被任何工作副本文件引用的旧版本。--vacuum-pristines
选项会扫描.svn/wc.db
数据库,找出并删除所有不再需要的原始副本文件,从而释放磁盘空间。 - 注意: 这个操作通常是安全的,主要影响磁盘使用量。在 SVN 1.8 及更高版本中,原始副本的管理已经相当高效,此选项的需求可能不如早期版本那么迫切。
- 作用: 清理工作副本中存储的 原始副本 (pristine copies)。SVN 在
--include-externals
:- 作用: 使
cleanup
命令也递归地进入并清理通过svn:externals
属性定义引入的 外部工作副本 (external working copies)。默认情况下,cleanup
只作用于主工作副本。如果外部工作副本也出现了锁定或其他问题,需要使用此选项来一并清理。
- 作用: 使
--quiet
(-q
):- 作用: 执行命令时不打印任何进度信息,只在出错时显示错误消息。
--diff3-cmd CMD
:- 作用: 指定一个替代的
diff3
程序。这在处理合并冲突相关的清理时可能用到,但属于高级用法,普通用户很少需要设置。
- 作用: 指定一个替代的
--config-dir DIR
:- 作用: 指定从哪个目录读取用户配置文件。
--config-option CONFS
:- 作用: 临时设置 SVN 配置项。
使用示例
-
清理当前目录及其子目录:
bash
svn cleanup
这是最常用、最基本的形式。 -
清理指定的项目目录:
bash
svn cleanup /path/to/my/project/working_copy -
清理多个特定子目录:
bash
svn cleanup src/ Maint/ docs/ -
清理工作副本,并删除所有未版本化的文件 (请极其小心!):
bash
# 首先检查哪些文件会被删除
svn status | grep '^\?'
# 确认无误后执行
svn cleanup --remove-unversioned -
清理工作副本,并整理原始副本以节省空间:
bash
svn cleanup --vacuum-pristines -
清理工作副本及其包含的外部定义的工作副本:
bash
svn cleanup --include-externals
3.2 图形用户界面 (GUI) 用法 (以 TortoiseSVN 为例)
TortoiseSVN 是 Windows 平台上非常流行的 SVN 图形客户端。它将 svn cleanup
功能集成到了资源管理器的右键菜单中。
操作步骤
- 定位: 在 Windows 资源管理器中,导航到你的 SVN 工作副本的根目录,或者任何你怀疑存在问题的子目录。
- 右键菜单: 在该目录的空白处(或者直接在该目录文件夹图标上)点击鼠标右键。
- 选择命令: 在弹出的 TortoiseSVN 子菜单中,选择 “Cleanup” (清理)。
(图片引用自 TortoiseSVN 官方文档,仅作示意)
-
配置选项: TortoiseSVN 会弹出一个 “Cleanup” 对话框,提供一系列复选框选项,这些选项通常直接对应于命令行的 flags:
- Clean up working copy status (清理工作副本状态): 这是最核心的功能,相当于不带选项的
svn cleanup
,主要用于解锁和完成中断的操作。通常默认勾选。 - Break write locks (中断写锁): 对应解锁功能。通常默认勾选。
- Fix time stamps (修正时间戳): 让文件的“最后修改时间”与“最后提交时间”一致。一般不需要勾选,除非有特殊需求。
- Vacuum pristine copies (整理原始副本): 对应
--vacuum-pristines
。 - Delete unversioned files and folders (删除未版本化文件和文件夹): 对应
--remove-unversioned
。使用时需格外小心! - Delete ignored files and folders (删除忽略的文件和文件夹): 对应
--remove-ignored
。同样需谨慎! - Include externals (包含外部项): 对应
--include-externals
。 - Make dates current (更新日期为当前): 不常用。
- Clean up working copy status (清理工作副本状态): 这是最核心的功能,相当于不带选项的
-
执行: 根据需要勾选相应的选项(通常保持默认即可,除非明确知道要执行特殊清理),然后点击 “OK”。TortoiseSVN 会显示一个进度窗口,列出它正在执行的操作。
其他 GUI 客户端(如 macOS 上的 Cornerstone、Versions,或集成在 IDE 中的 SVN 插件如 IntelliJ IDEA/Eclipse Subversive/Subclipse)通常也提供类似的图形化界面来执行 cleanup
操作,具体菜单项和选项名称可能略有不同。
4. 常见问题与解决方案 (FAQ)
4.1 何时需要执行 svn cleanup
?(常见错误提示)
你应该在遇到以下情况或错误信息时,首先尝试执行 svn cleanup
:
svn: E155004: Working copy '[PATH]' locked.
(或类似的工作副本锁定错误)svn: E155037: Previous operation has not finished; run 'svn cleanup' only if it was interrupted.
(提示之前的操作未完成)svn: E200030: BUSY: try restarting transaction
(可能由锁引起)svn: E155016: Failed to perform DB query
(有时与工作副本数据库状态有关)svn: E720002: Can't open file '.../.svn/tmp/...': No such file or directory
(可能由中断的操作导致临时文件问题)- 执行
svn update
,svn commit
,svn switch
,svn merge
等命令时意外失败,且错误信息暗示工作副本状态异常。 - 客户端(如图形界面)表现怪异,例如文件状态显示不正确,操作无响应等。
总之,当你的工作副本行为不符合预期,尤其是涉及到锁或操作中断时,svn cleanup
是首选的修复工具。
4.2 svn cleanup
执行失败或无法解决问题怎么办?
如果 svn cleanup
本身执行失败,或者执行成功后问题依旧存在,可以尝试以下步骤:
- 仔细阅读错误信息:
cleanup
失败时通常会给出具体的错误代码和描述。根据错误信息搜索解决方案或判断问题根源(例如,磁盘已满svn: E000028: Can't write to file ...: No space left on device
,权限不足svn: E000013: Can't open file ...: Permission denied
)。 - 在父目录执行
cleanup
: 有时问题可能出在更上层的目录。尝试在工作副本的根目录执行svn cleanup
。 - 检查是否有嵌套的工作副本: 一个常见的复杂情况是在一个工作副本内部意外地创建了另一个工作副本(例如,在
project/
下还有一个project/subdir/.svn
)。这会导致 SVN 行为混乱。找到并移除嵌套的.svn
目录(备份重要数据后操作!),然后重新运行cleanup
。可以使用find . -name .svn -type d
(Linux/macOS) 或类似命令查找。 - 检查
.svn
目录权限: 确保你对工作副本下的所有文件和.svn
目录及其内容有读写权限。 - 检查 SVN 客户端版本: 确保你的 SVN 客户端版本与仓库服务器兼容,并且没有已知的 bug。有时升级客户端可以解决问题。
- 检查磁盘健康状况和文件系统: 磁盘错误或文件系统损坏可能导致
.svn
数据库 (wc.db
) 损坏。运行磁盘检查工具(如chkdsk
on Windows,fsck
on Linux)。 - 终极手段:重新迁出 (Checkout)
- 如果以上方法都无效,最可靠(但也最费时)的解决方案是:
- 备份: 将当前工作副本中有本地修改但未提交的文件 复制 到一个安全的位置。非常重要! 可以使用
svn status
识别已修改 (M
)、新增 (A
但未提交)、未版本化 (?
) 的文件。 - 删除旧工作副本: 将整个有问题的旧工作副本目录删除(或重命名作为备份)。
- 重新 Checkout: 在原位置执行
svn checkout <REPOSITORY_URL> <WORKING_COPY_PATH>
,获取一个全新的、干净的工作副本。 - 恢复修改: 将之前备份的本地修改文件 复制 回新的工作副本相应的位置。
- 检查状态: 使用
svn status
检查,确保所有修改被正确识别。对于新增的文件,需要重新svn add
。 - 提交: 确认无误后,进行提交。
- 备份: 将当前工作副本中有本地修改但未提交的文件 复制 到一个安全的位置。非常重要! 可以使用
- 这个方法相当于用一个全新的、保证健康的工作副本替换掉有问题的旧副本,并手动恢复本地工作进度。
- 如果以上方法都无效,最可靠(但也最费时)的解决方案是:
4.3 “Working copy ‘…’ locked” 错误的具体原因与处理
这个错误明确指出工作副本的某个部分被锁定了。原因通常是:
- SVN 操作异常中断: 这是最常见的原因,如前所述。
- 另一个 SVN 进程正在运行: 可能有另一个 SVN 命令(来自命令行、GUI 工具或 IDE 插件)正在同一个工作副本上执行操作。确保没有其他 SVN 进程在后台运行。有时重启计算机可以解决此类问题。
- 权限问题: 锁文件可能存在,但当前用户没有权限删除它。
- 文件系统问题: 锁文件所在的位置可能存在文件系统层面的问题。
处理方法:
- 运行
svn cleanup
: 这是标准的解决步骤。 - 结束冲突的 SVN 进程: 检查任务管理器或活动监视器,查找名为
svn
或与你的 SVN GUI 相关的进程,并尝试结束它们(谨慎操作)。 - 检查并修复权限。
- 重启计算机。
- 如果问题依然存在,且确定没有其他进程干扰,可能需要参考 4.2 中的高级步骤,甚至考虑手动删除
.svn
目录中的锁文件(极不推荐,除非你完全理解其后果,这通常是在wc.db
文件内的一个条目,而不是一个单独的文件)。在 SVN 1.7+ 中,锁信息主要在wc.db
SQLite 数据库里,手动编辑风险很高。
4.4 遇到 “Checksum mismatch” 错误时 cleanup
有用吗?
通常 svn cleanup
不能直接修复 “Checksum mismatch” (校验和不匹配) 错误。
这个错误意味着工作副本中的某个文件的本地副本内容与其在 .svn
目录中记录的原始副本(pristine copy)的校验和不一致。这通常发生在:
- 文件内容被意外修改(例如,被非 SVN 工具编辑后保存,破坏了 SVN 的元数据预期)。
- 文件传输过程中损坏。
.svn/pristine/
目录下的原始副本本身损坏。
处理方法:
- 确定问题文件: 错误信息通常会指明哪个文件出现校验和不匹配。
- 尝试
svn update --force [FILENAME]
:--force
选项会强制 SVN 从仓库下载该文件的最新版本,覆盖本地版本,并更新元数据。注意:这会丢失该文件的本地修改! 如果需要保留修改,先备份该文件。 - 如果
--force
更新无效或文件没有本地修改:- 备份该文件(如果需要)。
- 执行
svn revert [FILENAME]
将文件恢复到基准版本。 - 执行
svn update [FILENAME]
获取最新版本。
- 如果问题大范围存在或持续出现: 可能工作副本或
.svn
数据库严重损坏。此时,参考 4.2 中的 重新迁出 (Checkout) 方法可能是最有效的。
4.5 svn cleanup
是否会删除我的本地修改或未版本化的文件?
- 标准
svn cleanup
(不带特殊选项): 通常不会 删除你对 已版本化文件 所做的本地修改。它的主要目的是修复元数据和锁,而不是改变受版本控制的文件内容。 - 带
--remove-unversioned
选项: 会 删除所有 未版本化 的文件和目录。 - 带
--remove-ignored
选项: 会 删除所有 被忽略 的文件和目录。
因此,在使用 svn cleanup
时,特别是带有 --remove-...
选项时,一定要清楚这些选项的作用,并在执行前确认不会误删重要数据。 最佳实践是,在执行可能删除文件的 cleanup
之前,先运行 svn status
(可能加上 --no-ignore
查看忽略项)来检查哪些文件会被影响。
4.6 svn cleanup
与 svn update
/ svn resolve
的关系?
这三个命令处理不同类型的问题:
svn cleanup
: 处理 工作副本状态 问题,如锁、中断的操作、元数据不一致。它通常是为了让其他命令(如update
)能够顺利执行而进行的准备或修复步骤。svn update
: 将工作副本与仓库中的特定版本(默认为最新版本)同步。它下载新的变更,并可能导致 内容冲突 (conflicts)。svn resolve
: 用于在svn update
或svn merge
之后,解决文件内容冲突。当 SVN 无法自动合并仓库变更和本地修改时,会标记文件为冲突状态,用户需要手动编辑文件解决冲突,然后使用svn resolve --accept=[...] [FILENAME]
告诉 SVN 冲突已解决。
关系:你可能需要先运行 svn cleanup
来解锁工作副本,然后才能成功运行 svn update
。update
后如果发生冲突,你需要使用 svn resolve
来处理。它们是 SVN 工作流中处于不同阶段、解决不同问题的工具。
4.7 cleanup
命令执行缓慢的原因及优化
svn cleanup
需要递归扫描工作副本目录,检查 .svn
目录中的数据库和文件。如果工作副本非常大(包含大量文件和目录),或者磁盘 I/O 性能较差,cleanup
可能会比较慢。
可能的原因与优化:
- 工作副本过大:
- 考虑使用 SVN 的 稀疏检出 (Sparse Checkouts) 功能,只检出项目中你需要的部分。
- 定期清理不再需要的文件和目录(通过
svn delete
并提交)。
- 磁盘性能: 在 SSD (固态硬盘) 上运行通常比在传统 HDD (机械硬盘) 上快得多。
.svn/pristine
目录膨胀: 如果使用了较旧的 SVN 版本,或者项目历史悠久且包含大量二进制文件,原始副本可能占用很大空间。使用svn cleanup --vacuum-pristines
可以帮助清理,但这本身也可能是一个耗时操作。- 杀毒软件干扰: 某些杀毒软件可能会实时扫描
.svn
目录中的大量小文件和数据库访问,显著拖慢cleanup
速度。尝试临时禁用杀毒软件对工作副本目录的扫描(风险自负),或者将其配置为排除.svn
目录。 - 网络驱动器: 如果工作副本位于网络驱动器上,网络延迟和带宽限制会严重影响性能。尽量将工作副本放在本地磁盘。
- 外部项 (Externals): 如果工作副本包含许多外部项,并且没有使用
--include-externals
,cleanup
只处理主工作副本。如果使用了--include-externals
,则清理时间会相应增加,因为它需要处理所有外部工作副本。
5. 使用 svn cleanup
的最佳实践
- 优先尝试: 当遇到工作副本锁定或操作中断相关的错误时,
svn cleanup
应作为首选的修复尝试。 - 在问题目录下执行: 尽量在最接近问题的子目录下运行
cleanup
,而不是总是在根目录运行,这样可以节省时间。当然,如果不知道问题具体位置,或问题涉及多个子目录,则在根目录执行是必要的。 - 理解选项: 不要随意使用
--remove-unversioned
和--remove-ignored
选项,除非你确切知道其后果并需要清理这些文件。 - 谨慎中断: 尽量避免在 SVN 操作(尤其是
update
,commit
,switch
,merge
)进行过程中强制中断客户端。 - 保持客户端更新: 使用最新稳定版的 SVN 客户端,可以获得 bug 修复和性能改进。
- 定期维护: 对于非常大的或长期使用的项目,偶尔执行一次
svn cleanup --vacuum-pristines
可能有助于控制磁盘空间占用(尤其是在 SVN 1.8 之前)。 - 了解替代方案: 如果
cleanup
反复失败,要知道何时放弃并采取更彻底的方法,如重新 Checkout。 - 结合 GUI 工具: 对于不熟悉命令行的用户,TortoiseSVN 等 GUI 工具提供了友好的界面来执行
cleanup
,并且通常默认选择了最安全、最常用的选项。
6. 总结
svn cleanup
是 SVN 用户工具箱中不可或缺的一个命令。它扮演着工作副本“医生”的角色,专门处理由于操作中断、异常退出等原因导致的锁定和不一致状态。通过理解其解锁、完成中断操作、恢复一致性的核心作用,掌握命令行和 GUI 的用法,并了解常见问题的解决方案,开发者和团队可以更有效地维护其 SVN 工作副本的健康,确保版本控制工作流的顺畅进行。虽然现代开发中 Git 等分布式版本控制系统日益流行,但 SVN 仍在许多组织和项目中发挥着重要作用,因此熟练运用 svn cleanup
依然是一项有价值的技能。记住,谨慎使用其破坏性选项,并在遇到疑难问题时,有条不紊地进行故障排查,包括最终采用重新 Checkout 的可靠方案。