-1

Lets say the following is my TFS structure:

  • Branches (Folder)
    • Module1 (Folder)
      • Branch1 (Branch with parent Dev)
      • Branch2 (Branch with parent Branch1)
      • Branch3 (Branch with parent Branch1)
  • Dev (Branch)

In code, I have access to my local workspace, as well as a VersionControlServer object.

I want a method such as string GetParentPath(string path) that would act like the following:

GetParentPath("$/Branches/Module1/Branch1"); // $/Dev
GetParentPath("$/Branches/Module1/Branch2"); // $/Branches/Module1/Branch1
GetParentPath("$/Branches/Module1/Branch3"); // $/Branches/Module1/Branch1
GetParentPath("$/Dev"); // throws an exception since there is no parent

I currently have the following, thought it worked, but it doesn't (and I didn't honestly expect it to work either)

private string GetParentPath(string path)
{
    return versionControlServer.QueryMergeRelationships(path)?.LastOrDefault()?.Item;
}

2 Answers2

2

You can get all branch hierarchies (Parent/Child) using below code: (Install the Nuget package Microsoft.TeamFoundationServer.ExtendedClient)

using System;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;

namespace DisplayAllBranches
{
    class Program
    {
        static void Main(string[] args)
        {
            string serverName = @"http://ictfs2015:8080/tfs/DefaultCollection";

            //1.Construct the server object
            TfsTeamProjectCollection tfs = new TfsTeamProjectCollection(new Uri(serverName));
            VersionControlServer vcs = tfs.GetService<VersionControlServer>();

            //2.Query all root branches
            BranchObject[] bos = vcs.QueryRootBranchObjects(RecursionType.OneLevel);

            //3.Display all the root branches
            Array.ForEach(bos, (bo) => DisplayAllBranches(bo, vcs));
            Console.ReadKey();
        }

        private static void DisplayAllBranches(BranchObject bo, VersionControlServer vcs)
        {
            //0.Prepare display indentation
            for (int tabcounter = 0; tabcounter < recursionlevel; tabcounter++)
                Console.Write("\t");

            //1.Display the current branch
            Console.WriteLine(string.Format("{0}", bo.Properties.RootItem.Item));

            //2.Query all child branches (one level deep)
            BranchObject[] childBos = vcs.QueryBranchObjects(bo.Properties.RootItem, RecursionType.OneLevel);

            //3.Display all children recursively
            recursionlevel++;
            foreach (BranchObject child in childBos)
            {
                if (child.Properties.RootItem.Item == bo.Properties.RootItem.Item)
                    continue;

                DisplayAllBranches(child, vcs);
            }
            recursionlevel--;
        }

        private static int recursionlevel = 0;
    }
}

enter image description here

Andy Li-MSFT
  • 28,712
  • 2
  • 33
  • 55
  • However, I don't really care about the children, I ONLY care about the parent, the direct parent. Also, querying every path on our server is not an option due to the number of branches we have. – Nick Sosinski Aug 03 '18 at 10:21
  • I guess what I **could** do would be do as I did before (`QueryMergeRelationships`) and use `QueryBranchObjects` on all of those paths to find which one contains my path, but that seems like a very roundabout way of solving this issue. I'm just surprised there isn't a method built in that tells me who my parent for a branch is. – Nick Sosinski Aug 03 '18 at 10:29
1

Figured it out (Thanks to Andy Li-MSFT for poking my brain with the BranchObject class):

string GetParentPath(string path)
{
    BranchObject branchObject = versionControlServer.QueryBranchObjects(new ItemIdentifier(path), RecursionType.None).Single();
    if (branchObject.Properties.ParentBranch != null)
        return branchObject.Properties.ParentBranch.Item;
    else
        throw new Exception($"Branch '{path}' does not have a parent");
}

In addition, if you want to get the parent branch of a file/folder located within that branch, you could use the following code to get that functionality:

private string GetParentPath(string path)
{
    string modifyingPath = path;
    BranchObject branchObject = versionControlServer.QueryBranchObjects(new ItemIdentifier(modifyingPath), RecursionType.None).FirstOrDefault();
    while (branchObject == null && !string.IsNullOrWhiteSpace(modifyingPath))
    {
        modifyingPath = modifyingPath.Substring(0, modifyingPath.LastIndexOf("/"));
        branchObject = versionControlServer.QueryBranchObjects(new ItemIdentifier(modifyingPath), RecursionType.None).FirstOrDefault();
    }

    string root = branchObject?.Properties?.ParentBranch?.Item;
    return root == null ? null : $"{root}{path.Replace(modifyingPath, "")}";
}
  • Well, since the issue was resolved, you could [Accept it as an Answer](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work), This can be beneficial to other community members reading this thread. – Andy Li-MSFT Aug 04 '18 at 03:13
  • Has to be 24 hours before you can mark it as the answer – Nick Sosinski Aug 05 '18 at 07:56