删除 TFS 2010 中的分支关系

Posted

技术标签:

【中文标题】删除 TFS 2010 中的分支关系【英文标题】:Remove a Branching Relationship in TFS 2010 【发布时间】:2012-01-09 12:50:13 【问题描述】:

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

Main

----Test

--------Dev

但是在过去的某个时候,有人在 Dev 和 Main 之间进行了毫无根据的合并。这引起了很大的混乱,因为开发人员现在不小心将代码直接从 Dev 合并到 Main。

当代码遵循正确的流程并从 Test 合并到 Main 时,这会导致无法预料的合并冲突的痛苦,并且可能会造成未经测试的代码被提升到 Main 分支的场景。

有没有什么方法可以在不删除分支的情况下,去掉 Dev 和 Main 之间的分支关系?我想保留 Dev 分支及其与 Test 的关系。只需删除与 Main 的关系即可。

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

【问题讨论】:

当您说它不起作用时,您是否收到错误消息?我最近这样做了,它也让我着迷,请参阅此处的“解决方法”-connect.microsoft.com/VisualStudio/feedback/details/503673/…。您可以使用“转换为文件夹”选项,您似乎已经这样做了,所以可能不是那样 - 它对我有用,所以我有兴趣了解发生了什么。 @dash 当我使用“转换为文件夹”时,图标会发生变化,但关系仍然存在。 IE。我仍然可以将文件夹与其父分支合并,合并 UI 仍然显示 2 个关系。我还应该提到,这个团队项目最近从 TFS 2008 升级到了 TFS 2010 【参考方案1】:

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

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

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

/*
 * 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 线程上运行(尽管我对此表示怀疑),因此您的里程可能会有所不同。)

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

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

【讨论】:

谢谢爱德华,我宁愿删除错误的关系,但这是不可能的。我会制定一个签到政策。 Edward,您能否举个例子说明如何创建这样的签到政策? @JohnSaunders:你打赌。它非常非常粗略,但我希望它能解释我的想法。 我即将开始做原作者目前所做的事情,这真的帮助我没有犯大错。谢谢爱德华。【参考方案2】:

很好的问题!我没有直接的答案,但我有减少未来发生风险的建议:

严格限制谁有权合并到父分支,尤其是主分支。我指定一位 Dev Lead 或 Sr. Dev 作为负责 RI 合并到该分支的分支所有者。 (管理员也可以覆盖而不需要额外的权限。)

一旦毫无根据的合并创建了新的关系,这对您没有帮助,但它应该会降低未来意外再次发生的风险。也可能存在需要跳转测试分支的有效案例,但我想不出这样做的任何充分理由。

【讨论】:

感谢 Zephan,我们确实限制了合并访问。问题更多是由于合并对话按字母顺序显示目标分支,开发人员很容易意外合并到主分支。我只是想消除任何愚蠢的错误

以上是关于删除 TFS 2010 中的分支关系的主要内容,如果未能解决你的问题,请参考以下文章

Git删除TFS git存储库中的远程分支

安全删除 TFS 分支项目

如何删除 TFS 组

TFS 获取分支 -> 回滚 -> 向后合并并希望删除所有更改

是否有一种简单的方法可以在一个分支中创建补丁,然后将其应用于 TFS 2010 中的另一个分支?

如何从Visual Studio 2017中的组合框中删除TFS存储库帐户