在 Perforce 中确定同步到的最后一个变更列表

偶尔会出现的一个问题是,在 Perforce 中,确定最后一次同步到的变更列表的最佳方法是什么。这通常是诸如通过自动构建系统向修订信息中注入变更列表号之类的事情所需要的。

89283 次浏览

仅仅是为了回答这个问题,以便与 Jeff 的建议保持一致,即使用 Stackoverflow 作为保存技术片段的地方... ..。

从命令行使用:

p4 changes -m1 @<clientname>

只需要替换为客户机规范的名称即可,这将生成表单的输出:

Change 12345 on 2008/08/21 by joebloggs@mainline-client '....top line of description...'

它很容易解析以提取变更列表号。

对于一个严肃的构建(一个正在准备测试的构建) ,显式地指定所需的标签或变更列表编号 标签同步,,并将其嵌入到构建构件中。

如果没有给出变更列表(或标签) ,请使用 p4 counter change获取当前的变更号并记录下来。但是你仍然需要 使用那个更改号码同步所有内容。

我不认为您可以完全达到您想要的效果,因为通常情况下,整个工作区不会与特定的变更列表号同步。我们可以显式地将一些文件同步到旧版本,然后一个变更列表号就没有意义了。这就是为什么需要一个新的 sync来确保单个变更列表号准确地表示代码版本。


关于注释: 是的,我的回答是为准备构建版本的配置管理员提供的。我们的开发人员通常不会将其作为构建的一部分进行同步; 他们会在提交之前进行构建,以确保他们的更改不会破坏构建或测试。在这种情况下,我们不必费心去嵌入存储库标签。

在您的方法中,您假设您的整个工作区在您最后一次提交变更列表时已经同步到头部,并且变更列表包含了您所有打开的文件。在这些假设中很容易出错,很难发现,而且在损失时间方面代价高昂。另一方面,解决这个问题很容易,没有缺点。并且因为可以显式指定变更列表号,所以不管您需要什么样的修订,也不管代码库更改的速度有多快。

对于自动构建系统,我推荐相反的做法: 您应该首先使用以下方法从服务器获取最新的变更列表:

p4 changes -s submitted -m1

然后同步到那个变化,并记录在修订信息。原因如下。尽管 Perforce 建议采取以下措施用于确定工作区同步到的变更列表:

p4 changes -m1 @clientname

他们指出了一些陷阱:

  • 这只有在您没有从有问题的工作区提交任何东西的情况下才有效。
  • 也有可能客户端工作区没有同步到任何特定的变更列表。

还有一个问题他们没有提到:

  • 如果发生严格删除工作区中的文件的同步的最高变更列表,那么将报告次高的变更列表(除非它也严格删除了文件)。

如果你必须先同步然后再记录,Perforce 建议运行以下命令来确定你是否被上面的陷阱所困扰; 它应该表明没有同步或删除任何东西:

p4 sync -n @changelist_number

您可以尝试在“ p4 files”命令的输出中查找最大更改号。但是工作目录不应该包含后同步提交。这只是比

p4 changes -m1 "./...#have"

因为后者似乎在服务器上运行,并且可能由于“ MaxResults”限制而在大源树上失败。

$ p4 changes -m1 "./...#have"
Request too large (over 850000); see 'p4 help maxresults'.


$ p4 -G files "./...#have" | python c:/cygwin/usr/local/bin/p4lastchange.py
Files: 266948
2427657

其中 p4lastchange.py 基于柯达信息网络(Kodak Information Network/Ofoto) J.T.Goldstone 2005年4月15日的 从命令行使用 P4G.py演示文稿中的代码。

#! /usr/bin/env python
import sys, os, marshal


if os.name == "nt":
# Disable newline translation in Windows.  Other operating systems do not
# translate file contents.
import msvcrt
msvcrt.setmode( sys.stdin.fileno(), os.O_BINARY )


lastcl = 0
num = 0
try:
while 1:
dict = marshal.load(sys.stdin)
num = num + 1
for key in dict.keys():
# print "%s: %s" % (key,dict[key])
if key == "change":
cl = int(dict[key])
if cl > lastcl:
lastcl = cl
except EOFError:
pass
print "Files: %s" % num
print lastcl

到目前为止,我发现最好的方法是同步到您想要构建的任何变更列表,然后使用 change-m1//... # have to get The current local changelist (Amendment)。

P4 sync@CHANGELIST _ NUM p4 changes -m1 //...#have | awk '{print $2}'

给出变更列表号码,您可以在任何地方使用它。我目前正在寻找一种比 p4更简单的方法-m1//... # have。

您还可以使用 cstat 命令:

P4帮助 cstat

cstat -- Dump change/sync status for current client


p4 cstat [files...]


Lists changes that are needed, had or partially synced in the current
client. The output is returned in tagged format, similar to the fstat
command.


The fields that cstat displays are:


change   changelist number
status   'have', 'need' or 'partial'

整个仓库(不仅仅是你的工作空间/客户)

p4 counter change

完成任务,只是告诉最后一个变更列表。

我不确定你是否得到了你需要的答案,但是我有一个类似的问题。我们的目标是在日志中写入项目的特定版本。问题在于,当我们制作自己的 makefile 时,整个构建系统是由我们的组态管理控制的。这意味着,所有的解决方案,说“同步到某些事情,然后做某些事情”并不真正工作,我不想手动更改版本,无论何时我们提交(一个肯定的错误来源)。 解决方案(实际上在上面的一些答案中已经暗示了)是这样的: 在 makefile 中,我对 p4进行了更改-m1“ ./... # have” 其结果是 user@client‘ msg’在日期上更改 Change _ number 我只是简单地将消息创建到一个字符串中,这个字符串由日志记录器打印出来(更改编号是重要的元素,但是另一个元素对于快速判断某个版本是否包含更改也很有用,你知道这些更改是你自己做的,而不需要强制检查)。 希望这个能帮上忙。

p4 changes -m1 @clientname,这是“推荐”的方式做到这一点,为我的客户需要大约10分钟

我用的是这个:

p4 cstat ...#have | grep change | awk '$3 > x { x = $3 };END { print x }'

for the same client takes 2.1 seconds

If you are using P4V you can do this graphically:

  • 在 Dashboard 选项卡(View-> Dashboard)中选择一个文件夹,您将看到一个尚未更新该文件夹的变更列表列表。注意最低的数字(在最高的行中)。
  • Make sure that in the Workspace Tree you have selected the same folder as previously in the Dashboard. Then go to the History tab (View->History) and scroll down to the number noted previously. The number just below that number is the number of your current changelist.