Remove a Branching Relationship in TFS 2010

不问归期 提交于 2019-11-30 18:37:41

TFS doesn't necessarily build merge candidates based on branch objects for backwards compatibility (branch objects were new in TFS 2010) and to support baseless merges (once you perform a baseless merge between two paths, those will be stored with a merge relationship for future merges.)

I'd suggest using a custom check-in policy here that enforces that merges go from Dev -> Test or Test -> Dev and don't skip the intermediate level. This also allows you to keep Dev as a branch object, so you'll still get all the nice features like branch visualization.

I can provide a very rough, very pseudo-codey example of what I had in mind. (It's rough both because I'm lazy and because I spend my time in the Java SDK and not the .NET SDK and I realize that most people want a .NET check-in policy. But mostly because I'm lazy.)

/*
 * Create a dictionary of merge targets to allowable merge sources.
 * For an item in this list, the allowable merge sources are a whitelist.
 */
private readonly Dictionary<String, List<String>> restrictedMergeTargets =
    new Dictionary<String, List<String>>();

public static MergeWhitelistPolicy
{
    /* Only allowed merges to $/Main from $/Test. */
    List<String> mainWhitelist = new List<String>();
    mainWhitelist.add("$/Test");
    allowedMerges.put("$/Main", mainWhitelist);

    /* Only allow merges to $/Test from $/Dev. */
    List<String> testWhitelist = new List<String>();
    testWhitelist.add("$/Dev");
    allowedMerges.put("$/Test", testWhitelist);
}

public PolicyFailure[] evaluate(PolicyContext context)
{
    PendingChange[] pendingChanges = GetPendingCheckin().GetCheckedPendingChanges();

    foreach(PendingChange change : pendingChanges)
    {
        if(! change.IsMerge())
        {
            continue;
        }

        foreach(KeyValuePair<String, List<String>> restrictedTarget : restrictedMergeTargets)
        {
            if(VersionControlPath.IsChild(restrictedTarget.GetKey(), change.GetServerItem())
            {
                /* Whitelisted merge path - investigate. */
                foreach(String allowedSource : restrictedTarget.GetValue())
                {
                    foreach(MergeSource mergeSource : change.GetMergeSources())
                    {
                        if(! VersionControlPath.IsChild(allowedSource, mergeSource.GetServerItem()))
                        {
                            return new PolicyFailure("Merge from " +
                                mergeSource.GetServerItem() + " to " +
                                change.GetServerItem() + " is disallowed.");
                        }
                    }
                }
            }
        }
    }

    return null;
}

There are several issues with this, of course. You certainly wouldn't want to hardcode the list of acceptable merge relationships into the policy - you could externalize it into a configuration file, or you could query the merge relationships on the server and cache them if you had particular rules like only direct descendants can merge. (Caching this is important as check-in policy evaluation runs frequently and is expected to be fast. It may even run on the UI thread occasionally (though I doubt it), so your mileage may vary.)

Also, my path testing code is pretty sloppy, mostly just to save some space in my comment. (And also, the aforementioned laziness on my part.)

I hope this is a good start.

Excellent question! I don't have the direct answer but I have suggestion to reduce risk of future occurrences:

Severely restrict who has rights to merge to parent branches, especially to the Main branch. I designate one Dev Lead or Sr. Dev as a branch owner who is responsible for RI merges to that branch. (Admins can also cover without needing extra privileges.)

This doesn't help you once the baseless merge creates a new relationship, but it should reduce the risk of unintended recurrence in the future. There might also be a valid case where jumping your Test branch would be necessary, but I can't think of any good reason for doing so.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!