получить набор файлов, которые были изменены после определенной даты

StackOverflow https://stackoverflow.com/questions/1528806

  •  20-09-2019
  •  | 
  •  

Вопрос

Есть ли у кого-нибудь удобный скрипт PowerShell, который получает набор файлов из TFS на основе даты изменения?Я хотел бы сказать: «дайте мне все файлы в этой папке (или подпапке), которые были изменены после X/Y/ZZZZ», и сбросьте эти файлы в папку, отличную от той, в которую они обычно попадают.Я знаю достаточно PowerShell, чтобы в конечном итоге взломать и сделать это, но я надеюсь избежать этого.

Это было полезно?

Решение

Убедитесь, что у вас есть Team Foundation 2015 Электроинструменты установлен.Он поставляется с оснасткой PowerShell.Вы можете запустить файл консоли PowerShell прямо из его группы автозагрузки или выполнить Add-PSSnapin Microsoft.TeamFoundation.PowerShell.Затем перейдите в рабочую область и выполните:

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

Обратите внимание, что при этом файлы копируются в плоскую структуру папок.Если вы хотите сохранить структуру каталога, это немного сложнее.

Другие советы

Использование 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

Первый — это прямая адаптация кода Кита с использованием более дешевых запросов и устранением зависимости от рабочей области.Это лучший вариант, если вы знаете, что большой процент элементов в этом каталоге был недавно изменен.

Второй вариант напрямую запрашивает историю набора изменений.Если позволить оператору Where вычисляться в SQL, а не на клиенте, это может быть на порядок более эффективно, если недавно был изменен небольшой процент элементов (как это часто бывает).Однако запросы на основе элементов будут задерживаться, если будет возвращено много больших наборов изменений, что сделает JOIN сервера для получения свойств элемента дорогостоящим и заставит наше удаление дубликатов на стороне клиента выполнять большую работу.

[Да, я знаю, что для -Version требуется строка, это не совсем в стиле Powershell;моя вина.Ты мог создайте DateVersionSpec с помощью new-object и вызовите его 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() будет ограничен точным набором интересующих нас элементов.И, конечно же, мы исключаем вероятность того, что время загрузки станет узким местом.Вероятно, это лучшее решение из всех, когда количество наборов изменений невелико, и опасения, которые я высказал по поводу синхронизации рабочей области Кейта, по какой-либо причине неактуальны.

Могу ли я просто сказать, что необходимость использования PowerShell для этого кажется абсурдом.

Кстати, я занимался TFS внутри и за пределами MS в течение 4,5 лет и никогда не видел запроса на эту функцию.Если бы вы могли подробнее рассказать, какую цель вы на самом деле пытаетесь достичь, я думаю, мы могли бы предложить лучший способ.Не поймите меня неправильно, я написал расширения Powershell именно для того, чтобы справляться с такими странными сценариями.Но часто это работа для другого инструмента, например:Аннотации, MSBuild, сравнение схем БД...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top