Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find the tfs path of merged branch

Using TFS, I have trunk $/project/trunk and a branch $/project/dev/feature/new_one.

I have merged my branch back to trunk as follows:

C33($/project/trunk)
|  \
|   \
|    C32($/project/dev/feature/new_one)
|     |
|     |
|     |
...

I use the TFS API and can find the merge changeset C33. With the method QueryMerges(), I'm able to find the parent changeset C32 with all the changes on the files, but not the information I need :(

Is there a way, using the TFS API, to find the repository path of the branch merged $/project/dev/feature/new_one?

With the changeset C32, I'm only able to get paths of modified files, like $/project/dev/feature/new_one/path/to/file.txt but I'm unable to extract the path of the branch from the full path of the file :(

PS : A solution working since TFS2008 will be the best, but if it works only since 2010, it should be good...

PS2 : solving this problem will help to manage merge changesets in git-tfs which I develop...

like image 599
Philippe Avatar asked May 28 '13 10:05

Philippe


1 Answers

Unfortunately there is no API method to get a branch for a given item path, which you would think is a fairly common use case.

TFS 2010 onwards you can use VersionControlServer.QueryRootBranchObjects to query all branches in version control. Using RecursionType.Full as the parameter to this method you will get a BranchObject array of all branches with no parent and all of their descendents. You can then determine a branch for a given file path as follows:

var collection = new TfsTeamProjectCollection(new Uri("http://tfsuri"));
var versionControl = collection.GetService<VersionControlServer>();

var branchObjects = versionControl.QueryRootBranchObjects(RecursionType.Full);

var mergeFilePath = "$/project/dev/feature/new_one/path/to/file.txt";
var branch = branchObjects.SingleOrDefault(b => {
            var branchPath = b.Properties.RootItem.Item;
            return mergeFilePath.StartsWith(branchPath.EndsWith("/") ? branchPath : branchPath + "/");
        });

Console.WriteLine(branch.Properties.RootItem.Item);

As shown, the path to the branch is at BranchObject.Properties.RootItem.Item. I believe it is safe to find the relevant BranchObject in the array simply by checking which branch's path is contained in the merge file's path (given it is only possible match at most one branch as TFS enforces that only one branch can exist in a given folder hierarchy).

Just to be aware, I have been burned by this Connect issue when using QueryRootBranchObjects in TFS 2012. The cause were some spurious branches that had apostrophes in the branch name.

The workaround to this is to use VersionControlServer.QueryBranchObjects, however this takes an item identifier which is the exact path to the branch. Clearly you don't know the branch path at this point as all you have is a file path, so you have to recurse up the directories of the file path calling QueryBranchObjects each time until you get a match.

like image 98
Pero P. Avatar answered Sep 21 '22 16:09

Pero P.