Team Foundation Server-перемещение источника с историей


Мне было интересно, какой лучший подход может быть в перемещении исходного кода, с историей, из одного командного проекта в другой командный проект. Я не занимаюсь рабочими элементами, отчетами или сайтами SharePoint, поскольку система, которую мы собираемся восстанавливать, не использовала эти функции. Причина желания перейти к другому командному проекту также обусловлена тем, что исходная реализация (восстанавливаемая из резервной копии, которая поддерживалась третьей стороной) использовала сторонний шаблон процесса, который мы не хотим использовать в будущем. Мы хотим начать использовать отслеживание рабочих элементов и отчетность после завершения миграции.

The платформа интеграции TFS кажется, один из вероятных сценариев. Он может быть использован для изменения шаблона процесса, в соответствии с документацией. Однако мне было любопытно, если tf.синтаксис перемещения exe может работать? Что-то вроде:

tf.exe move $/ProjectA $ / ProjectB

Это мое понимая, что эта команда работает так же, как операция переименования, в то время как перемещение с помощью пункта контекстного меню "переместить" в Обозревателе управления версиями больше похоже на операцию удаления и добавления. Кроме того, будет ТФ.путь перемещения exe фактически связывает код под папками с соответствующим командным проектом, предполагая, что $/ProjectA является корневой папкой управления исходным кодом для одного проекта и $/ProjectB является корневой папкой управления исходным кодом для другого? Ключ должен быть в состоянии сохранить историю, если вероятный.

любые советы или советы будут с благодарностью!

Edit-может ли ветвление на другой проект обрабатывать этот сценарий-так же, как Microsoft обсуждает в Руководство По Ветвлению документации? Я думаю, что это может быть ответом, так как история, скорее всего, будет сохранена с веткой. Однако на данный момент у меня нет доступа к экземпляру Team Foundation Server 2008 для его тестирования.

4 56

4 ответа:

перемещение и переименование псевдонимы. Нет абсолютно никакой разницы, в любой версии TFS, из командной строки или пользовательского интерфейса.

оба они сохраняют историю. По крайней мере, в 2005/2008 году вы сохраняете один и тот же физический элемент в таблице VersionedItem независимо от того, как часто и как сильно изменяется имя и/или родительский путь. На самом деле нет никакого способа получить "поддельное" переименование (удалить + добавить) без большой ручной работы с вашей стороны.

однако, в то время как эта модель управления версиями очень чисто в теоретическом смысле, у него есть некоторые практические готы. Поскольку разные элементы могут занимать одно и то же имя в разные моменты времени, TFS необходимо полное имя + версия, чтобы однозначно идентифицировать любые входные данные, которые вы отправляете. Обычно вы не замечаете этого ограничения, но как только вы переименовали элементы в системе, если вы говорите tf [doSomething] $ / newname-version: oldversion тогда он запутается и либо бросит ошибку, либо будет работать с элементом, который вы, возможно, не намеревались. Вы нужно быть осторожным, чтобы передать допустимые комбинации (newname+newversion или oldname+oldversion), чтобы гарантировать, что команды ведут себя так, как вы хотите.

TFS 2010 несколько меняет историю: это ветка+удаление под обложками, что приводит к изменению itemID. Тем не менее, повседневные команды, такие как Get и History, очень хорошо "подделаны"; старые клиенты совместимы примерно на 95%. Преимущество заключается в том, что при наличии нескольких переименований в системе и поиске элементов на основе пути начинают становиться неоднозначными, как указано чтобы выше, сервер просто примет указанное вами имя и запустится с ним. Это улучшает общую производительность системы и устраняет несколько ловушек, в которые часто попадали незнакомые пользователи, за счет того, что они не были такими гибкими и не сохраняли историю со 100% точностью (например, когда есть конфликты имен во время слияния двух ветвей).

возвращаясь к проблеме под рукой...

Это не так просто, как говорят TF переименовать $ / projectA $ / projectB. Верхний папки уровня в дереве управления версиями зарезервированы для мастера создания командных проектов; вы не можете запускать стандартные команды tf против них. Что вам нужно, это скрипт, как:

Get-TfsChildItem $/ProjectA |
    select -Skip 1 |  # skip the root dir
    foreach {
        tf rename $_.serveritem $_.serveritem.replace("$/ProjectA", "$/ProjectB")
    }

[конечно, вы можете сделать это вручную, если не слишком много детей под $ / ProjectA]

что касается gotchas, о которых я упоминал, я подробно остановлюсь на одном прямо сейчас, так как просмотр старой истории кажется вам очень важным. Как только вы проверяете переименование, история tf $ / ProjectA / somefile.cs не будет работать. По умолчанию команды tf принимают version = " latest."Любая из этих альтернатив будет полной историей, которую вы хотите:

  • история tf $/ProjectA / somefile.cs; 1234 где набор изменений 1234 был до переезда
  • история tf $/ProjectB / somefile.cs; 5678 где набор изменений 5678 был после переезда. Или вы можете просто опустить версию.

окончательная Альтернатива для полноты & цели отладки:

  • история tf $/ProjectA / somefile.cs-slotmode. Вы увидите только изменения, которые произошли до перемещения; однако вы также увидите историю любых других элементов, которые могли жить в $/ProjectA/somefile.cs "слот" до или после элемента, который вы переместили под B.

(в TFS 2010" режим слота " является поведением по умолчанию; есть опция-ItemMode, чтобы запросить трассировку вашего поиска история, как это было в 2008 году, а не на основе пути.)

EDIT-нет, ветвление не является отличной альтернативой. Хотя ветвление оставляет достаточно метаданных в системе, чтобы проследить полную историю До & от ProjectB, это не очень удобно для пользователя в 2008 году. Планируйте потратить много времени на изучение ТФ сливает команда (без эквивалента пользовательского интерфейса). 2010 значительно улучшает вашу способность визуализировать изменения в нескольких ветвях, но это все еще не чистый унифицированный опыт, который вы бы получить от переименования.

ответ Ричарда выше хорошо написан и хорошо объясняет ситуацию. Однако у меня была пара более практичных gotcha, чтобы добавить.

в TFS2010 поведение по умолчанию делает его кажется как перемещение файла приводит к потере всей истории от до перемещения. Команда, которую мои пользователи, вероятно, будут использовать (и тот, который используется, кажется, графическим интерфейсом VS2010):

tf history $/ProjectB/somefile.cs

мои пользователи намерены получить всю историю somefile.cs, как до, так и после переезда. Они хотят " историю кода, который в настоящее время хранится в $/ProjectB/somefile.КС", независимо от имени файла в любой момент времени. Может быть, другие люди видят это по-другому.

первый gotcha является то, что графический интерфейс, который появляется для меня в VS2010 с помощью TFS2010 initally показывает только историю с момента переезда. Самый последний элемент в списке-это операция переименования. Он может быть расширен с помощью тонкой маленькой выпадающей стрелки. Под ним находится история из предыдущего места. Если вы не знаю, чтобы искать это, это может выглядеть, как ваша история ушла.

вторая проблема заключается в том, что если вы позже удалите ProjectA (потому что вы закончили миграцию в ProjectB, скажем), история действительно ушла. Расширение раскрывающегося списка в истории для $/ProjectB / somefile.cs не производит более старую историю.

другой вариант (и я думаю, что проще) - импортировать в Git, а затем экспортировать обратно в TFS с помощью Git-TF инструменты командной строки.

  • установите Git-TF из двоичного, Choclatey или исходного кода.

  • клонировать папку TFS:

git tf clone https://myAcc.visualstudio.com/mycollection $/TeamProjectA/Main --deep

  • отключите репозиторий Git от сервера TFS, удалив

относительно исходной команды выше:-

Get-TfsChildItem $/ProjectA |
select -Skip 1 |  # skip the root dir
foreach {
    tf rename $_.serveritem $_.serveritem.replace("$/ProjectA", "$/ProjectB")
}

имена источника и цели должны быть заключены в кавычки, если в полном имени файла пути есть пробелы. Мне было трудно сделать это $_.ServerItem как окружающий его с экранированным " возвращает весь дочерний объект, а не только его .строки serverItem. Или если мне удалось получить строку, я получил нежелательные возвраты каретки такие как

"
$proj / папка / файл
"

В конце концов я получил команду для работы со следующим, но я обнаружил, что история все еще не передается, в чем и был весь смысл! Поэтому я считаю, что эта команда является прямым эквивалентом просто с помощью щелчка правой кнопкой мыши в проводнике источника и выбора переименовать (или переместить).

$tfsServerString = "http://machine:8080/tfs/DefaultCollection"
$tfs = Get-TfsServer $tfsServerString
Get-TfsChildItem -server $tfs "$/Dest Project/MyTestProject" | select -Skip 1 | foreach { $sourceName = $_.serveritem; $targetName = $_.serveritem.replace("$/Dest Project/MyTestProject/", "$/Dest Project/Source/StoreControllers/dSprint/dSprint2/") ; ./tf rename `"$sourceName`" `"$targetName`" /login:myUser }

Также обратите внимание, что для этого требуется использовать backtick ` to escape"