有没有人有一个方便的 powershell 脚本,可以根据修改日期从 TFS 获取一组文件?我想说“给我这个文件夹(或子文件夹)中在 X/Y/ZZZZ 之后修改的所有文件”并将这些文件转储到他们通常会去的文件夹之外的文件夹中。我知道足够多的 powershell 来破解并最终完成这项工作,但我希望避免这种情况。
2 回答
确保已安装Team Foundation 2015 Power Tools。它带有一个 PowerShell 管理单元。您可以直接从其启动组运行 PowerShell 控制台文件,也可以执行 Add-PSSnapin Microsoft.TeamFoundation.PowerShell。然后 cd 到您的工作区并执行:
Get-TfsItemProperty . -r | Where {$_.CheckinDate -gt (Get-Date).AddDays(-30)} |
Format-Table CheckinDate,TargetServerItem -auto
CheckinDate TargetServerItem
----------- ----------------
9/14/2009 1:29:23 PM $/Foo/Trunk/Bar.sln
9/29/2009 5:08:26 PM $/Foo/Trunk/Baz.sln
将该信息转储到目录:
Get-TfsItemProperty . -r | Where {$_.CheckinDate -gt (Get-Date).AddDays(-30)} |
Select TargetServerItem > c:\recentlyChangedFiles.txt
要将这些文件复制到另一个目录(假设您已将它们从本地下拉到工作文件夹中):
Get-TfsItemProperty . -r | Where {$_.CheckinDate -gt (Get-Date).AddDays(-30)} |
CopyItem -Path $_.LocalItem -Destination C:\SomeDir -Whatif
请注意,这会将文件复制到平面文件夹结构中。如果要维护目录结构,则涉及更多。
像 Keith 一样使用 Get-TfsItemProperty 不仅需要用于文件副本的工作区。它是 GetExtendedItems() 的包装器,它是源代码管理资源管理器中最常见的本地信息的服务器查询。通过依赖它报告的版本信息,您假设文件本身是在过去 30 天内下载的(更一般地说:同步,在重命名和删除的情况下)。如果工作区不是最新的,您会错过一些文件/给它们提供过时的名称/等等。作为信息命令,它也非常昂贵。
一些替代示例:
# 1
Get-TfsChildItem $/FilesYouWant -R |
? { $_.CheckinDate -gt (Get-Date).AddDays(-30) } |
% { $_.DownloadFile(join-path C:\SomeDir (split-path $_.ServerItem -leaf)) }
# 2
Get-TfsItemHistory $/FilesYouWant -R -All -Version "D$((Get-Date).AddDays(-30).ToString('d'))~" |
Select-TfsItem |
Select -Unique -Expand Path |
Sort |
Out-File c:\RecentlyChanged.txt
第一个是对 Keith 代码的直接改编,使用更便宜的查询并消除工作空间依赖性。如果您知道该目录下的大部分项目最近被修改过,这是最好的选择。
第二个选项直接查询变更集历史。通过让 Where 子句在 SQL 中而不是在客户端上计算,如果最近更改的项目的百分比较低(通常是这种情况),这可以提高一个数量级的效率。但是,如果返回大量大型变更集,它将滞后于基于项目的查询,从而使服务器的 JOIN 获取项目属性的成本很高,并迫使我们的客户端重复删除做大量工作。
[是的,我知道 -Version 需要一个字符串并不是 Powershell 式的;过失。您可以使用 new-object 创建一个 DateVersionSpec 并调用它的 ToString(),但这需要更多的工作。]
我没有展示 API 调用 + 所需任务的所有组合。不用说,您可以使用#1 生成文件列表,并使用#2 通过修改管道的后半部分来(重新)下载。您甚至可以将该复制技术与 Get-TfsItemHistory 的效率结合起来:
# 2b, with local-to-local copying
Get-TfsItemHistory $/FilesYouWant -R -All -Version "D$((Get-Date).AddDays(-30).ToString('d'))~" |
Select-TfsItem |
Select -Unique -Expand Path |
Get-TfsItemProperty |
Copy $_.LocalItem -Dest C:\SomeDir
确实,这会与服务器进行第二次往返,但由于初始查询,GetExtendedItems() 调用的范围将限定为我们感兴趣的精确项目集。当然,我们消除了下载时间成为瓶颈的任何机会. 当变更集的数量很小并且我提出的关于 Keith 的工作区同步的担忧无论出于何种原因都无关紧要时,这可能是所有解决方案中的最佳解决方案。
我只能说必须使用 powershell 来执行此操作似乎很荒谬。
FWIW, I've been involved with TFS from inside & outside MS for 4.5yr and never seen this feature requested. If you could expand on what goal you're actually trying to accomplish, my guess is we could suggest a better way. Don't get me wrong, I wrote the Powershell extensions precisely to handle oddball scenarios like this. But frequently it's a job for another tool entirely, eg: Annotate, MSBuild, DB schema compare...