用户文章转载:P4 Rmdir 会自动删除空目录?不,没那么简单

来源:游戏QA  作者:向华        发布时间:2021-12-24 09:50

你好,我是向华。

前原神项目 P4 Admin,持续集成开发者

8 年游戏测试开发工程师。

这是向华的第 8 篇原创内容。

 

 

最近在使用 P4 时,遇到一个挺诡异的问题,是关于 P4 Workspace 的配置项 Rmdir。
问题是这样的。
在 Windows 版 P4V 设置了 workspace 的属性 Rmdir,然后对一个目录执行 Mark For Delete 时,本来期望会清除整个目录下的文件连带目录本身,但结果目录下文件删掉了,空目录怎么也删不掉。(横屏观看下方视频更佳)
这有悖于 Rmdir 的描述 !!!
看看P4V上的Rmdir配置描述怎么说。
640 9
究竟是怎么回事呢?

 

展开调查
先从外部因素调查。
换一台电脑?
在另一台电脑上,去尝试 Mark For Delete,也会留下空目录。
换一个系统?
在 Mac 上,尝试 Mark For Delete,符合 rmdir 的规则,能够清除空目录。
难道是系统原因?
感觉也不应该,P4V发展这么多年,理论上不应该有这种不兼容的问题。
潜意识也让我排除掉了「P4V版本不对」的可能。
我又尝试用 P4 命令行来解决这个问题。
但结果同样是 Mac 上符合预期,Windows 上有问题。
这应该不是根本原因。
直觉告诉我,一款商业软件在系统层面的兼容性问题虽然可能存在,但不应该在这么明显的配置上出现问题。

 

寻找可能的原因
Rmdir 选项究竟是什么意义,难道是我理解不对,还是操作不对呢?
我陷入思考,并开始搜索。
无奈,所有的搜索结果中,只有官方的那篇文档具有有限的指导意义,就是这篇 (https://community.perforce.com/s/article/3416)
640 1 2
文档中有两点引起了我的注意:
一是,空目录的删除时机是 p4 delete 和 p4 sync #0。
640 2 2

二是,Windows Junctions 的概念。

640 3 2
第 1 条我已经尝试过了,p4 delete,p4 sync #0 按官方的说法是可以移除空目录的,但我这么做了,未能解决问题。
第 2 条中的 Junction 虽然没有用过,但又一次启发我想到了非 Windows 系统的表现。
没错,就是上文第 01 部分提到的,在 Mac 上 Rmdir 选项的效果是符合预期的。 

 

再次分析原因
难道真的是 Windows 版 P4V 不支持 Rmdir 选项了?
联想上述官方文档中提到的:
640 4 2
99 版以前 P4V 是需要手动删除空目录的。
哦?那就尝试下手动删除看看有啥效果。
Windows 上打开cmd,cd 到上级目录。
执行删除命令。
rd View
640 5 1

果然,被~阻~拦~了!

答案浮出水面。

有「另一个程序」占用了 View 目录,P4V 删除空目录的操作被 Windows 系统拦截了。

「另一个程序」是什么呢?

 

解决方案 

打开 Windows 的资源监视器,CPU-关联的句柄,搜索空目录的名字「Scripts\View」,发现有以下结果:

640 6 1

竟然有一个 cmd.exe,这时我注意到,之前为了在该目录执行 P4 命令,右键打开过 P4 Command Line,在执行 Mark For Delete 时没有关闭该 cmd 窗口。

640
难道是这个问题?
尝试把第一个 cmd.exe 右键结束进程。
然后再尝试执行删除命令。
rd View
640 7 1
执行成功,空目录被删。
在没有开 cmd.exe 的情况下,重新尝试了文章开头的 Mark For Delete 操作,发现 P4V 能够顺畅地清除空目录。

 

更进一步的发现
通过进一步的实验,有了更多的发现。
发现1:Mac 不受Command Line影响,没有cmd占用目录不让删除这一说。
在Mac上,右键一个目录打开command line。
紧接着对该目录执行 Mark For Delete,发现能够顺利删除。
发现2:手动在预删目录中创建空目录,对预删目录执行 Mark For Delete,发现空目录无法正常清除。
这一点能够理解,P4V最大程度地保护了用户主观上期望存在的空目录结构。
发现3:P4V 清除空目录的动作是一次性的。错过了,后面就只能手动清除。
解释一下,正如官方文档中所提,只有当 p4 delete和 p4 sync #0 时,会一次性触发清除空目录的动作。
任何阻止删除空目录的程序都会导致未来无法自动清除该空目录。
个人认为这一项 Perforce 官方可以改进。

这也是 Unity 在 PlayMode 下,P4V Mark For Delete一整个目录的文件时,如果有另一程序阻止了删除空目录的操作,会在本地残留无用的空目录。

麻烦就麻烦在,Unity 会为这些空目录生成对应的 meta 文件,其实这都是无用的垃圾文件。

 

总结一下

调查诡异问题,先从外部因素着手,能更快地排除各种无关因素。

在解决问题上,多实践才能够找到正确的方向。
本文问题只有Windows P4V 可能会出现,Mac 上的正常表现促使我解决问题,故而发出感慨:
Windows 用户的伤感,Mac 用户来拯救。