Perforce 声明文件在不同时是不同的

Perforce claims file is different when it's not

我的这个文件似乎进入了一种奇怪的状态。 Perforce 声称它已修改且未打开:

> p4 diff -se
data.xml

通常情况下,当一个文件被修改并且未打开时,我可以使用sync -f 来修复它。但是,出于某种原因,这个特定文件真的很顽固:

> p4 sync -f data.xml
//Depot/Stream/data.xml#19 - refreshing data.xml

> p4 diff -se
data.xml

sync -f 一样,clean 似乎有效,但它仍然声称已修改:

> p4 clean data.xml
//Depot/Stream/data.xml#19 - refreshing data.xml

> p4 diff -se
data.xml

毫不奇怪,当我尝试 reconcile -w:

时,同样的事情发生了
> p4 reconcile -w data.xml
//Depot/Stream/data.xml#19 - refreshing data.xml

> p4 diff -se
data.xml

如果我使用 reconcile(没有 -w),文件会打开,但 P4Merge 显示文件相同,即使没有忽略空格或行尾:

> p4 reconcile data.xml
//Depot/Stream/data.xml#19 - opened for edit

> p4 diff -se

> p4 diff -sa
data.xml

使用 revert 只是将其恢复到之前的状态:

> p4 revert data.xml
//Depot/Stream/data.xml#19 - was edit, reverted

> p4 diff -sa

> p4 diff -se
data.xml

什么给了?我之前不小心复制了这个文件而没有打开它进行编辑。这是否使它进入了不可逆转的状态,也许与 Windows 权限有关?

我尝试删除文件 (del data.xml) 并重新获取它,但是 Perforce 创建的新副本有同样的问题。

想到两种可能性:

  1. 服务器的文件校验和与其内容不匹配(这意味着差异将始终显示为不同)。您的管理员可以使用 p4 verify 命令进行检查。
  2. 文件中的行尾不一致你有share LineEnd选项,它本质上对每个进行隐式dos2unix行尾转换每当从本地磁盘读取文件时。如果 dos2unix 是空操作,文件将显示为相同;如果文件中有 \r,那么它们的删除将显示为差异。

在任何一种情况下,都可能通过创建一个校验和与您的工作区中的任何内容相匹配的修订来 "fix" 提交文件——但我建议让管理员检查 p4 verify 因为如果文件已损坏,则可能是更大问题(磁盘故障等)的征兆。

稍微详细说明一下@Samwise 的回答:

如果您的工作区配置了行尾配置“共享”,但某个文件在某个时候以 windows (CrLf) 行尾签入存储库,那么会发生这种情况:

  • 当您获取文件时,perforce 会准确地保存到您的工作区 has/tracks(一个文本文件,带有 windows 行结尾),因为“共享”没有规定 sync-time转换。
  • 如果您要保存文件,它会将行结尾转换为 unix 行结尾(实际上 运行“dos2unix”作为提交的一部分)。
  • 因此,当您运行“协调”(例如)时,它会将这些windows-line-ending 文件突出显示为“本地修改”并邀请您打开它们进行编辑并提交它们。

这种情况大概是在另一个用户将其工作区配置为“Unix”行结束模式时实际提交了一个Windows-style文件时出现的。因为配置“unix”根本没有规定任何转换,所以“Cr”字符被保存在服务器上。这可能是偶然的,也可能是故意的。

在这种情况下正确的做法似乎有些不清楚:

  • 您可以通过将行结束字符设置更改为“unix”而不是“共享”来“正确地”协调工作;但是,您之后可能会不小心检查新的 CrLf 文件(假设您使用 Windows 并且您的某些工具倾向于这样做),从而不小心让每个人的情况变得更糟 - 就像以前的用户所做的那样
  • 您真的可以将所有这些 CrLf 文件转换为 Lf(通过打开它们进行编辑并提交它们而不做任何更改,使用您的“共享”工作区设置)以防止将来出现此问题,但这将显示为虚假更改对于潜在的许多文件。 也可能是错误的做法 如果您的工具中的任何内容实际上取决于这些包含 Cr 字符的文件 - 例如,如果它们针对某些测试过程的输出进行校验和。

就我个人而言,我会暂时将我的工作区设置从“共享”更改为“unix”,仅用于协调操作,然后切换回“共享”以供日常使用用法。