获取一组在特定日期之后修改过的文件

时间:2009-10-07 00:07:03

标签: tfs powershell powershell-v2.0

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

2 个答案:

答案 0 :(得分:5)

确保已安装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

请注意,这会将文件复制到平面文件夹结构中。如果你想保持dir结构,那就更多了。

答案 1 :(得分:4)

像Keith一样使用Get-TfsItemProperty不仅需要文件副本的工作空间。它是GetExtendedItems()的包装器,它是Source Control Explorer中最常见的本地信息的服务器查询。依靠它报告的版本信息,您可以假设在过去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式的; mea culpa。你可以使用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,我从内部和外部参与了TFS。在MS之外的4.5升并且从未见过要求此功能。如果你可以扩展你实际想要实现的目标,我猜我们可以建议一个更好的方法。不要误会我的意思,我精确编写了Powershell扩展来处理像这样的奇怪场景。但通常它完全是另一个工具的工作,例如:Annotate,MSBuild,DB模式比较......