3

作業フォルダーを RAM ドライブに設定しました。夜中に長時間の停電があり、UPS が不足し、私のマシンがダウンしました。ありがたいことに、家に帰る前に変更を棚上げしたので、そのシェルブセットがチーム エクスプローラーに表示されます。変更セットには、プロジェクト ファイルと、まだソース管理に追加されていないいくつかの新しいファイルが含まれています。

影響を受けたファイルを回復しようとしていますが、エラーが発生しています:

棚上げされたファイルを表示しようとすると、リストに表示されていても表示されますTF10187(または一般的な番号なし) 。The system cannot find the file specifiedPending Changes

セット全体を保留解除しようとすると、incompatible changes解決できないエラーが発生します。

TFS がシェルフセットを RAM ディスクにローカルにキャッシュしたため、それ自体が再初期化されたため、キャッシュが失われたと推測していますが、間違っていることを願っています。

誰でも手伝ってもらえますか?

4

3 に答える 3

6

昨日誰かが私のところに来て、同じ質問をしました。幸いなことに、彼らはTFSプロジェクトデータベース(tfs_)のバックアップを持っていたので、それを別のデータベースに復元し、私はそれを調べて理解しました(バックアップがある場合は、はい、すべてのファイルを復元できます)。

最初に、データベース内のテーブルに関する情報を少し説明します。

シェルフセットは、tbl_Workspace テーブルにクエリを実行し、Type=1 (シェルフセット) のすべてのレコードを検索することで識別できます。もちろん、WorkspaceName 列を使用して名前でフィルター処理することもできます。

関心のある他のテーブルは次のとおりです。

tbl_PendingChanges (tbl_Workspace から WorkspaceId を参照) - ShelveSet の一部であるファイル

tbl_VersionedItem (ItemId 列を介して tbl_PendingChanges にリンク) - ファイルの親パスと名前

tbl_Content (FileId を介して PendingChanges にリンク) - これは、ファイルの内容が圧縮 (gzip) データとして保存される場所です。

解決策は次のとおりです。次のクエリでファイルを表示できます。

SELECT c.[CreationDate], c.[Content], vi.[ChildItem], vi.ParentPath
FROM [dbo].[tbl_Content] c 
INNER JOIN [dbo].[tbl_PendingChange] pc ON pc.FileId = c.FileId
INNER JOIN [dbo].[tbl_Workspace] w ON w.WorkspaceId = pc.WorkspaceId
INNER JOIN [dbo].[tbl_VersionedItem] vi ON vi.ItemId = pc.ItemId
WHERE w.WorkspaceName = '<YOUR SHELVESET NAME>'

そこで、SQL からデータを取得し、GZipStream クラスを使用してコンテンツを解凍し、ファイルをディスクに保存するコードをいくつか書きました。

1 週間ほどの作業が 1 時間ほどで完了しました。

これは TFS 2010 で行われました。

お役に立てれば!

于 2013-05-09T10:03:51.750 に答える
2

TFS 2012 インスタンスで同様のことが起こりました。TFS 2012 のスキーマが変更されたため、私の SQL クエリは少し異なりました。これが誰かの役に立てば幸いです。

SELECT c.[CreationDate], c.[Content], v.FullPath
FROM [dbo].[tbl_Content] c 
INNER JOIN [dbo].[tbl_File] f ON f.ResourceId = c.ResourceId
INNER JOIN [dbo].[tbl_PendingChange] pc ON pc.FileId = f.FileId--c.FileId
INNER JOIN [dbo].[tbl_Workspace] w ON w.WorkspaceId = pc.WorkspaceId
INNER JOIN [dbo].[tbl_Version] v ON v.ItemId = pc.ItemId AND v.VersionTo = 2147483647
WHERE w.WorkspaceName = @ShelvesetName

2147483647 は 2^32 - 1 のようです。これは、TFS 2012 の「最新」を表すと思われます。次に、Gzip でエンコードされたストリームを解凍し、適切なファイル名でディスクにダンプする C# ウィジェットも作成しました。私は階層を維持していません。

string cnstring = string.Format("Server={0};Database={1};Trusted_Connection=True;", txtDbInstance.Text, txtDbName.Text);
SqlConnection cn = new SqlConnection(cnstring);
SqlCommand cmd = new SqlCommand(@"
SELECT c.[CreationDate], c.[Content], v.FullPath
FROM [dbo].[tbl_Content] c 
INNER JOIN [dbo].[tbl_File] f ON f.ResourceId = c.ResourceId
INNER JOIN [dbo].[tbl_PendingChange] pc ON pc.FileId = f.FileId--c.FileId
INNER JOIN [dbo].[tbl_Workspace] w ON w.WorkspaceId = pc.WorkspaceId
INNER JOIN [dbo].[tbl_Version] v ON v.ItemId = pc.ItemId AND v.VersionTo = 2147483647
WHERE w.WorkspaceName = @ShelvesetName", cn);

cmd.Parameters.AddWithValue("@ShelvesetName", txtShelvesetName.Text);

DataTable dt = new DataTable();
new SqlDataAdapter(cmd).Fill(dt);
listBox1.DisplayMember = "FullPath";
listBox1.ValueMember = "FullPath";
listBox1.DataSource = dt;

if(!Directory.Exists(txtOutputLocation.Text)) { Directory.CreateDirectory(txtOutputLocation.Text); }
foreach (DataRow row in dt.Rows)
{
    string[] arrFilePath = row[2].ToString().Split('\\');
    string fileName = arrFilePath[arrFilePath.Length - 2];
    byte[] unzippedContent = Decompress((byte[])row[1]);
    File.WriteAllBytes(Path.Combine(txtOutputLocation.Text, fileName), unzippedContent);
}
}

    static byte[] Decompress(byte[] gzip)
    {
using(GZipStream stream = new GZipStream(new MemoryStream(gzip), CompressionMode.Decompress))
{
    const int size = 4096;
    byte[] buffer = new byte[size];
    using(MemoryStream memory = new MemoryStream())
    {
        int count = 0;
        do
        {
    count = stream.Read(buffer, 0, size);
    if(count > 0)
    {
        memory.Write(buffer, 0, count);
    }
        }
        while(count > 0);
        return memory.ToArray();
    }
}
}
于 2014-05-06T21:19:59.087 に答える