2012-05-03 23 views
11

Vorrei ottenere il codice sorgente di un progetto in un momento specifico (changeset). Quindi ho bisogno di scaricare l'intera cartella. Mi piacerebbe farlo per tempi diversi e gestire un diverso spazio di lavoro non è molto conveniente.Come ottenere una versione specifica della cartella da tfs senza creare uno spazio di lavoro?

Sono a conoscenza di TFS Get Specific Version into separate folder (con area di lavoro) e Need command to get a file from TFS without a workspace (un file).

C'è qualche soluzione per l'intera cartella senza creare un nuovo spazio di lavoro?

Modifica Ho trovato la risposta accettata troppo ambiziosa. Avevo bisogno di qualcosa di più semplice.

Ipotesi:

  • posso accedere a TFS da Visual Studio sul mio computer
  • voglio ottenere il ChangeSetNumber Changeset dalla cartella DesiredFolder nel progetto di TFS tProj

corro il seguente batch da una cartella di destinazione in Prompt dei comandi di Visual Studio

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 

È necessario confermare rimuovere l'associazione di controllo origine quando si avvia la soluzione scaricata.

+0

Puoi spiegare/elaborare "per farlo per tempi diversi"? – Nock

+0

@Nockawa: Forse ci dovrebbero essere diversi changeset. Ho solo bisogno di studiare se e perché si comporta in modo diverso da quello che era solito fare. – IvanH

+0

Puoi spiegare perché la manipolazione con uno spazio di lavoro non è conveniente? Se hai impostato uno spazio di lavoro e vuoi sincronizzare l'intero progetto con il changeset 150, puoi farlo con un comando: "tf get/version: 150". –

risposta

13

Io uso questa sintassi per gli spazi di lavoro temporanei:

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

Penso che dovresti creare uno spazio di lavoro temporaneo per recuperare il contenuto che desideri, quindi eliminare lo spazio di lavoro e conservare gli elementi locali.

Uno spazio di lavoro in TFS è una vista locale di ciò che è presente sul server, per un determinato spazio di lavoro si sceglie quale cartella si desidera recuperare localmente e dove si memorizzeranno le cartelle/i file.

Non è come SourceSafe sei non associato a un solo spazio di lavoro, puoi avere quante ne vuoi su un determinato computer.

Quindi ti suggerisco di creare uno spazio di lavoro dedicato per l'operazione che vuoi fare e di sbarazzartene quando lo giudichi appropriato.

Utilizzare il comando TF.exe workspace per creare/eliminare un'area di lavoro da Shell. Quindi TF.exe get per recuperare i file.

+0

Gli darò una possibilità. Ma mi piacerebbe avere qualcosa come vista ma per una cartella. – IvanH

6

ho scoperto che si può fare questo tramite l'API HTTP che TFS espone. La "firma" per l'URL è la seguente:

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

Quindi, se si dispone di un progetto denominato "MyProject" nel DefaultCollection, e vuole ottenere il contenuto di una cartella chiamata "MyFeature":

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

Penso che "versione" possa essere qualsiasi specifica di versione, che è documentata nella documentazione dell'API TFS. Il mio esempio richiede la versione del set di modifiche 1001.Stavo usando l'API .NET per ottenere una versione specifica, che è piuttosto semplice, ma lenta perché può ottenere solo un file alla volta. Sto cercando di capire se questa stessa funzionalità è esposta tramite l'API .NET perché scaricare i file in questo modo è molto più veloce di ottenere un singolo file alla volta.

L'ho implementato come metodo di estensione su Microsoft.TeamFoundation.VersionControl.Client.Item. Questo restituisce un flusso che contiene un file zip. L'ho usato come parte di un'attività MSBuild personalizzata che salva il contenuto di questo stream in un percorso file.

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

Comunica con un server TFS con WebClient o l'altro modo? Vuoi aggiungere un codice di esempio? – IvanH

+0

@IvanH Uso System.Net.WebRequest per ottenere il contenuto. Incluso un esempio – MarkPflug

+0

Si noti che l'utilizzo di questo tipo di meccanismo non sfrutta i proxy di download, se ne sono configurati. Altrimenti, questo è davvero un buon meccanismo. –

1

È possibile utilizzare tf view per ottenere un file specifico senza creare uno spazio di lavoro.

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

Questo approccio funziona solo con singoli file, non con le directory. L'esecuzione del comando così com'è qui produrrà un file di grandi dimensioni (denominato C: \ path \ to \ localdirectory) che contiene tutti i file nella cartella concatenati insieme. – JamesQMurphy

+0

@JamesQMurphy, grazie! Non posso credere che sia così che funziona. Ho finito per risolvere questo problema con una funzione di PowerShell usando una combinazione di 'dir' e' view'. Puoi vederlo in questo [gist] (https://gist.github.com/clintcparker/ee92d2e6faa45614e2c41afbd33884ed). – clintcparker

Problemi correlati