web-dev-qa-db-ja.com

Team Foundation Server-履歴を持つソースの移動

あるチームプロジェクトから別のチームプロジェクトにソースコードを履歴とともに移動するのに最適なアプローチは何だろうと思っていました。復元しようとしているシステムはこれらの機能を使用していなかったため、作業項目、レポート、またはSharePointサイトは関係ありません。別のチームプロジェクトに移行したい理由は、元の実装(サードパーティによって管理されているバックアップから復元されている)が使用したくないサードパーティプロセステンプレートを使用していたためです。今後。移行が完了した後、作業項目の追跡とレポートの利用を開始したいと考えています。

TFS Integration Platform は、ありそうなシナリオのようです。ドキュメントによると、プロセステンプレートの変更に使用できます。しかし、tf.exe move構文が機能するかどうか興味がありましたか?何かのようなもの:

tf.exe move $/ProjectA $/ProjectB

このコマンドは名前変更操作によく似ており、ソース管理エクスプローラーの[移動]コンテキストメニュー項目を使用した移動は、削除および追加操作に似ていることを理解しています。また、$/ProjectAが1つのプロジェクトのルートソース管理フォルダーであり、$/ProjectBが他のプロジェクトのルートソース管理フォルダーであると仮定すると、tf.exeの移動パスは実際にフォルダーの下のコードを適切なチームプロジェクトに関連付けますか?重要なのは、可能であれば、履歴を保存できるようにすることです。

アドバイスやヒントは大歓迎です!

編集-別のプロジェクトへの分岐がこのシナリオを処理できますか?-Microsoftが 分岐ガイダンス ドキュメントで説明しているように?これは答えかもしれないと思う、なぜなら歴史はブランチと共に保存される可能性が高いからだ。ただし、現時点ではTeam Foundation Server 2008インスタンスにアクセスしてテストすることはできません。

57
Joseph Ferris

MoveとRenameはエイリアスです。 TFSのどのバージョンでも、コマンドラインまたはUIとまったく違いはありません。

両方とも歴史を保存します。少なくとも2005/2008では、名前や親パスがどれほど頻繁に、またはどれだけ大きく変更されても、同じ物理アイテムをVersionedItemテーブルに保持します。実際には、多くの手作業を行わずに「偽の」名前変更(削除+追加)を行う方法はありません。

ただし、このバージョン管理モデルは理論的な意味では非常に純粋ですが、実用的な落とし穴がいくつかあります。異なるアイテムは異なる時点で同じ名前を使用できるため、TFSは送信する入力を一意に識別するためにフルネーム+バージョンが必要です。通常、この制限に気付きませんが、一度システムのアイテムの名前を変更すると、tf [doSomething] $/newname -version:oldversionと言うと、混乱してエラーをスローしますまたは、意図していない可能性のあるアイテムを操作します。有効な組み合わせ(newname + newversionまたはoldname + oldversion)を渡して、コマンドが希望どおりに動作するように注意する必要があります。

TFS 2010は、ストーリーを多少変更します。これは、ブランチ+削除の下にあるため、itemIDが変更されます。それでも、GetやHistoryなどの日常的なコマンドは非常によく「偽造」されています。古いクライアントの互換性は約95%です。利点は、システムに複数の名前変更があり、パスベースのアイテム検索が上記のようにあいまいになり始めると、サーバーは指定した名前を受け入れてそれで実行することです。これにより、システム全体のパフォーマンスが向上し、あまり馴染みのないユーザーがよく陥るいくつかのトラップが排除されますが、100%の精度で履歴が保持されないほど柔軟性が失われます(たとえば、2つのブランチのマージ中に名前の衝突がある場合)。

手元の問題に戻る...

tf rename $/projectA $/projectBと言うほど簡単ではありません。ソース管理ツリーの最上位フォルダーは、チームプロジェクト作成ウィザード用に予約されています。それらに対して標準のtfコマンドを実行することはできません。必要なのは次のようなスクリプトです:

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

[もちろん、$/ProjectAの下にあまり多くの子がいない場合は、手で行うことができます]

私が言及した落とし穴に関しては、古い歴史を調べることはあなたにとって非常に重要であると思われるので、今すぐ詳しく説明します。名前変更をチェックインすると、tf history $/ProjectA/somefile.csは機能しません。デフォルトでは、tfコマンドはversion = "latest"を想定しています。これらの選択肢のいずれも、あなたが望む完全な歴史になります:

  • tf history $/ProjectA/somefile.cs; 1234変更セット1234は移動前でした
  • tf history $/ProjectB/somefile.cs; 5678変更セット5678は移動後です。または、バージョンを省略できます。

完全性とデバッグを目的とした最終的な代替手段:

  • tf history $/ProjectA/somefile.cs -slotmode。移動前に発生した変更のみが表示されます。ただし、Bの下に移動したアイテムの前または後に$/ProjectA/somefile.csの「スロット」に存在した可能性のある他のアイテムの履歴も表示されます。

(TFS 2010では、「スロットモード」がデフォルトの動作です。パスベースではなく、2008年のように履歴全体でルックアップをトレースすることを要求する-ItemModeオプションがあります。)

編集-いいえ、分岐は素晴らしい選択肢ではありません。分岐はシステムに十分なメタデータを残してProjectBとの間で完全な履歴をトレースしますが、2008年にはそれほどユーザーフレンドリーではありません。tf mergesコマンド(UIに相当するものはありません) )。 2010は、複数のブランチにわたる変更を視覚化する能力を劇的に向上させますが、それでも名前の変更から得られるクリーンな統合エクスペリエンスではありません。

38
Richard Berg

上記のリチャードの答えはよく書かれており、状況をよく説明しています。ただし、追加する実用的な落とし穴がいくつかありました。

TFS2010では、デフォルトの動作によりseemになります。ファイルを移動すると、移動前のすべての履歴が失われます。ユーザーが使用する可能性が高いコマンド(およびVS2010 GUIで使用されるコマンド)は次のとおりです。

tf history $/ProjectB/somefile.cs

ユーザーは、移動の前後にsomefile.csのすべての履歴を取得する予定です。いつでもファイル名に関係なく、「現在$/ProjectB/somefile.csに保存されているコードの履歴」が必要です。たぶん他の人はそれを異なって見るでしょう。

最初の落とし穴は、VS2010でTFS2010を使用して表示されるGUIには、移動後の履歴のみが最初に表示されることです。リスト内で最も新しいアイテムは名前変更操作です。微妙な小さなドロップダウン矢印で展開できます。その下には、以前の場所からの履歴があります。これを探すことを知らない場合、あなたの歴史がなくなっているように見えます。

2番目の落とし穴は、後でProjectAを削除すると(たとえば、ProjectBへの移行が完了したため)、履歴が本当になくなることです。 $/ProjectB/somefile.csの履歴のドロップダウンを展開しても、古い履歴は生成されません。

17
solublefish

別のオプション(そして私はもっと簡単だと思う)は、Gitにインポートしてから、 Git-TF コマンドラインツールを使用してTFSにエクスポートすることです。

  • バイナリ、Choclatey、またはソースコードからGit-TFをインストールします。

  • TFSフォルダーを複製します。

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

  • .Git/tfフォルダーと.Git/git-tfファイルを削除して、GitリポジトリとTFSサーバーの関連付けを解除します。

  • emptyTFSフォルダーに接続するように新しいGitリポジトリを構成します。

git tf configure https://myAcc.visualstudio.com/mycollection $/TeamProjectB/Main --deep

  • --deepを忘れないでください

git tf pull

この時点で「git-tf:これは新しく構成されたリポジトリです。tfsから取得するものはありません。」というメッセージが表示されます。

git commit -a -m "merge commit"

git tf checkin --deep

2
david004

上記の元のコマンドに関して:-

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

完全なパスファイル名にスペースが含まれる場合に備えて、ソース名とターゲット名の両方を引用符で囲む必要があります。 $ _。ServerItemでこれを行うのは難しいことがわかりました。エスケープされた "で囲むと、.serverItem文字列だけでなく、その子オブジェクト全体が返されます。などの不要なキャリッジリターン


$ proj/folder/file

最終的には次のコマンドを処理するコマンドを取得しましたが、履歴がまだ転送されないことがわかりました。これが全体のポイントでした。したがって、このコマンドは、ソースエクスプローラーでマウスの右クリックを使用し、名前の変更(または移動)を選択することとまったく同じだと思います。

$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 }

また、エスケープするにはバックティック `を使用する必要があります。

0
Philip Beck