2012-05-03 18 views
11

Ich möchte den Quellcode eines Projekts zu einem bestimmten Zeitpunkt erhalten (Changeset). Also muss ich den ganzen Ordner herunterladen. Ich würde es gerne für verschiedene Zeiten machen und die Handhabung eines anderen Arbeitsbereichs ist nicht sehr praktisch.Wie bekomme ich eine bestimmte Version des Ordners von tfs, ohne einen Arbeitsbereich zu erstellen?

Ich weiß über TFS Get Specific Version into separate folder (mit Arbeitsbereich) und Need command to get a file from TFS without a workspace (eine Datei).

Gibt es eine Lösung für den gesamten Ordner, ohne einen neuen Arbeitsbereich zu erstellen?

Bearbeiten Ich habe die akzeptierte Antwort zu ambitioniert gefunden. Ich brauchte etwas Einfacheres.

Annahmen:

  • ich TFS von Visual Studio auf meinem Computer
  • zugreifen Ich kann die ChangeSetNumber Changeset aus dem Ordner DesiredFolder in TFS Projekt tProj

ich das bekommen will laufen folgenden Stapel aus einem Zielordner in Visual Studio-Eingabeaufforderung

set workspace_name=TemporaryWorkspace%username% 
set changeset= ChangeSetNumber     
tf workspace -new %workspace_name% -noprompt 
tf workfold -map $/tProj . -workspace:%workspace_name% 
tf get $/tProj/DesiredFolder -version:C%changeset% -recursive -noprompt 
tf workfold -unmap . -workspace:%workspace_name% 
tf workspace -delete %workspace_name% -noprompt 

Beim Start der heruntergeladenen Lösung muss die Zuordnung der Quellcodeverwaltung entfernt werden.

+0

Können Sie erklären/erarbeiten "es für verschiedene Zeiten tun"? – Nock

+0

@Nockawa: Vielleicht sollte es verschiedene Changesets geben. Ich muss nur untersuchen, ob und warum es sich anders verhält als früher. – IvanH

+0

Können Sie erklären, warum Manipulation mit einem Arbeitsbereich nicht bequem ist? Wenn Sie einen Arbeitsbereich eingerichtet haben und das gesamte Projekt mit Änderungssatz 150 synchronisieren möchten, können Sie dies mit einem einzigen Befehl tun: "tf get/version: 150". –

Antwort

13

Ich benutze diese Syntax für temporäre Arbeitsbereiche:

tf workspace -new %JOB_NAME%;%user% -noprompt -server:http://%host%:8080/tfs/%project% -login:%user%,%password% 
tf workfold -map $/Release/MilestoneX.X . -workspace:%JOB_NAME% -server:http://%host%:8080/tfs/%project% -login:%user%,%password% 
tf get . -version:L%TFS_LABEL% -recursive -noprompt -login:%user%,%password% 
tf workfold -unmap . -workspace:%JOB_NAME% -login:%user%,%password% 
tf workspace -delete %JOB_NAME%;%user% -noprompt -server:http://%host%:8080/tfs/%project% -login:%user%,%password% 
4

Ich denke, Sie sollten einen temporären Arbeitsbereich erstellen, um den gewünschten Inhalt abzurufen, löschen Sie den Arbeitsbereich und behalten Sie die lokalen Elemente.

Ein Arbeitsbereich in TFS ist eine lokale Ansicht dessen, was auf dem Server ist. Für einen bestimmten Arbeitsbereich wählen Sie, welche Ordner Sie lokal abrufen möchten und wo Sie die Ordner/Dateien speichern.

Es ist nicht wie SourceSafe Sie sind nicht an einen einzigen Arbeitsplatz gebunden, können Sie so viele wie Sie wollen auf einem bestimmten Computer haben.

Also ich schlage vor, dass Sie einen dedizierten Arbeitsbereich für die Operation, die Sie tun möchten, erstellen und loswerden, wenn Sie es für richtig halten.

Verwenden Sie den Befehl TF.exe workspace, um einen Arbeitsbereich aus der Shell zu erstellen/löschen. Dann TF.exe get, um die Dateien abzurufen.

+0

Ich gebe es eine Chance. Aber ich hätte gerne etwas als Ansicht aber für einen Ordner. – IvanH

6

Ich habe entdeckt, dass Sie dies über das HTTP-api tun können, die TFS aussetzt. Die „Signatur“ für die URL lautet wie folgt:

http(s)://{server}:{port}/tfs/{collectionName}/{teamProjectName}/_api/_versioncontrol/itemContentZipped?version={versionSpec}&path={escapedPathToFolder} 

Also, wenn Sie ein Projekt „MyProject“ in der DefaultCollection genannt haben, und wollen den Inhalt eines Ordners „MyFeature“ genannt bekommen:

http://MyTfsServer:8080/tfs/DefaultCollection/MyProject/_api/_versioncontrol/itemContentZipped?version=C1001&path=%24%2FMyProject%2FMyFeature 

Ich denke, "Version" kann jede Versionsspezifikation sein, die in der TFS-API-Dokumentation dokumentiert ist. Mein Beispiel fordert die Version ab Änderungssatz 1001 an.Ich habe die .NET-API verwendet, um eine bestimmte Version zu erhalten, die ziemlich einfach, aber langsam ist, da sie nur jeweils eine Datei abrufen kann. Ich versuche herauszufinden, ob die gleiche Funktionalität über die .NET-API verfügbar gemacht wird, weil das Herunterladen der Dateien viel schneller ist, als eine einzelne Datei gleichzeitig zu erhalten.

Ich habe dies als eine Erweiterungsmethode auf Microsoft.TeamFoundation.VersionControl.Client.Item. implementiert Dies gibt einen Stream zurück, der eine Zip-Datei enthält. Ich hatte dies als Teil einer benutzerdefinierten MSBuild-Aufgabe verwendet, die dann den Inhalt dieses Streams an einem Speicherort speichert.

public static class TfsExtensions 
{ 

    const String ItemContentZippedFormat = "/_api/_versioncontrol/itemContentZipped?version={0}&path={1}&__v=3"; 

    public static Stream DownloadVersion(this Item folder, VersionSpec version) 
    { 
     if (folder.ItemType != ItemType.Folder) 
      throw new ArgumentException("Item must be a folder", "folder"); 


     var vcs = folder.VersionControlServer; 

     var collectionName = vcs.TeamProjectCollection.CatalogNode.Resource.DisplayName; 

     var baseUri = folder.VersionControlServer.TeamFoundationServer.Uri; 
     if (!baseUri.LocalPath.EndsWith(collectionName, StringComparison.OrdinalIgnoreCase)) 
      baseUri = new Uri(baseUri, baseUri.LocalPath + "/" + collectionName); 


     var apiPath = String.Format(ItemContentZippedFormat, version.DisplayString, WebUtility.UrlEncode(folder.ServerItem)); 
     var downloadUri = new Uri(baseUri, baseUri.LocalPath + apiPath); 

     var req = WebRequest.Create(downloadUri); 
     req.Credentials = CredentialCache.DefaultCredentials; 
     var response = req.GetResponse(); 
     return response.GetResponseStream(); 
    } 
} 
+0

Kommunizieren Sie mit einem tfs-Server mit dem WebClient oder anders herum? Würden Sie einen Beispielcode hinzufügen? – IvanH

+0

@IvanH Ich benutze System.Net.WebRequest, um den Inhalt zu erhalten. Enthalten ein Beispiel. – MarkPflug

+0

Beachten Sie, dass die Verwendung dieser Art von Mechanismus die Download-Proxies nicht nutzt, wenn Sie diese konfiguriert haben. Ansonsten ist das in der Tat ein sehr schöner Mechanismus. –

1

Sie können tf view verwenden, um eine bestimmte Datei zu erhalten, ohne einen Arbeitsbereich zu schaffen.

Retrieves a specific version of a file to a temporary folder on your computer and displays it. 

tf vc view [/collection:TeamProjectCollectionUrl] 
     [/console] [/recursive] [/output:localfile] 
     [/shelveset:shelvesetname[;owner]] [/noprompt] itemspec 
     [/version:versionspec] [/login:username,[password]] 

Versionspec: 
Date/Time   D"any .Net Framework-supported format" 
        or any of the date formats of the local machine 
Changeset number Cnnnnnn 
Label    Llabelname 
Latest version T 
Workspace   Wworkspacename;workspaceowner 
+1

Dieser Ansatz funktioniert nur mit einzelnen Dateien, nicht mit Verzeichnissen. Wenn Sie den Befehl so ausführen, wie Sie ihn hier haben, wird eine massive Datei (C: \ Pfad \ zu \ Lokalverzeichnis) erzeugt, die alle Dateien in dem Ordner enthält, die verkettet sind. – JamesQMurphy

+0

@JamesQMurphy, danke! Ich kann nicht glauben, dass das so funktioniert. Am Ende habe ich das mit einer Powershell-Funktion gelöst, die eine Kombination aus 'dir' und' view' verwendet. Sie können es in diesem [gist] (https://gist.github.com/clintcparker/ee92d2e6faa45614e2c41afbd33884ed) sehen. – clintcparker