Cm find 示例
“cm find”
在每个版本控制系统中,我们经常需要获取有关使用情况、正在更改哪些文件或只是搜索特定更改或特定分支的信息。
实现这一点的最佳方法是使用查询。因此,当我们创建 Plastic SCM 时,我们添加了名为 cm find 的非常强大的查询系统命令,该命令允许您获取涉及变更集、分支、标签、合并和代码审查的特定信息。
find 命令还可用于自定义 GUI 中的视图。
本文通过示例介绍了一些可以使用 cm find 命令处理的场景。这些只是您在 Plastic SCM 安装中可以执行的操作的一小部分。每个示例都包含一个问题、一个分步解决方案以及预期输出(以帮助您了解返回的信息类型)。
注意
您可以使用单数和复数来查找对象。例如,cm find branch 和 cm find branches 都可以使用。
注意
从命令行中使用比较运算符(>、<、>=、<=)运行查询时,请注意,shell 将这些运算符视为 IO 重定向。
因此,需要用引号将查询引起来:
cm find branches "where owner='pablo' and changesets >= '2013/03/01'"
关于 Powershell 的注意事项
默认情况下,Powershell 控制台将转义 " " 双引号(但不是简单的 " "),因此我们必须添加一对额外的引号来指定我们希望将它们放置在我们的命令中:
cm find replicationlog where branch = "'/semanticmain'" --format="{date}" --nototal | select -Last 1
或者,也可以将全部查询引起来:
cm find replicationlog "where branch = '/semanticmain'" --format="{date}" --nototal | select -Last 1
分支
我可以查找在特定日期之前通过测试的所有分支吗?
我们可以检索用户在某个时间跨度内创建的分支,然后我们可以按特定属性进行筛选。
查找所有分支
我们开始检索所有可用的分支:
cm find branches
301186 09/01/2013 8:18:51 /main/Fix-4.1/SCM12154 borja codice T
378467 12/02/2013 12:43:24 /main/scm12336 violeta codice T
379892 12/02/2013 17:52:14 /main/scm12336/scm12013 pablo codice T
407817 22/04/2013 16:32:31 /main/scm12636/scm12666 pablo codice T
426648 29/05/2013 17:36:04 /main/scm12313 pablo codice T
Total: 5
寻找我们的分支
我们只想要我们的分支,所以我们按用户进行筛选:
cm find branches "where owner='pablo'"
379892 12/02/2013 17:52:14 /main/scm12336/scm12013 pablo codice T
407817 22/04/2013 16:32:31 /main/scm12636/scm12666 pablo codice T
426648 29/05/2013 17:36:04 /main/scm12313 pablo codice T
Total: 3
查找按日期筛选的分支
按用户筛选后,我们现在只需要与此 sprint 相关的分支,因此我们正在寻找在特定日期之后创建的分支:
cm find branches "where owner='pablo' and date >= '2013/03/01'"
407817 22/04/2013 16:32:31 /main/scm12636/scm12666 pablo codice T
426648 29/05/2013 17:36:04 /main/scm12313 pablo codice T
Total: 2
您可以使用格式化的输出:
cm find branches "where owner='pablo' and date >= '2013/03/01'" --format="{name,-30} {date}"
/main/scm12636/scm12666 22/04/2013 16:32:31
/main/scm12313 29/05/2013 17:36:04
Total: 2
按属性值查找分支
最后,我们寻找一个特定的属性。根据我们的内部功能生命周期,每个分支在集成到 main 分支之前必须通过测试。
当分支通过测试时,“test”属性将设置为“passed”,因此,我们按属性名称和属性值进行筛选:
cm find branches "where owner='pablo' and date >= '2012/01/01' and attribute ='test' and attrvalue = 'passed'"
426648 29/05/2013 17:36:04 /main/scm12313 pablo codice T
Total: 1
筛选和输出选项
下表显示了当前可用于 cm find branch 命令的不同筛选选项:
筛选选项 (where...) |
attribute |
attrvalue |
changesets |
comment |
date |
guid |
id |
item |
name |
owner |
parent |
repllogid |
replsrcdate |
replsrcid |
replsrcrepository |
replsrcserver |
了解如何使用常量按日期进行筛选。
以下另一个表显示了当前可用于 cm find branch 命令的不同输出选项:
输出选项 (--format...) |
comment |
date |
id |
name |
owner |
parent |
变更集
显示变更集的注释
我可以找到我在某些签入中写的注释吗?我确定它一定在这个分支的某个地方,并且与“solution”有关。
我们可以找到很多关于变更集的信息,注释只是其中之一。如需快速获取信息,我们可以使用 cm log 并执行我们自己的筛选(使用 shell 命令)或让 cm find 代劳。
在此示例中,我们将获取属于一个分支的所有变更集的日期和注释:
cm find changeset "where branch = 'main/scm12800'" --format="{date} - {comment}"
27/05/2013 13:25:53 - Updated output.
27/05/2013 13:26:45 - Changed SccPlugin with the new change.
27/05/2013 13:35:15 - Added solution.
Total: 3
所以这里就是所有的变更集,现在我们要寻找“solution”这个词,在这里我们很容易就可以看到它,但是当我们有几百个变更集时,寻找过程将变得缓慢而无聊。为了按特定字词进行筛选,我们使用 SQL 语法 LIKE 和 % 执行近似搜索,因为我们不需要寻找完整的注释:
cm find changeset "where branch = 'main/scm12800' and comment like '%solution%'" --format="{date} - {comment}"
27/05/2013 13:35:15 - Added solution.
Total: 1
查找复制的变更集
我可以找到我在特定日期复制的变更集吗?
我们还可以使用以下命令按复制日期查询变更集(稍后我们将看到如何获取上次复制日期):
cm find changeset "where branch='semanticmain' and replsrcdate > '2013/06/17'" --nototal
427425 16794 /semanticmain 07/06/2013 11:06:38 violeta codice IntegrateMiryamtask 12838
427435 16804 /semanticmain 07/06/2013 19:25:31 violeta codice Changeassemblyversion (0.9.28.0).
427436 16805 /semanticmain 07/06/2013 19:54:35 lrodriguez codice Updatemapall
“returnparent”字段
该 returnparent 字段有什么用途?
returnparent 允许我们获取特定变更集或修订的父级。这样,如果我们想知道在此变更集之前发生了什么,我们可以进行简单的查询:
cm find changeset "where changesetid = 16583 and returnparent = 'true'" --nototal
423630 16582 /main/scm12800 27/05/2013 13:25:53 roberto codice Updated output.
筛选和输出选项
下表显示了当前可用于 cm find changeset 命令的不同筛选选项:
筛选选项 (where...) |
attribute |
attrvalue |
branch |
changesetid |
comment |
date |
guid |
id |
owner |
parent |
repllogid |
replsrcdate |
replsrcid |
replsrcrepository |
replsrcserver |
returnparent |
了解如何使用常量按日期进行筛选。
以下另一个表显示了当前可用于 cm find changeset 命令的不同输出选项:
输出选项 (--format...) |
branch |
changesetid |
comment |
date |
guid |
id |
owner |
parent |
复制日志
我可以找出特定分支的最后一次复制是什么时候吗?
对于给定的分支,我们可以按时间顺序获取从相关时间开始以来的所有复制操作。
cm find replicationlog "where branch = '/semanticmain'" --nototal
424089 03/06/2013 12:16:42 codice@diana:9095 F pablo
426718 17/06/2013 18:46:38 codice@diana:9095 F pablo
427606 17/06/2013 18:50:47 codice@diana:9095 F pablo
如果我们只想要最后一个日期,我们可以使用 Powershell 或 Bash 按日期筛选搜索,并选择最后一行。
Powershell:
cm find replicationlog "where branch = '/semanticmain'" --format="{date}" --nototal | select -Last 1
Bash:
cm find replicationlog "where branch = '/semanticmain'" --format="{date}" --nototal | tail -n 1
结果:
17/06/2013 18:50:47
筛选和输出选项
下表显示了当前可用于 cm find replicationlog 命令的不同筛选选项:
筛选选项 (where...) |
branch |
date |
id |
owner |
package |
repositoryname |
server |
了解如何使用常量按日期进行筛选。
以下另一个表显示了当前可用于 cm find replicationlog 命令的不同输出选项:
输出选项 (--format...) |
date |
id |
owner |
package |
server |
标签
在特定分支中查找标签
我可以找到特定分支中的所有标签吗?
我们可以获取所有的标签:
cm find label --format="{name} {owner} {branch} {branchid}" --nototal on repository 'codice'
BL234 lrodriguez /main 3
BL235 lrodriguez /main 3
BL236 lrodriguez /main/task001 4
BL237 lrodriguez /main 3
BL238 lrodriguez /main/task002 5
BL239 lrodriguez /main 3
我们可以获取我们在某个分支中创建的所有标签:
cm find label "where branch = '/main'" --format="{name} {owner}" --nototal on repository 'codice'
BL234 lrodriguez
BL235 lrodriguez
BL237 lrodriguez
BL239 lrodriguez
查找具有特定标签的分支
我可以找到包含特定标签的分支吗?
在 codice 中,我们保留了一个用于开发的 main 分支和一个用于支持当前和旧版本的“Fix”分支,因此我们可能想找到哪个分支包含特定版本:
cm find label "where name = 'BL237' on repository 'codice'" --nototal
191871 17/11/2011 16:38:06 BL237 10503 /main lrodriguez codice
我们可以看到,标签 BL237 来自 main 分支。
查找 2 个标签之间的变更集
我可以找到在 2 个标签之间创建的变更集吗?
我们可以获取标签日期,然后查询该时间跨度内在该分支中创建的变更集。获取两个(或更多)标签的信息非常简单:
cm find label "where name = 'BL237' or name='BL235' on repository 'codice'" --nototal
191869 11/11/2011 14:20:02 BL235 1750 /main lrodriguez codice
191871 17/11/2011 16:38:06 BL237 10503 /main lrodriguez codice
筛选和输出选项
下表显示了当前可用于 cm find label 命令的不同筛选选项:
筛选选项 (where...) |
attribute |
attrvalue |
branch |
branchid |
changeset |
comment |
date |
guid |
id |
name |
owner |
repllogid |
replsrcdate |
replsrcid |
replsrcrepository |
replsrcserver |
了解如何使用常量按日期进行筛选。
以下另一个表显示了当前可用于 cm find label 命令的不同输出选项:
输出选项 (--format...) |
branch |
branchid |
changeset |
comment |
date |
id |
name |
owner |
属性
获取所有属性
我可以获得此分支的所有属性吗?
这些属性可以无差别应用于分支、变更集和标签。我们首选需要对象 ID。为了获取 ID,我们可以在查询分支时指定 ID:
cm find branch "where name = 'main'" --format="{id}" --nototal
3
一旦我们有了 ID,我们就可以使用以下命令获取属性列表:
cm find attributes "where srcobj = 3" --nototal
objid:3@repid:2@repserver:localhost:8087 -- status --> PASSED
在本例中,属性名称是“status”,属性值是“Passed”。
我们可以使用一些 Powershell 脚本来组合这两条命令:
cm find branch "where name = 'main'" --format="{id}" --nototal |Foreach-Object { cm find attributes where srcobj= $_ --nototal}
或使用 Bash 脚本:
for branch_id in 'cm find branch "where name = 'main'" --format="{id}" --nototal' ;do cm find attributes "where srcobj=$branch_id" --nototal; done
输出将与之前相同:
objid:3@repid:2@repserver:localhost:8087 -- status --> PASSED
通过运行以下查询也可以获得相同的输出:
cm find attributes "where srcobj='br:/main'" --nototal
获取具有特定属性的所有对象
我可以获取上个月应用了属性 foo 和值 bar 的所有对象吗?
假设我们为一些对象设置了一个特定的属性(在我们的示例中是测试的“status”)。无论包含属性的对象是什么,我们都可以查询这些属性。
cm find attributes "where type = 'status' and value='PASSED' and date > 'this month'"
objid:253012@repid:2@repserver:localhost:8087 -- status --> PASSED
objid:253013@repid:2@repserver:localhost:8087 -- status --> PASSED
objid:253014@repid:2@repserver:localhost:8087 -- status --> PASSED
objid:268518@repid:2@repserver:localhost:8087 -- status --> PASSED
筛选和输出选项
下表显示了当前可用于 cm find attributes 命令的不同筛选选项:
筛选选项 (where...) |
comment |
date |
guid |
id |
owner |
srcobj |
type |
value |
了解如何使用常量按日期进行筛选。
以下另一个表显示了当前可用于 cm find attributes 命令的不同输出选项:
输出选项 (--format...) |
comment |
date |
id |
owner |
type |
value |
修订
在变更集中更改的文件
我可以在变更集中找到哪些文件已更改吗?
根据在前一个示例中检索到的特定变更集,我们现在可能想进一步了解包含更改的文件,为此我们可以使用 find revision。
我们指定自定义格式,因为我们只需要文件和文件夹路径:
cm find revisions "where changeset=16716" --format="{path}"
d:\linked_replicated\
d:\linked_replicated\01nerva
d:\linked_replicated\01nerva\src
d:\linked_replicated\01nerva\src\client
d:\linked_replicated\01nerva\src\client\plastic
d:\linked_replicated\01nerva\src\client\plastic\libplasticTranslations.es.resx
d:\linked_replicated\01nerva\src\client\plastic\libplasticTranslations.resx
d:\linked_replicated\01nerva\src\client\plastic\ActionMenuManager.cs
Total: 8
我们还可以使用一些命令行帮助(Linux 上的 grep 和 Windows Powershell 上的 where)按文件夹进行筛选:
Powershell:
cm find revisions "where changeset=16716" --format="{path}" --nototal | where {$_ -match "client\\"}
Bash:
bcm find revisions "where changeset=15430" --format="{path}" --nototal | grep client\/
然后,输出将如下所示:
d:\linked_replicated\01nerva\src\client\plastic
d:\linked_replicated\01nerva\src\client\plastic\libplasticTranslations.es.resx
d:\linked_replicated\01nerva\src\client\plastic\libplasticTranslations.resx
d:\linked_replicated\01nerva\src\client\plastic\ActionMenuManager.cs
在分支内更改的文件夹
我能否知道文件夹 foo 在经历特定时间后是否在分支内发生了更改?
我们还可以获取分支的修订信息,在其中搜索分支的所有更改。我们可以先获取一个分支和一个时间跨度的所有已更改项:
cm find revisions "where branch = 'main/Fix-4.1/scm12814' and date<='2013/05/30' and date > '2013/05/28'" --format="{date} - {path}"
稍后我们可以使用我们最喜欢的 shell 工具(在我们的示例中为 Powershell)来筛选该信息。
cm find revisions "where branch = 'main/Fix-4.1/scm12814' and date<='2013/05/30' and date > '2013/05/28'" --format="{date} - {path}" | where {$_ -match "view\\"}
如果您更喜欢 Bash,代码行如下:
cm find revisions "where branch = 'main/Fix-4.1/scm12814' and date<='2013/05/30' and date > '2013/05/28'" --format="{date} - {path}" | grep view\/
期望的输出如下所示:
28/05/2013 12:35:18 - d:\linked_replicated\01nerva\src\client\plastic\view\releasediagram
28/05/2013 12:35:18 - d:\linked_replicated\01nerva\src\client\plastic\view\releasediagram\drawingStyles
28/05/2013 12:35:18 - d:\linked_replicated\01nerva\src\client\plastic\view\releasediagram\drawingStyles\BaseDrawingStyle.cs
筛选和输出选项
下表显示了当前可用于 cm find revisions 命令的不同筛选选项:
筛选选项 (where...) |
archived |
attribute |
attrvalue |
branch |
changeset |
date |
guid |
id |
item |
itemid |
label |
marker |
owner |
parent |
repllogid |
replsrcdate |
replsrcid |
replsrcrepository |
replsrcserver |
returnparent |
size |
type |
workspacecheckoutid |
了解如何使用常量按日期进行筛选。
以下另一个表显示了当前可用于 cm find revisions 命令的不同输出选项:
输出选项 (--format...) |
branch |
changeset |
date |
id |
item |
itemid |
owner |
parent |
size |
type |
合并
在哪里集成了分支
我可以知道这个分支集成到哪里了吗?
合并呢?可以跟踪在特定分支或变更集之间完成的合并。
如果我们想知道一个分支集成在了什么地方,可以输入以下命令:
cm find merge "where srcbranch ='main/Fix-4.1/SCM11769'"
br:/main/Fix-4.1/SCM11769@55613 -->br:/main/Fix-4.1/Release-4.1.10.447@55808
Total: 1
在特定版本上集成的分支
我可以找出在 4.1.10.447 版中集成了哪些分支吗?
如果我们想知道具体的分支中集成了哪些分支,所需的命令如下:
$ cm find merge "where dstbranch ='main/Fix-4.1/Release-4.1.10.447'"
br:/main/Fix-4.1/SCM12835@55568 -->br:/main/Fix-4.1/Release-4.1.10.447@55801
br:/main/Fix-4.1/scm11898@55647 -->br:/main/Fix-4.1/Release-4.1.10.447@55802
br:/main/Fix-4.1/scm12839@55678 -->br:/main/Fix-4.1/Release-4.1.10.447@55803
br:/main/Fix-4.1/SCM11769@55613 -->br:/main/Fix-4.1/Release-4.1.10.447@55808
br:/main/Fix-4.1/SCM12860@55735 -->br:/main/Fix-4.1/Release-4.1.10.447@55809
Total: 5
先前的命令也可以使用我们的格式标志通过仅返回分支名称来自定义输出,例如,第二个命令将因此变成如下所示:
$ cm find merge "where dstbranch ='main/Fix-4.1/Release-4.1.10.447'" --format="{srcbranch}" --nototal
br:/main/Fix-4.1/SCM12835
br:/main/Fix-4.1/scm11898
br:/main/Fix-4.1/scm12839
br:/main/scm12419
br:/main/SCM4052
br:/main/Fix-4.1/SCM11769
br:/main/Fix-4.1/SCM12860
或:
cm find merges "where dstbranch='br:/main/ReleaseBL274'" --format="{srcbranch}@{srcchangeset} --> {dstbranch}@{dstchangeset}({type})" --nototal
br:/main/scm11148@43953 --> br:/main/ReleaseBL274@44094 (merge)
br:/main/scm11181@43969 --> br:/main/ReleaseBL274@44096 (merge)
br:/main/Fix-4.0/SCM11101@44010 --> br:/main/ReleaseBL274@44030 (merge)
br:/main/scm11135@43980 --> br:/main/ReleaseBL274@44031 (merge)
br:/main/ReleaseBL272@43914 --> br:/main/ReleaseBL274@44032 (cherrypick)
br:/main/ReleaseBL268@43663 --> br:/main/ReleaseBL274@44033 (cherrypick)
br:/main/scm10957@43952 --> br:/main/ReleaseBL274@44093 (merge)
br:/main/SCM11195@43981 --> br:/main/ReleaseBL274@44095 (merge)
br:/main/SCM10924@43942 --> br:/main/ReleaseBL274@44033 (merge)
请记住,find merge 返回所有类型的合并:常规合并、挑拣合并和减法合并。
因此,您可以向给定的分支进行间隔合并:
cm find merges "where dstbranch='br:/main/Fix-4.1/ReleaseBL285' and type='intervalcherrypick'" --format="({basebranch}@{basechangeset}, {srcbranch}@{srcchangeset}] --> {dstbranch}@{dstchangeset}" --nototal
(br:/main@44448, br:/main/scm11318@44461] --> br:/main/Fix-4.1/ReleaseBL285@44463
未集成的分支
我可以知道在这个 sprint 中创建的哪些分支没有集成吗?
我们可以通过两个查询(find branches、find merge)和一些 Powershell 破解手段来回答这个问题。将以下代码放在 PS1 文件中并从 Powershell 控制台运行:
$allBranches = cm find branches "where date >= '2013/06/20'" --format="{name}" --nototal;
$allMerged = cm find merge "where date >= '2013/06/20'" --format="{srcbranch}" --nototal;
for($i = 0; $i -le $allBranches.length -1; $i++) {$allBranches[$i] = 'br:' + $allBranches[$i]}
$allBranches| ?{$allMerged -notcontains $_}
下面是一个示例输出:
br:/main/scm12619
br:/main/Fix-4.1/scm12916
br:/main/Fix-4.1/scm12899/scm12947
br:/main/Fix-4.1/scm11180
br:/main/Fix-4.1/scm8782
br:/main/Fix-4.1/scm12944
br:/semanticmain/SCM12759/scm12948
此代码执行以下操作:
- 查找这个 sprint 中的所有分支。
- 查找这个 sprint 中的所有合并,并仅返回源分支。
- 更改 $allbranches 输出的格式,使两个列表具有相同的格式。
- 检查“merges”列表是否包含来自 allBranches 列表的分支。如果不包含,则没有集成该分支。
Bash shell 中的等效代码如下:
$ allBranches='cm find branches "where date >= '2013/06/20'" --format="{name}" --nototal'
$ allMerged='cm find merge "where date >= '2013/06/20'" --format="{srcbranch}" --nototal'
$ for branch in $allBranches; do [ ! 'echo $allMerged | grep 'br:$branch'' ] && print "br:$branch"; done
就其本身而言,这段代码会执行以下操作:
- 查找属于这个 sprint 的每个分支。
- 查找属于这个 sprint 的每个合并,仅返回它们的源分支。
- 打印这个 sprint 中没有位于已合并分支列表中的所有分支。
未完全集成的分支
我可以知道哪些分支没有完全集成吗?
我们正在寻找这种场景:
我们需要的分支符合以下条件:已经集成到另一个分支中(所以我们必须放弃合并到同一个分支中),但具有待集成的变更集(图片上的橙色变更集),没有问题,我们可以通过一个查询来完成,然后使用一些 Powershell 代码进行一些后期处理:
$allMergedNonFiltered = cm find merge "where date >= '2013/06/01'" --format="{srcbranch} {dstbranch} {srcchangeset}" --nototal;
$allMerged = $allMergedNonFiltered | ForEach-Object {$res = $_.Split(" "); if($res[0] -ne $res[1]) {$res[0] + " " + $res[2]} };
$semiMerged = $allMerged | ForEach-Object {$_.Split(" ")[0] };
$allBranches = cm find branches where "date >= '2013/06/01'" --format="{name} {changeset}" --nototal;
for($i = 0; $i -le $allBranches.length -1; $i++) {$allBranches[$i] = 'br:' + $allBranches[$i]}
$allBranches| ?{$allMerged -notcontains $_ -and $semiMerged -contains $_.Split(" ")[0]}
下面是一个示例输出:
br:/main/Fix-4.1/scm12861 56049
br:/main/Fix-4.1/SCM12817 56300
br:/main/Fix-4.1/scm12899 56270
此代码执行以下操作:
- 获取所有合并以及在特定日期后完成的源变更集。
- 筛选那些具有相同源和目标的合并。
- 获取仅包含合并的列表,丢弃已完成的合并。
- 更改 find branches 输出的格式,使其与 find merge 格式匹配。
- 比较并筛选那些在该时间间隔内已合并但具有待合并变更集的分支。
如果使用的是 Bash,替代方案如下:
$ cm find merge "where date >= '2013/06/01'" --format="{srcbranch}#{dstbranch}#{srcchangeset}" --nototal |awk -F "#" '{if($1 != $2) print $1 "#" $3}' | tee allMerges | cut -d'#' -f1 | sort -u > mergedBranches
$ for branch in 'cm find branches where "date >= '2013/06/01'" --format="br:{name}#{changeset}" --nototal;'; do [ ! "'grep $branch allMerges'" ] && [ "'echo $branch | grep -f mergedBranches'" ] && echo $branch; done
$ rm allMerges mergedBranches
我们执行的操作如下:
- 将特定日期之后执行的所有合并写入文件(指示源变更集);同时,将所有源合并分支写入另一个文件。
- 按分支名称和变更集迭代所有现有分支,只打印那些没有出现在第一个文件中(合并源分支和变更集)但出现在第二个文件中的分支(意味着具有待合并的变更集)。
- 最后,删除临时文件。
在此版本上集成的分支
我可以知道在此版本中(直接或间接)集成了哪些分支吗?
我们正在寻找这种场景:
我们想知道在 1.0 版中直接或间接集成了哪些分支。和以前一样,我们只需要对服务器进行一次查询,并使用更多的一些 powershell 来筛选数据。在这个特定的示例中,我们希望获取已集成到 /main 中的所有分支。
function ListAll($list, $visited, $targetBranch, $depth)
{
$visited += $targetBranch;
$list | ForEach-Object {
$res = $_.Split(" ");
if(($res[1] -eq $targetBranch) -and ($visited -notcontains $res[0]))
{
Write-Host $depth $res[0];
$visited += $res[0];
$temp_visited = ListAll $list $visited $res[0] ($depth + "-");
$temp_visited | ForEach-Object{
if($visited -notcontains $_)
{
$visited += $_;
}
}
}
}
return $visited;
}
$targetBranch = "br:/main";
$allMergedNonFiltered = cm find merge "where date >= '2013/01/01'" --format="{srcbranch} {dstbranch}" --nototal;
$allMerged = $allMergedNonFiltered | ForEach-Object {$res =$_.Split(" "); if($res[0] -ne $res[1]) {$res[0] + " " + $res[1]} }
$visited = @();
$targetBranch
ListAll $allMerged $visited $targetBranch "-" | Out-Null;
以下是一个示例输出,我们可以看到分支 12299 间接集成到了 4.3.39.406 版中
br:/main
br:/main/Release-4.2.29.406
br:/main/SCM12356
br:/main/scm12238
br:/main/Release-4.2.28.387/SCM12169/scm12230
br:/main/SCM12243/scm12280/scm12277/scm12293
br:/main/scm12238/scm12299
该脚本的简要说明:
- 我们像以前一样获取列表并删除重复项。
- 我们使用目标分支、一个空的 visited 列表和一个将帮助我们显示深度的标记来调用 ListAll 函数。此函数的输出通过管道传递给 null,因为我们不会在我们的代码中使用这个值,否则它会显示。
- 在 ListAll 函数中,我们尝试查找目标与目标窗口匹配的合并。
- 如果匹配,我们会将相应的项添加到我们的 visited 列表中,然后我们递归调用 ListAll,这次包含我们的合并源。
- 递归函数返回后,我们根据函数的返回值更新我们的 visited 列表。
在 Bash 下可以使用以下脚本实现相同效果:
cm find merge "where date >= '2013/01/01'" --format="{srcbranch}#{dstbranch}" --nototal | awk -F "#" '{if($1 != $2) print $1 "#" $2}' > list
touch old_targets
touch next_targets
echo "br:/main" | tee targets
depth=">"
while [ -s targets ]; do
for merge in 'grep -f targets list'; do
src_branch=${merge%#*}
was_already_target="'grep ${src_branch} old_targets 2>/dev/null'"
already_on_next_targets="'grep ${src_branch} next_targets 2>/dev/null'"
if [ ! "$was_already_target" ] && [ ! "$already_on_next_targets" ]; then
echo ${src_branch} >> next_targets
echo ${depth}${src_branch}
fi
done
depth="-${depth}"
cat targets >> old_targets
[ -s next_targets ] && mv next_targets targets || rm -f targets
done
rm -f list old_targets
这段脚本的简要说明:
- 我们获取合并列表,删除重复条目,然后将其存储到文件中。
- 我们准备两个辅助文件:
- old_targets,这将保存我们找到的每个目标分支
- targets,这将包含我们正在寻找来源的目标分支
- 我们现在继续查看目标分支是否存在于列表文件中作为目标。如果是这样,我们将存储下一轮的合并源分支(如果之前没有受到影响)。此外,我们会将其打印在屏幕上。
- 我们增加深度级别并切换目标列表:新的目标列表成为当前的目标列表,当前列表添加到“已使用”列表中。
- 最后,只留下清理操作以使环境保持原样。
筛选和输出选项
下表显示了当前可用于 cm find merge 命令的不同筛选选项:
筛选选项 (where...) |
date |
dstbranch |
dstchangeset |
guid |
id |
owner |
srcbranch |
srcchangeset |
type |
了解如何使用常量按日期进行筛选。
以下另一个表显示了当前可用于 cm find merge 命令的不同输出选项:
输出选项 (--format...) |
date |
dstbranch |
dstchangeset |
id |
owner |
srcbranch |
srcchangeset |
type |
代码审查
我能否获取已分配给我且尚未完成的审查?
集成的代码审查功能允许我们获取有关审查状态的信息。在此示例中,我们开始获取我的审查(也就是字面上分配给“我”的审查,其中“我”是指当前用户)。我们也可以像以前一样输入用户名。
cm find reviews "where assignee = 'me'"
399982 08/03/2013 10:43:30 danipen Status1 pablo "scm12563" Branch id:399570
419067 20/05/2013 9:59:49 asalim Status0 pablo "scm12411" Branch id:416824
8424078 29/05/2013 14:50:35 borja Status1 pablo "Review scm12816" Branch id:424073
425830 05/06/2013 17:04:37 jesusmg Status0 pablo "Review scm11179" Branch id:413120
426717 14/06/2013 14:01:14 roberto Status1 pablo "Code review 1" Branch id:426648
Total: 5
随后,我们可以将结果范围限定为具有特定状态(1 = 已批准)的审查:
cm find reviews "where assignee = 'me' and status = 1"
399982 08/03/2013 10:43:30 danipen Status1 pablo "scm12563" Branch id:399570
8424078 29/05/2013 14:50:35 borja Status1 pablo "Review scm12816" Branch id:424073
426717 14/06/2013 14:01:14 roberto Status1 pablo "Code review 1" Branch id:426648
Total: 3
最后,我们获取在特定的时间范围内完成的审查:
cm find "review where assignee = 'me' and date > '2013/05/01' and date < '2013/06/29'"
419067 20/05/2013 9:59:49 asalim Status0 pablo "scm12411" Branch id:416824
8424078 29/05/2013 14:50:35 borja Status1 pablo "Review scm12816" Branch id:424073
425830 05/06/2013 17:04:37 jesusmg Status0 pablo "Review scm11179" Branch id:413120
426717 14/06/2013 14:01:14 roberto Status1 pablo "Code review 1" Branch id:426648
Total: 4
所以我们想将该审查与特定时间跨度内符合以下特定条件的那些审查进行比较:
cm find "review where assignee = 'me' and date > '2013/06/14' and date < '2013/06/15' and status = 1"
8424078 29/05/2013 14:50:35 borja Status1 pablo "Review scm12816" Branch id:424073
426717 14/06/2013 14:01:14 roberto Status1 pablo "Code review 1" Branch id: 426648
Total: 2
注意:正如在前几章中介绍的那样,我们在每个命令的末尾看到的 Total 值可以用 --nototal 选项省略。
通过这两个查询,我们可以获得此 sprint 中已批准/所有审查的比率。
在前面的示例中,我们将日期设置为特定值,但我们也可以使用“昨天”甚至“3 个月前”。如果您想检查与当前日期相关的时间跨度,这将非常有用:
cm find "review where assignee = 'me' and date >= '4 days ago' and status = 1"
8424078 29/05/2013 14:50:35 borja Status1 pablo "Review scm12816" Branch id:424073
Total: 1
筛选和输出选项
下表显示了当前可用于 cm find review 命令的不同筛选选项:
筛选选项 (where...) |
assignee |
comment |
date |
guid |
id |
owner |
status |
targetid |
了解如何使用常量按日期进行筛选。
以下另一个表显示了当前可用于 cm find review 命令的不同输出选项:
输出选项 (--format...) |
assignee |
date |
id |
owner |
status |
target |
targettype |
title |
搁置
我可以查找其他人创建的搁置吗?
我们可以获取我的团队成员在去年创建的搁置:
cm find shelve "where owner != 'me' and date >= '1 years ago'"
3848 2 04/10/2018 5:58:22 PM pablo doom3code Shelve - temporary compilation.txt file
3860 3 06/23/2018 11:08:06 PM pablo doom3code Shelve - test with a new configuration
Total: 2
筛选和输出选项
下表显示了当前可用于 cm find shelve 命令的不同筛选选项:
筛选选项 (where...) |
owner |
date |
attribute |
attrvalue |
comment |
guid |
parent |
shelveid |
id |
了解如何使用常量按日期进行筛选。
以下另一个表显示了当前可用于 cm find shelve 命令的不同输出选项:
输出选项 (--format...) |
id |
shelveid |
date |
owner |
repository |
comment |
输出和后期处理选项
在本文中,我们已经介绍了如何自定义输出,但我们也可以将输出设置为 XML 并将其保存到文件中以供稍后分析。这样,以下命令:
cm find revisions "where changeset=16716" --xml --file=output.xml
生成以下 XML 内容:
<?xml version="1.0" encoding="utf-8" ?>
<PLASTICQUERY>
<REVISION>
<ID>426098</ID>
<COMMENT></COMMENT>
<DATE>07/06/2013 16:00:09</DATE>
<OWNER>roberto</OWNER>
<TYPE>dir</TYPE>
<SIZE>0</SIZE>
<CHANGESET>16716</CHANGESET>
<PARENT>426069</PARENT>
<ITEM>d:\linked_replicated\</ITEM>
<ITEMID>2</ITEMID>
<BRANCH>br:/main/Fix-4.1/scm12863</BRANCH>
<PATH>d:\linked_replicated\</PATH>
<REPOSITORY>codice</REPOSITORY>
<REPNAME>codice</REPNAME>
<REPSERVER>localhost:8087</REPSERVER>
<HASH>kWJO1fm+7RCiZZcgSjM4/Q==</HASH>
</REVISION>
<REVISION>
<ID>426092</ID>
<COMMENT></COMMENT>
<DATE>07/06/2013 16:00:09</DATE>
<OWNER>roberto</OWNER>
<TYPE>txt</TYPE>
<SIZE>78238</SIZE>
<CHANGESET>16716</CHANGESET>
<PARENT>426056</PARENT>
<ITEM>d:\linked_replicated\01nerva\src\client\plastic\ActionMenuManager.cs</ITEM>
<ITEMID>37736</ITEMID>
<BRANCH>br:/main/Fix-4.1/scm12863</BRANCH>
<PATH>d:\linked_replicated\01nerva\src\client\plastic\ActionMenuManager.cs</PATH>
<REPOSITORY>codice</REPOSITORY>
<REPNAME>codice</REPNAME>
<REPSERVER>localhost:8087</REPSERVER>
<HASH>FXmLNV7B9Et1wTGqULWpgQ==</HASH>
</REVISION>
</PLASTICQUERY>
此内容稍后可以导入到 Excel 等工具中,并轻松从中获取统计信息。
统计信息
假设我们想要获取存储库中所有变更集的信息;然后我们可以执行以下命令:
cm find changeset --xml --file=output.xml
然后,我们可以在 Excel 中加载输出;结果如下:
Excel 包含一个非常有用的实用程序,称为“数据透视表”,可让我们获取更多统计信息。
使用 Excel 中提供的筛选和排序功能,我们可以对变更集用户进行分组,并将这些统计信息转换为图表:
我们也可以按分支分组;通过按分支分组,我们可以了解有多少用户参与,每个用户在每个分支上创建了多少变更集。
语法规则
find 命令针对每个对象都有一个默认输出,但我们可以定义我们先前看到的自定义输出选项,使用 XML 格式和 --xml 属性检索结果,以及使用 --file 属性将结果保存在文件中以供稍后分析。
一般语法如下:
cm find object "[where conditions] [on repositories]" [options]
其中:
日期常量
在按日期进行筛选时,可以使用遵循机器本地化设置的日期格式。例如,如果计算机以“MM-dd-yyyy”格式显示日期,则可以在查询中使用“12-31-2019”之类的日期。
还可以使用以下常量来简化查询:
'today'
:今天的日期。
yesterday'
:昨天的日期。
this week'
:本周星期一的日期。
this month'
:本月第一天的日期。
this year'
:本年 1 月 1 日。
one day ago'
:当前日期前一天。
one week ago'
:当前日期前七天。
one month ago'
:当前日期前一个月。
n days ago'
:当前日期前“n”天。
n months ago'
:当前日期前“n”个月。
n years ago'
:当前日期前“n”年。
以下 where 子句对于类型为 date 的字段有效:
- (...) where date > 'today' (...)
- (...) where date < 'yesterday' (...)
- (...) where date > 'this week' (...)
- (...) where date > 'this month' (...)
- (...) where date < 'one day ago' and date > '3 days ago' (...)
- (...) where date < 'one week ago' and date > '3 weeks ago' (...)
- (...) where date < 'one month ago' and date > '3 months ago' (...)
- (...) where date > '1 year ago' (...)
上次更新
2019 年 12 月 10 日
我们通过添加缺失的双引号修复了一些 cm find 示例。
2018 年 12 月 7 日
我们添加了一些新示例。
了解如何查找搁置。
按日期筛选时可以使用日期常量。
2017 年 11 月 20 日
了解如何使用 on repositories 参数从一个或多个存储库进行查询。
2014 年 7 月 1 日
发布日期。