Team Foundation Server - 使用历史记录移动源

Jos*_*ris 57 version-control tfs

我想知道将源代码从历史记录中移动到一个团队项目到另一个团队项目的最佳方法是什么.我不关心工作项,报告或SharePoint站点,因为我们要恢复的系统没有使用这些功能.想要转移到另一个团队项目的原因还在于原始实现(从第三方维护的备份恢复)使用我们不希望使用的第三方流程模板往前走.我们希望在迁移完成后开始使用工作项跟踪和报告.

TFS集成平台似乎是一个可能的方案.根据文档,它可用于更改流程模板.但是,如果tf.exe移动语法可能有效,我很好奇吗?就像是:

tf.exe移动$/ProjectA $/ProjectB

我的理解是这个命令的操作很像重命名操作,而在Source Control Explorer中使用"Move"上下文菜单项移动更像是删除和添加操作.此外,tf.exe移动路径是否会将文件夹下的代码与相应的Team Project相关联,假设$/ProjectA是一个项目的根源控制文件夹,而$/ProjectB是另一个项目的根源控制文件夹?关键是如果可能的话,能够保存历史.

任何建议或提示将不胜感激!

编辑 - 可以分支到另一个项目来处理这种情况 - 就像微软在分支指导文档中讨论的那样?我认为这可能是答案,因为历史可能会被分支机构保留下来.但是,我目前无法访问Team Foundation Server 2008实例来测试它.

Ric*_*erg 38

移动和重命名是别名.在任何版本的TFS中,命令行或UI都没有任何区别.

他们都保留了历史.至少在2005/2008中,无论名称和/或父路径发生变化的频率或频率如何,都会在VersionedItem表中保留相同的物理项.实际上没有办法在没有大量手动工作的情况下进行"假"重命名(删除+添加).

然而,虽然这个版本控制模型在理论意义上非常纯粹,但它有一些实际的问题.由于不同的项目可能在不同的时间点占用相同的名称,因此TFS需要全名+版本来唯一标识您发送的任何输入.通常你没有注意到这个限制,但是一旦你在系统中重命名了项目,如果你说tf [doSomething] $/newname -version:oldversion那么它会混淆并抛出错误或操作你可能的项目没有意图.您必须小心传递有效组合(newname + newversion或oldname + oldversion)以确保命令按您希望的方式运行.

TFS 2010在某种程度上改变了故事:它是一个分支+删除的封面,导致itemID发生变化.即便如此,像Get和History这样的日常命令也很"伪造"; 老客户约95%兼容.优点是,当您在系统中有多个重命名并且基于路径的项目查找开始变得模棱两可时,如上所述,服务器将只接受您指定的名称并使用它运行.这提高了整体系统性能,并消除了不熟悉的用户经常陷入的几个陷阱,代价是不够灵活,不能保持100%精度的历史记录(例如,在两个分支的合并期间存在名称冲突时).

回到手头的问题......

这并不像说重命名$/projectA $/projectB那么简单.源代码管理树中的顶级文件夹是为团队项目创建向导保留的; 你不能对它们运行标准的tf命令.你需要的是一个脚本,如:

Get-TfsChildItem $/ProjectA |
    select -Skip 1 |  # skip the root dir
    foreach {
        tf rename $_.serveritem $_.serveritem.replace("$/ProjectA", "$/ProjectB")
    }
Run Code Online (Sandbox Code Playgroud)

[当然,如果$/ProjectA下没有太多孩子,你可以手工完成]

至于我提到的陷阱,我现在会详细说明,因为查找旧的历史对你来说非常重要.一旦你检查了重命名,tf history $/ProjectA/somefile.cs将不起作用.默认情况下,tf命令假定version ="latest".任何这些替代方案都将是您想要的完整历史:

  • tf history $/ProjectA/somefile.cs; 1234其中changeset 1234在移动之前
  • tf history $/ProjectB/somefile.cs; 5678其中changeset 5678在移动之后.或者你可以省略版本.

完整性和调试目的的最终替代方案:

  • tf history $/ProjectA/somefile.cs -slotmode.您只会看到移动前发生的变化; 但是你也会看到你在B下面移动的项目之前或之后可能存在于$/ProjectA/somefile.cs"slot"中的任何其他项目的历史记录.

(在TFS 2010中,"插槽模式"是默认行为;有一个-ItemMode选项可以请求在历史记录中跟踪查找,就像2008年而不是基于路径一样.)

编辑 - 不,分支不是一个很好的选择.虽然分支确实在系统中留下了足够的元数据来跟踪ProjectB的完整历史记录,但它在2008年并不是非常用户友好.计划花费大量时间学习tf merges命令(没有UI等价).2010年大大提高了您在多个分支机构中可视化变更的能力,但它仍然不是您从重命名中获得的干净统一体验.

  • 如果在移动后删除ProjectA,那么转移到ProjectB的任何历史记录也不会从ProjectB上移动的项目中消失吗? (2认同)

sol*_*ish 17

理查德在上面的答案写得很好并且很好地解释了这种情况.不过,我确实有一些更实际的问题需要补充.

在TFS2010中,默认行为使得看起来像移动文件会导致您在移动之前丢失所有历史记录.我的用户可能会使用的命令(以及VS2010 GUI使用的命令)是:

tf history $/ProjectB/somefile.cs
Run Code Online (Sandbox Code Playgroud)

我的用户打算在移动之前和之后获得somefile.cs的所有历史记录.他们想要"当前存储在$/ProjectB/somefile.cs中的代码的历史记录",而不管任何时间点的文件名.也许其他人看到的方式不同.

第一个问题是,使用TFS2010在VS2010中为我显示的GUI最初只显示移动后的历史记录.列表中最近的项是重命名操作.它可以通过微妙的小下拉箭头进行扩展.下面是以前位置的历史记录.如果你不知道要找这个,看起来你的历史就不见了.

第二个问题是如果你以后删除了ProjectA(因为你已经完成了向ProjectB的迁移,比如说),那么历史真的已经消失了.扩展$/ProjectB/somefile.cs历史记录中的下拉列表不会产生较旧的历史记录.

  • 感谢您指出删除"ProjectA"的危险以及它如何影响视觉历史. (3认同)