Team Foundation Server - 移动带有历史记录的源代码 [英] Team Foundation Server - Moving Source with History

查看:20
本文介绍了Team Foundation Server - 移动带有历史记录的源代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

TFS 集成平台 似乎是一种可能的情况.根据文档,它可用于更改流程模板.但是,我很好奇 tf.exe 移动语法是否可行?类似的东西:

tf.exe 移动 $/ProjectA $/ProjectB

据我所知,此命令的操作很像重命名操作,而在源代码管理资源管理器中使用移动"上下文菜单项移动更像是删除和添加操作.此外,假设 $/ProjectA 是一个项目的根源代码管理文件夹,而 $/ProjectB 是另一个项目的根源代码管理文件夹,tf.exe 移动路径实际上是否会将文件夹下的代码与相应的团队项目相关联?如果可能的话,关键是能够保存历史.

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

编辑 - 可以分支到另一个项目来处理这种情况 - 就像微软在 分支指南 文档?我认为这可能是答案,因为历史可能会与分支一起保存.但是,我目前无权访问 Team Foundation Server 2008 实例以对其进行测试.

解决方案

Move 和 Rename 是别名.在任何版本的 TFS 中,无论是命令行还是 UI,都完全没有区别.

它们都保存了历史.至少在 2005/2008 年,无论名称和/或父路径更改的频率和幅度如何,您都在 VersionedItem 表中保留相同的物理项目.如果您不进行大量手动工作,实际上无法获得假"重命名(删除 + 添加).

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

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

回到手头的问题...

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

Get-TfsChildItem $/ProjectA |选择 - 跳过 1 |# 跳过根目录foreach{tf 重命名 $_.serveritem $_.serveritem.replace("$/ProjectA", "$/ProjectB")}

[当然,如果$/ProjectA下的孩子不多的话,你可以自己动手]

至于我提到的问题,我现在将详细说明一个问题,因为查找旧历史对您来说似乎非常重要.一旦您签入重命名,tf history $/ProjectA/somefile.cs 将不起作用.默认情况下,tf 命令假定 version = "latest".这些替代方案中的任何一个都将获得您想要的完整历史记录:

  • tf history $/ProjectA/somefile.cs;1234 移动前变更集 1234 所在的位置
  • tf history $/ProjectB/somefile.cs;5678 移动后变更集 5678 所在的位置.或者您可以省略版本.

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

  • tf 历史记录 $/ProjectA/somefile.cs -slotmode.您只会看到移动之前发生的更改;但是,您还会看到在您移动到 ​​B 下方的项目之前或之后可能存在于 $/ProjectA/somefile.cs槽"中的任何其他项目的历史记录.

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

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

I was wondering what the best approach might be in moving source code, with history, from one Team Project to another Team Project. I am not concerned with work items, reporting, or SharePoint sites, as the system we are going to be restoring from did not use these functionalities. The reason for wanting to move to a different Team Project also is driven by the fact that the original implementation (being restored from a backup that was maintained by a third party) were using a third-party process template that we do not wish to use going forward. We want to start utilizing work item tracking and reporting after the migration is complete.

The TFS Integration Platform seems to be one likely scenario. It can be used to change the process template, according to the documentation. However, I was curious if the tf.exe move syntax might work? Something like:

tf.exe move $/ProjectA $/ProjectB

It is my understanding that this command operates much like a rename operation, whereas moving with the "Move" context menu item in Source Control Explorer is more like a delete and add operation. Also, would the tf.exe move path actually associate the code under the folders with the appropriate Team Project, assuming that $/ProjectA is the root source control folder for one project and $/ProjectB is the root source control folder for the other? The key is to be able to preserve the history, if possible.

Any advice or tips would be greatly appreciated!

Edit - Could branching to another project handle this scenario - much like Microsoft discusses in the Branching Guidance documentation? I think that this could be the answer, since the history would likely be preserved with the branch. However, I do not have access to a Team Foundation Server 2008 instance at the moment to test it.

解决方案

Move and Rename are aliases. There is absolutely no difference, in any version of TFS, from the command line or the UI.

Both of them preserve history. At least in 2005/2008, you keep the same physical item in the VersionedItem table no matter how often or how drastically the name and/or parent path changes. There is actually no way to get a "fake" rename (delete + add) without a lot of manual work on your part.

However, while this versioning model is very pure in a theoretical sense, it has some practical gotchas. Because different items can occupy the same name at different points in time, TFS needs the full name + version to uniquely identify any inputs you send it. Normally you don't notice this restriction, but once have you renamed items in the system, if you say tf [doSomething] $/newname -version:oldversion then it will get confused and either throw an error or operate on an item you may not have intended. You have to be careful to pass valid combinations (newname+newversion or oldname+oldversion) to ensure commands behave the way you want.

TFS 2010 changes the story somewhat: it's a branch+delete under the covers, causing the itemID to change. Even so, everyday commands like Get and History are "faked" very well; old clients are about 95% compatible. The advantage is that when you have multiple renames in the system and path-based item lookups start to become ambiguous as alluded to above, the server will simply accept the name you specify and run with it. This improves overall system performance and eliminates several traps that unfamiliar users often fell into, at the cost of not being quite as flexible and not preserving history with 100% precision (eg when there are name collisions during a Merge of two branches).

Returning to the problem at hand...

It's not as simple as saying tf rename $/projectA $/projectB. Top level folders in the source control tree are reserved for the Team Project Creation Wizard; you can't run standard tf commands against them. What you need is a script like:

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

[of course, you can do it by hand if there aren't too many children under $/ProjectA]

As far as the gotchas I mentioned, I'll elaborate on one right now since looking up old history seems very important to you. Once you checkin the rename, tf history $/ProjectA/somefile.cs will NOT work. By default, tf commands assume version = "latest." Any of these alternatives will the full history you want:

  • tf history $/ProjectA/somefile.cs;1234 where changeset 1234 was before the move
  • tf history $/ProjectB/somefile.cs;5678 where changeset 5678 was after the move. Or you could just omit the version.

A final alternative for completeness & debugging purposes:

  • tf history $/ProjectA/somefile.cs -slotmode. You will only see the changes that happened prior to the move; however you'll also see the history of any other items that may have lived in the $/ProjectA/somefile.cs "slot" prior to or subsequent to the item you moved underneath B.

(In TFS 2010, "slot mode" is the default behavior; there's an -ItemMode option to request that your lookup be traced across history like it was 2008 rather than path-based.)

EDIT - no, branching is not a great alternative. While branching does leave enough metadata in the system to trace the full history to & from ProjectB, it's not terribly user friendly in 2008. Plan to spend a lot of time learning the tf merges command (no UI equivalent). 2010 dramatically improves your ability to visualize changes across multiple branches, but it's still not the clean unified experience you'd get from a Rename.

这篇关于Team Foundation Server - 移动带有历史记录的源代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆