2

I am using the TFS API to get latest code files, directories, .csproj files, etc. under a TFS-bound folder.

For the same, I use something like the following:

var tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(ConfigurationManager.AppSettings["TFSUrl"])); tfs.EnsureAuthenticated(); var vsStore = tfs.GetService<VersionControlServer>(); string workingFolder = @"C:\TFS\SolutionFolder"; Workspace wsp = vsStore.TryGetWorkspace(workingFolder); if (wsp != null) { ItemSet items = vsStore.GetItems(workingFolder, VersionSpec.Latest, RecursionType.Full); string relativePath = workingFolder + @"/"; foreach (Item item in items.Items) { string relativePath1 = item.ServerItem.Replace("$/TFS/SolutionFolder", relativePath); if (item.ItemType == ItemType.Folder) { Directory.CreateDirectory(relativePath1); } else { item.DownloadFile(relativePath1); } } } 

Now, I get the items to download and then download happens. However, I want it to be like how VS handles it - if (and only if) there is a change in a file/folder, then only download the same. With this code, I always get 'n' number of files/folders in that folder and then I overwrite the same. Wrong approach, I know. I can, however, modify this code to check for the folder's or file's last change time and then choose to either overwrite it or ignore it. That's an option, albeit a bad one at that.

Now, what I would ideally like is to get ONLY the list of files/folders that actually need to be changed i.e. the incremental change. After that, I can choose to overwrite/ignore each item in that list. So, in the present case, if a new file/folder is created (or one of the existing ones got changed inside $/TFS/SolutionFolder i.e. in the sever), then only I want to pull that item in the list of files/folders to change(and decide what I want to do with it inside C:\TFS\SolutionFolder).

Also, is using one of the overloads of VersionControlServer.QueryHistory() an option? I had something like this:

(latestVersionIdOf $/TFS/SolutionFolder) - (existingVersionIdOf C:\TFS\SolutionFolder) = (Versions that I'd go out and get back from the server, for that folder) 

in mind.

Any pointers will be very helpful. Thanks!

2
  • Why not use vsStore.Get() method to get the files into the workspace? It will just get the files that out of date. Commented Jun 30, 2017 at 2:34
  • Thanks, Eddie! I will check this approach. Also, I just posted an updated answer with what I have at present. Let me know what you think about. Cheers! Commented Jun 30, 2017 at 18:52

3 Answers 3

2

Just use Workspace.Get() or overload method (wsp.Get()), it just update updated files.

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks, Starain! I tried the default version of Workspace.Get() and it took ages to complete so I stopped it mid-way. Do you have anything specific in mind? Also, I posted an updated approach. Please let me know what you think of it and how to better it, if possible.
@NabakamalDas How much time it takes? What's the result if you get part of files? wsp.Get(new string[] { "$/ScrumStarain/CustomCode/Properties" }, VersionSpec.Latest, RecursionType.Full, GetOptions.None); On the other hand, do you use Microsoft Team Foundation Server Extended Client package.
Let me give this one a shot. So, let's say I have a 1000 files under a folder, the Get() call always tries 'downloading' this 1000 files every single time. Like you indicated here, I guess a if I pass the names of the files in the first argument then I can avoid doing the 'all' option. I haven't tried all the options from the GetOptions but I guess I should gun for that now. Thoughts? Maybe the Remap option is the one for me..I gotta give this one a better look.
Ok. So, I tried wsp.Get(new string[] { "$/TFS/FolderX/item.cs" }, VersionSpec.Latest, RecursionType.Full, GetOptions.None); and I still see that the file gets "checked-out" :(
@NabakamalDas How do you know that file gets "checked-out"? On the other hand, you also can specify the path directly, such as $/TFS/FolderX
|
0

I don't think we can achieve that. If the files are downloaded to a folder without in source control, there are no versions compared within the folder, even if the folder is in source control, the behavior is just download also no version compare actions. So, it will download all the files ever time and then overwrite the same ones.

In VS, the files are all in TFS source control system, so when we Get Latest Version the changed/added files will be retrieved from TFS. If you want to get the same behavior as VS handles, you can use the tf get command. See Get Command

You can reference this article to use the tf get command : get-latest-version-of-specific-files-with-tfs-power-tools

2 Comments

Thanks, Andy! I am trying to use wsp.GetExtendedItems() and filtering each item in that list based on the VersionLatest and VersionLocal. I think with a few tweaks I should be able to get something working. Thanks, again!
Sure thing! I will post an update soon ( along with the other problem(s) that I see with that solution). Thanks!
0

Update :-

var tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(ConfigurationManager.AppSettings["TFSUrl"])); tfs.EnsureAuthenticated(); var vsStore = tfs.GetService<VersionControlServer>(); string workingFolder = ConfigurationManager.AppSettings["LocalPathToFolder"]; // C:\TFS\SolutionFolder string tfsPathToFolder = ConfigurationManager.AppSettings["TFSPathToFolder"]; // $/TFS/SolutionFolder Workspace wsp = vsStore.GetWorkspace(workingFolder); if (wsp != null) { ItemSpec[] specs = { new ItemSpec(tfsPathToFolder, RecursionType.Full) }; ExtendedItem[][] extendedItems = wsp.GetExtendedItems(specs, DeletedState.NonDeleted, ItemType.Any); ExtendedItem[] extendedItem = extendedItems[0]; var itemsToDownload = extendedItem.Where(itemToDownload => itemToDownload.IsLatest == false); foreach (var itemToDownload in itemsToDownload) { try { switch (itemToDownload.ItemType) { case ItemType.File: if (itemToDownload.LocalItem != null) { vsStore.DownloadFile(itemToDownload.SourceServerItem, itemToDownload.LocalItem); } else { string localItemPath = itemToDownload.SourceServerItem.Replace(tfsPathToFolder, workingFolder); vsStore.DownloadFile(itemToDownload.SourceServerItem, localItemPath); } break; case ItemType.Folder: string folderName = itemToDownload.SourceServerItem.Replace(tfsPathToFolder, workingFolder); if ((!string.IsNullOrEmpty(folderName)) && (!Directory.Exists(folderName))) { Directory.CreateDirectory(folderName); } break; } } catch (Exception e) { File.AppendAllText(@"C:\TempLocation\GetLatestExceptions.txt", e.Message); } } } 

This code works well, except:

a. Whenever it downloads the latest copy of, let's say a file, it 'checks it out' in TFS :(

b. For some items, it throws errors like 'Item $/TFS/SolutionFolder/FolderX/abc.cs was not found in source control at version T.' - I have to find out what the exact cause of this issue is, though.

Any ideas on how to get around these two issues or any other problems you see with this code? Thanks!

2 Comments

a. it replaces the files (similar to paste a file), so state will be checked out. b. Are these files updated? Do you always get the errors?
Thanks, Starain! Yes, it replaces the content of the file and hence checks it out. I have the 'checks out' thing always but I only saw the second error a couple of days ago...guess its a very specific error.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.