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


117

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


p4 changes | head -1似乎比大多数这些解决方案都容易。
Sridhar Sarnobat,

Answers:


91

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

p4 changes -s submitted -m1

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

p4 changes -m1 @clientname

他们注意到一些陷阱:

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

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

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

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

p4 sync -n @changelist_number

为什么是“只有在您尚未从有关工作空间提交任何内容的情况下,这才起作用”?
gdw2 2013年

如果您提交更改,则“ p4更改-s提交-m1”将返回您的更改列表编号。例如,假设你同步到修改5,等待了几个小时,然后提交变更表10.上述变化命令将返回10
林恩

链接已失效,是本文吗?answers.perforce.com/articles/KB/3458/
user31389

请注意,可以使用#have代替@clientname,这使您不必查找客户端工作空间名称。
溜溜球

29

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

从命令行使用:

p4 changes -m1 @<clientname>

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

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

可以很容易地对其进行分析以提取变更列表编号。


我得到:请求太大(超过1500000);请参阅“ p4帮助maxresults”。
user674669

@ user674669:使用选项-m1仅返回最后(1)个更改列表
panako

这提供了上次提交的更改列表的信息,而不是上一次同步的更改列表的信息,而这正是操作员想要知道的。
安德烈亚斯(Andreas)'18

@marsh我认为它实际上是客户端工作区名称,如果未设置,则默认为计算机名称。参见此处:P4CLIENT
安德烈亚斯·哈弗堡

15

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

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基于JTGoldstone的“ 使用命令行中的P4G.py 使用命令行”演示文稿中的代码,柯达信息网络/ Ofoto,2005年4月15日。

#! /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

9

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

这是我用的:

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

同一客户需要2.1秒


客户名称是什么?我如何找到此信息?
沼泽

1
@marsh客户端(或工作区)名称是保存从服务器存储库到本地文件系统的映射的perforce对象的名称
gsf

2
支持此答案,因为它回答的是实际问题,而不是说“不要那样做”(这是有根据的,但不回答问题)。
sam hocevar '17

1
p4 changes -m1 @clientname无休止地运行... p4 cstat ...#have | grep change | awk '$3 > x { x = $3 };END { print x }'确实有效!谢谢!
simomo

@gsf-谢谢,只需在我的Linux机器上尝试一下,它就可以了!

9

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

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

8

您还可以使用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'

5

对于认真的版本(正在准备进行测试的版本),请明确指定所需的标签或变更列表编号,并与标签同步,并将其嵌入到构建工件中。

如果未提供变更列表(或标签),请使用p4 counter change来获取当前变更号并进行记录。但是您仍然需要使用该更改号同步所有内容。

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


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

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


Erickson-很好的建议,但我认为它所涵盖的情况与我提供的答案略有不同。当然,如果您可能只进行头部修订,并且服务器没有足够的忙,以至于某个人(可能在另一个项目中工作)不会在同步和调用p4计数器之间进行提交,则计数器将起作用。因此,我认为您的建议可能是在构建系统先执行先拉后构建的最佳建议。我的答案涵盖了同步可能会在时间上与构建分离的情况。两者都是有效的,具体取决于我认为的情况。
格雷格·惠特菲尔德

3

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

p4 counter change

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


2
请注意,这报告了最新的仓库变更列表的数量,其中包括未决(即尚未提交)的变更列表。因此,任何在其客户端中开始一些新工作的用户都会影响此数字。这将与同步到本地工作区的最后一个更改列表不同。
jasonmray 2014年

2

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

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

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


0

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.