TFS client C# API - get all changesets of an Item - c#

Microsoft TFS client for VS 2010:
http://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.versioncontrol.client.item(v=vs.100).aspx
I (i.e., my code) have a Changeset.
I iterate to a particular Change.
I have an Item in the Change.
Now, I wish to get all Changesets that had Changes for that item.
Could someone advise me the best way to do that?
I could iterate thro all the Changesets of the branch concerned, which would be very inefficient.

Edward is correct. And he has the credentials to back it up. (See his profile description)
VersionControlServer.QueryHistory is the method you need to use. There are several ways to use it and I'm only describing one below which assumes that the server path of that item is what is important to you...
First, you need the server path of the Item:
string serverPath = Item.ServerItem;
Next, if you don't already have a VersionControlServer object instantiated, you can get one from your TeamProject like this:
VersionControlServer VCServer = (VersionControlServer)this.TeamProject.Store.TeamProjectCollection.GetService(typeof(VersionControlServer));
Use the VersionControlServer QueryHistory(string, boolean) method to get other changesets associated with that server path:
VCServer.QueryHistory(serverPath, false);

Related

Get a list of branches of a TFS workspace programmatically

I want to retrieve a list of all branches of a TFS workspace which are mapped locally. I already got a solution where I retrieve all branches of a VersionControlServer-Object, but that`s not what I want to get here. It should be a list specific for my workspace.
var branchObjects = m_VersionControlServer.QueryRootBranchObjects(RecursionType.Full);
List<string> branches = new List<string>();
foreach (var branch in branchObjects)
{
var branchName = branch.Properties.RootItem.Item;
branches.Add(branchName);
}
Do u got any ideas how to check which of the branches where mapped at the local workspace? An instance of the specific workspace-class is available.
You can achieve this with the TFS tf command line tool
tf workspaces /owner:* /computer:* /collection:https://tfs.yourdomain.com/DefaultCollection /format:xml
If you don't have tf.exe, refer to this page How to get tf.exe (TFS command line client)?
Assuming you know the local path of your workspace you can use:
var workspace = versionControlServer.TryGetWorkspace(...path...)
Or you can use the Workstation class to query local workspaces on your machine.
Then from the workspace you can get the workspaces from the QueryWorkspaceInfo method and from there the mappings WorkspaceInfo.Mappings property. And from there you can check whether your branchroots (which you've already got figured out) are mapped in any of the workspaces on the server. If you want to be able to look up server path, you'll need to call the WorkspacnInfo.GetWorkspace method and from there use the Workspace.Folders property.

How to get a list of remote changes from fetch using LibGit2Sharp

I am able to successfully fetch, pull, push, etc. using LibGit2Sharp, but I would like to be able to list files that have changed, added, etc. after doing a fetch. I'm using https://github.com/libgit2/libgit2sharp/wiki/git-fetch and no errors or exceptions occur and logMessage is an empty string.
I would like to be able to show a list of changes like Visual Studio does when you perform a fetch.
How can I use LibGit2Sharp to accomplish this?
Edit:
I have read through the LibGit2Sharp Wiki and the LibGit2Sharp Hitchhiker's Guide to Git. While I have tried some of the available commands to review what results they offer, I am not sure what the equivalent git command would be for this either. It would be helpful to know and understand which command would provide this information and would be appreciated if you are familiar with Git, but not LibGit2Sharp.
Once the fetch is done, you can list the fetched commit of a given branch with
git log ..#{u}
with #{u} designating the branch you are merging from (the upstream remote tracking branch, generally origin/yourbranch)
In LibGitSharp, that is what LibGit2Sharp/BranchUpdater.cs#UpstreamBranch reference (the upstream branch)
With that, you should be able to list the commmits between your current branch HEAD and "UpstreamBranch", a bit like in issue 1161, but that issue was listing what is being pushed: let's invert the log parameters here.
var trackingBranch = repo.Head.TrackedBranch;
var log = repo.Commits.QueryBy(new CommitFilter
{ IncludeReachableFrom = trackingBranch.Tip.Id, ExcludeReachableFrom = repo.Head.Tip.Id });
var count = log.Count();//Counts the number of log entries
//iterate the commits that represent the difference between your last
//push to the remote branch and latest commits
foreach (var commit in log)
{
Console.WriteLine(commit.Message);
}

Dynamic Workspace.Merge TFS changesets

I'm writing a TFS plugin to automate merging of changesets related to a work item whenever said work item is changed from state "Resolved" to state "Closed". The following code is what I have so far:
C#
private void Action_ResolvedToClosed()
{
//Linq query for getting changesets associated with the current work item
var changeSets = WorkItem.Links
.OfType<ExternalLink>()
.Select(link =>
VersionControlServer.ArtifactProvider.GetChangeset(new Uri(link.LinkedArtifactUri))).ToList();
if (!changeSets.Any())
{
LOG_NOCHANGESETS(WorkItem.Id);
return;
}
Workspace workspace = VersionControlServer.GetWorkspace(<My Workspace>);
var source = URI_LOCAL; // $/<Project Name>/<Working Branch>
var destination = URI_DEV; // $/<Project Name>/<Development Branch>
// Merge applicable changesets
foreach (var versionSpec in changeSets.Select(changeset => new ChangesetVersionSpec(changeset.ChangesetId)))
{
workspace.Merge(source, destination, versionSpec, versionSpec);
workspace.CheckIn(workspace.GetPendingChanges(), "**Automated Merge**");
LOG_SUCCESS(versionSpec.ChangesetId, WorkItem.Id);
}
}
Is there a way to dynamically generate the workspace variable? Odds are I won't be the one actually making changes - the goal is to automate this process for our devs.
UPDATE: I'm pretty sure what I'm looking for in this second part is GetStatus, so it can be ignored. The paragraph above is my real question.
Secondary: I feel like automating merges can't be this simple. What happens if merge conflicts arise? Does Workspace.Merge fail gracefully? Are there any other glaring issues that someone with a bit more experience with the TFS API can point out?
First, it sounds like you want to query the user's workspace cache to get the appropriate Workspace and "realize" it. If
WorkspaceInfo workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(path);
Workspace workspace = workspaceInfo.GetWorkspace(new TfsTeamProjectCollection(workspaceInfo.ServerUri);
However, as you point out, you may prefer to create a temporary workspace. This will ensure that you do not conflict with any changes the user is trying to make in their own workspace. For example:
TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(new Uri("http://server:8080/tfs/DefaultCollection"));
VersionControlServer vcs = tpc.GetService<VersionControlServer>();
Workspace workspace = vcs.CreateWorkspace("MERGE-TEMP");
workspace.Map("$/Merge-Source", #"C:\Temp\Merge\Source");
workspace.Map("$/Merge-Target", #"C:\Temp\Merge\Target");
Second, if you run into merge conflicts, they will be set in the workspace. You can query the NumConflicts method of the returned GetStatus. (Though you will not be able to Checkin untli you have resolved the conflicts.

How to get the full folder history from TFS programmatically?

I have a folder under TFS source control system, let's say under "$/My Project/Branches/Dev" path.
It was just recently moved from another location, which was "$/My Project/Dev".
Now when I request its history from the Source Control Explorer in VS I get the full history, where the described move operation was just one of the changesets.
But when I try to get the history using TFS SDK I only get the recent history started with the move of the folder. How can I get the full history?
I'm using the following code:
TeamFoundationServer tfs = TeamFoundationServerFactory.GetServer(tfsServerURL);
VersionControlServer vcs = (VersionControlServer)tfs.GetService(typeof(VersionControlServer));
// Null means All
VersionSpec versionFrom = null;
System.Collections.IEnumerable enumerable = vcs.QueryHistory(_tfsPath,
VersionSpec.Latest,
0,
RecursionType.Full,
"",
versionFrom,
VersionSpec.Latest,
Int32.MaxValue,
true,
true);
You are passing slotMode = true. Change the final parameter to false.
"Slot mode" means "query by path, not by history." It's useful if you only remember the old name of an item but not where you moved it to, or if >1 item has occupied a given path.
For future reference, if you want to see what parameters VS (or tf.exe) is passing to the server so you can mimic them, turn on tracing.

How to list files of a team project using tfs api?

I am wondering if there is a way for me to list all 'files' containted in a tfs team project. What I am aiming to do is search for files of a particular name that dont have fixed paths within TFS caused by branching ($/MyTeamProject/Main/Build/instruction.xml and $/MyTeamProject/Branches/Release_1.0). Once a file would be found I would like to manipulate it.
I guess that we are talking items when it comes to entities containted within a team project and not traditional files and therefore this might be a bit tricky?
I have seen some samples for manipulating a file but all samples so far have fixed paths.
This is not a different answer, but simply an upgrade of Vengafoo's code. The TeamFoundationServer class is obsolete in 2011 (not sure when this happened, I just know it is obsolete as of now). Vengafoo's code is from 2009, so that makes sense. Use the TfsTeamProjectCollection class with the TfsTeamProjectCollectionFactory factory class instead.
Here is the upgrade, just one line of change:
//TeamFoundationServer server = new TeamFoundationServer("server");
TfsTeamProjectCollection server = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("http://tfsServerURI:8080/tfs/"));
VersionControlServer version = server.GetService(typeof(VersionControlServer)) as VersionControlServer;
ItemSet items = version.GetItems(#"$\ProjectName", RecursionType.Full);
//ItemSet items = version.GetItems(#"$\ProjectName\FileName.cs", RecursionType.Full);
foreach (Item item in items.Items)
{
System.Console.WriteLine(item.ServerItem);
}
Here is how I've figured out how to list all the files of a TFS Project:
Add Microsoft.TeamFoundation.Client and Microsoft.TeamFoundation.VersionControl.Client as a reference to your project.
Add a using for Microsoft.TeamFoundation.Client and Microsoft.TeamFoundation.VersionControl.Client
TeamFoundationServer server = new TeamFoundationServer("server");
VersionControlServer version = server.GetService(typeof(VersionControlServer)) as VersionControlServer;
ItemSet items = version.GetItems(#"$\ProjectName", RecursionType.Full);
ItemSet items = version.GetItems(#"$\ProjectName\FileName.cs", RecursionType.Full);
foreach (Item item in items.Items)
{
System.Console.WriteLine(item.ServerItem);
}
The second GetItems will restrict the items found to those of a specific filename. I just have this sample outputting the server path for all of the files found.

Categories