有没有人有一个方便的 powershell 脚本 根据修改日期从 TFS 获取一组文件?我想说“给我这个文件夹(或子文件夹)中在 X/Y/ZZZZ 之后修改的所有文件”,并将这些文件转储到它们通常所在的文件夹之外的文件夹中。我知道足够的 powershell 来破解并最终完成这件事,但我希望避免这种情况。

有帮助吗?

解决方案

确保您拥有 Team Foundation 2015 电动工具 安装。它带有一个 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,我从 MS 内部和外部参与 TFS 已有 4.5 年,但从未见过此功能请求。如果您可以详细说明您实际想要实现的目标,我猜我们可以提出更好的方法。不要误会我的意思,我编写 Powershell 扩展正是为了处理这样的奇怪场景。但通常这完全是另一个工具的工作,例如:注释、MSBuild、数据库架构比较...

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top