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

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

Determining the last changelist synced to in Perforce

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


对于自动构建系统,我建议相反:首先应使用以下命令从服务器获取最新的变更列表:

1
p4 changes -s submitted -m1

然后同步到该更改并将其记录在修订信息中。原因如下。尽管Perforce建议使用以下方法来确定将工作空间同步到的更改列表:

1
p4 changes -m1 @clientname

请注意一些注意事项:

  • 仅当您尚未从相关工作空间提交任何内容时,此方法才有效。
  • 客户端工作空间也可能未同步到任何特定的更改列表。

还有一个他们没有提到的附加陷阱:

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

如果您必须先同步并稍后进行记录,Perforce建议运行以下命令来确定您是否被上述陷阱所困扰;它应该表明没有同步或删除任何内容:

1
p4 sync -n @changelist_number

请自己回答这个问题,以符合Jeff的建议,即使用Stackoverflow作为保留技术摘要的地方....

在命令行中使用:

1
p4 changes -m1 @<clientname>

,只需将其替换为客户规范的名称即可。这将产生以下形式的输出:

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

可以很容易地解析出其中的变更列表编号。


您可以尝试在" p4文件"命令的输出中找到最大更改数。但是,工作目录不应包含同步后的提交。比

好一点

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

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

1
2
3
4
5
6
$ 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基于2005年4月15日柯达信息网/ Ofoto的J.T. Goldstone的"使用P4G.py从命令行进行演示"中的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#! /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

如果您使用的是P4V,则可以通过图形方式进行:

  • 在"仪表板"选项卡("视图"->"仪表板")中,选择一个文件夹,您将看到该文件夹??尚未更新的变更列表列表。注意最低的数字(在最高的行中)。
  • 确保在"工作区树"中选择了与以前在"仪表板"中相同的文件夹。然后转到"历史记录"选项卡("视图"->"历史记录")并向下滚动到前面提到的数字。该数字正下方的数字是您当前更改列表的数字。

p4 changes -m1 @clientname这是为客户执行此操作的"推荐"方法,大约需要10分钟

这就是我用的:

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

同一客户需要2.1秒


您还可以使用cstat命令:

p4帮助cstat

1
2
3
4
5
6
7
8
9
10
11
12
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获取当前更改编号并进行记录。但是您仍然需要使用该更改号来同步所有内容。

我认为您无法完全实现所需的功能,因为一般而言,整个工作区不会同步到特定的变更列表编号。可以将某些文件显式同步到较旧的版本,然后只有一个变更列表编号是没有意义的。这就是为什么需要新的sync来确保单个变更列表编号准确表示代码版本的原因。

关于评论:是的,我的答案供配置管理器使用,以准备进行质量检查。我们的开发人员通常不会在构建过程中进行同步;他们会在提交之前进行构建-这样他们可以确保所做的更改不会破坏构建或测试。在这种情况下,我们不必费心嵌入存储库标签。

使用您的方法,您假设整个工作区在上次提交更改列表时已同步到头部,并且该更改列表包含了所有打开的文件。在这些假设中容易被误解,很难被??发现,并且在浪费的时间方面损失惨重。另一方面,解决问题很容易,没有缺点。而且由于可以明确指定变更列表编号,所以无论您需要哪个修订版本或代码库的更改速度都没有关系。


对于整个软件仓库(不仅仅是您的工作空间/客户端)

1
p4 counter change

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


到目前为止,我发现最好的方法是将您的同步到要构建的任何更改列表,然后使用更改-m1 //...#必须获取当前的本地更改列表(修订版)。

p4同步@CHANGELIST_NUM
p4更改-m1 //...#have | awk'{print $ 2}'

为您提供可以在任何地方使用的变更列表编号。我目前正在寻找一种比p4更改更简单的方法-m1 //...# have。


我不确定您是否能找到所需的答案,但我遇到了类似的问题。目的是在记录器中编写项目的特定版本。问题在于,当我们创建自己的makefile时,整个构建系统由我们的配置管理控制。这意味着所有说"同步到某物然后做某事"的解决方案都无法真正起作用,并且我不想在每次提交时手动更改版本(确定错误的可靠来源)。
解决方案(实际上是上述某些答案中所暗示的)是:
在我们的makefile中,我执行p4更改-m1" ./...#have"
结果是user @ client'msg'在日期上更改change_number
我只是将消息创建为一个字符串,由记录器打印出来(更改号是重要的元素,但另一个元素对于快速确定某个版本是否包含您知道自己进行的更改也很有用,而无需强制检查)。
希望这会有所帮助。


推荐阅读