删除TFS 2010中的分支关系

时间:2012-01-09 12:50:13

标签: tfs tfs2010 branching-and-merging

我有一个TFS 2010团队项目,我刚刚接手。分支层次结构是Dev是Test的子项,Test是Main的子项。

Main

----Test

--------Dev

然而,在过去的某些时候,有人在Dev和Main之间进行了毫无根据的合并。这引起了很大的混乱,因为开发人员现在意外地将代码直接从Dev合并到Main。

当代码遵循正确的进程并从Test合并到Main时,这会导致无法预料的合并冲突,并且可能会创建一个将未经测试的代码提升为Main分支的场景。

有没有办法在不删除分支的情况下删除Dev和Main之间的分支关系?我想保留Dev分支及其与Test的关系。只需删除与Main的关系。

我尝试将分支转换为文件夹以删除关系,但这不起作用。我可以重新表达分支,但似乎没有任何明显的方法可以完全消除这种关系。我可以将分支转换为文件夹,然后删除它并从Test重新分配,但这将意味着确保代码库是同步的,这可能很难实现。

2 个答案:

答案 0 :(得分:5)

TFS不一定构建基于分支对象的合并候选者以实现向后兼容性(分支对象在TFS 2010中是新的)并支持无基础合并(一旦在两个路径之间执行无基本合并,这些将与合并一起存储未来合并的关系。)

我建议在这里使用自定义签到策略,强制合并来自Dev - >测试或测试 - >开发并且不要跳过中级。这也允许您将Dev保留为分支对象,因此您仍然可以获得分支可视化等所有不错的功能。

我可以提供一个非常粗略,非常伪代码的例子,说明我的想法。 (这很粗糙,因为我很懒,因为我把时间花在了Java SDK而不是.NET SDK上,我意识到大多数人都想要一个.NET签到策略。但主要是因为我很懒。)< / p>

/*
 * 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;
}

当然,这有几个问题。您当然不希望将可接受的合并关系列表硬编码到策略中 - 您可以将其外部化为配置文件,或者您可以查询服务器上的合并关系并缓存它们,如果您有特定规则,例如只有直接后代才能合并。 (缓存这一点很重要,因为签入策略评估经常运行并且预计会很快。它甚至可能偶尔在UI线程上运行(虽然我对此表示怀疑),因此您的里程可能会有所不同。)

另外,我的路径测试代码非常草率,主要是为了在评论中节省一些空间。 (还有,我前面提到的懒惰。)

我希望这是一个好的开始。

答案 1 :(得分:0)

很棒的问题!我没有直接答案,但我建议降低未来发生的风险:

严格限制谁有权合并到父母分支,特别是主分支。我指定一个Dev Lead或Sr. Dev作为分支所有者,负责RI合并到该分支。 (管理员也可以在不需要额外权限的情况下进行覆盖。)

一旦无基础合并创建新关系,这对您没有帮助,但它应该可以降低将来意外再次发生的风险。可能还有一个有效的案例,即跳过你的测试分支是必要的,但我想不出这样做的任何好理由。