TFS2010:检索与分支关联的所有变更集(完全递归)
这遵循我之前的问题是关于 TFS 2010 以及创建变更日志的可能性。
我以前使用标签来标识程序的版本,但由于标签不是固定的时间点,现在我使用分支。
分支层次结构如下所示:
正如您所看到的,有两个不同的应用程序是主干的分支:APP_A
(应用程序 A)和 APP_B
(应用程序 B)。两者几乎相同,但存在一些功能差异。
以下是创建新版本应用程序(例如版本 1.3)的过程:
- 修改
Main trunk
(添加新功能、修复错误...) - 来自修改后的
Main trunk
,创建一个新分支:Main trunk 1.3
APP_A
分支可能会被修改,因此APP_A
的独特功能将在修改后使用v1.3 的APP_B
分支可能会被修改,因此APP_B
的独特功能将与 v1.3 的修改一起使用Main trunk 1.3
已合并到APP_A
Main trunk
接收修改- 和
APP_B
,因此APP_A
和APP_B
应用程序都会从 修改的APP_A
分支,创建一个新分支:APP_A_1.3
- 从修改后的
APP_B
分支,创建一个新分支:APP_B_1。 3
我的目标是能够生成 APP_A_1.3
和 APP_A_1.2
之间的变更日志。
我所说的变更日志是指工作项列表。签入的每个变更集都与一个或多个工作项(例如 Bug 项)相关联。 我希望能够获取链接到影响 APP_A_1.3
变更集的所有工作项的列表:这些变更集可能来自 Main trunk
(上面的步骤 1)、APP_A 分支
(上面的步骤 3)甚至 APP_A_1.3
分支本身(如果在分行有已创建)。
为了获取此工作项列表,我尝试获取“链接”到APP_A_1.2
的所有变更集的列表(“链接”=已在变更集中签入的内容现在位于分支 APP_A_1.2
上)以及“链接”到 APP_A_1.3
的所有变更集的列表。
然后,我将能够知道哪些变更集“链接”到 APP_A_1.3
,而不“链接”到 APP_A_1.2
。从变更集的这个子集中,我将获得所有关联的工作项以及我的变更日志。
这是我的问题:如何获取与指定分支“链接”的所有变更集的列表?我正在使用 C# 代码的 TFS 2010 API。
我的程序的输入(将检索指定分支的所有变更集)将是分支的名称(例如 APP_A_1.2
),输出将是以下变更集的列表
- :
APP_A_1.2
之前,在APP_A_1.2
分支本身 - 在创建
- 应用了在
APP_A
分支上应用的变更集,在Main trunk 上应用了变更集1.2
分支,然后合并到APP_A
Main trunk 1.2
之前应用于Main trunk
分支
变更集,在创建我编写的 使用以下代码片段来获取所有这些变更集:
// Gets the list of all changesets ID from APP_A_1.2 branch
var branch1ChangeSets = myVersionControlServer.QueryHistory(
"$/PATH/APP_A_1.2/",
VersionSpec.Latest,
0,
RecursionType.Full,
null,
null,
null,
int.MaxValue,
false,
false).OfType<Changeset>().Select(z => z.ChangesetId).ToList();
即使指定了 RecursionType.Full
,上面的代码也仅返回在APP_A_1.2
分支本身。这与 Visual Studio 中“源代码资源管理器”视图中的“历史记录”命令相同。
然后我尝试了以下代码:
// Gets the list of all changesets ID from APP_A_1.2 branch
var branch1MergedChangeSets = myVersionControlServer.QueryMerges(
null,
null,
"$/PATH/APP_A_1.2/",
VersionSpec.Latest,
null,
null,
RecursionType.Full).Select(z => z.SourceVersion).ToList();
这将返回在 APP_A_1.2
分支上签入的变更集 + 在 之前在
已创建。好多了,但还不够。我找不到一种方法可以使递归与“上面”APP_A
分支上签入的变更集APP_A_1.2APP_A
的分支一起工作(在我的情况下是Main trunk
)...
有人有想法吗?
另外,欢迎任何更好的想法来获取两个分支之间的变更日志...... 谢谢。
This follows my previous question about TFS 2010 and the possibility to create a changelog.
I was previously using labels to identify a version of the program, but as labels are not fixed points in time, now I'm using branches.
Here's how the branch hierarchy looks like:
As you can see, there are two different applications that are branches of the trunk: APP_A
(application A) and APP_B
(application B). Both are almost identical, but there are some functional differences.
Here is the process to create a new version of the application (say version 1.3):
- The
Main trunk
is modified (new functionalities are added, bug fixes...) - From the modified
Main trunk
, a new branch is created:Main trunk 1.3
APP_A
branch might be modified, so unique functionalities ofAPP_A
will work with modification of v1.3APP_B
branch might be modified, so unique functionalities ofAPP_B
will work with modification of v1.3Main trunk 1.3
is merged toAPP_A
andAPP_B
, so bothAPP_A
andAPP_B
applications receive the modifications of theMain trunk
- From the modified
APP_A
branch, a new branch is created:APP_A_1.3
- From the modified
APP_B
branch, a new branch is created:APP_B_1.3
My goal is to be able to produce a changelog between APP_A_1.3
and APP_A_1.2
.
By changelog I mean a list of WorkItems. Each changeset that is checked-in is associated with one or more WorkItem (for instance a Bug item). I would like to be able to get the list of all workitems that were linked to a changeset that has impacted APP_A_1.3
: those changesets might come from the Main trunk
(step 1 above), the APP_A branch
(step 3 above) or even the APP_A_1.3
branch itself (if hotfixes are checked-in after the branch has been created).
To get this list of workitems, I tried to get the list of all changesets that are "linked" to APP_A_1.2
("linked" = the code that was checked-in in the changeset is now on the branch APP_A_1.2
) and the list of all changesets that are "linked" to APP_A_1.3
.
Then, I'll be able to know which changesets are "linked" to APP_A_1.3
and not "linked" to APP_A_1.2
. From this subset of changesets, I'll get all associated WorkItems and thus my changelog.
Here's my problem: how could I get the list of ALL changesets that are "linked" with a specified branch? I'm using the TFS 2010 API for C# code.
The input of my program (that would retrieve all changesets for a specified branch) would be the name of the branch (say APP_A_1.2
), and the output would be the list of following changesets:
- changesets applied on
APP_A_1.2
branch itself - changesets applied on
APP_A
branch beforeAPP_A_1.2
was created - changesets applied on
Main trunk 1.2
branch before it has been merged toAPP_A
- changesets applied on
Main trunk
branch beforeMain trunk 1.2
was created
I've wrote the following pieces of code to get all those changesets:
// Gets the list of all changesets ID from APP_A_1.2 branch
var branch1ChangeSets = myVersionControlServer.QueryHistory(
"$/PATH/APP_A_1.2/",
VersionSpec.Latest,
0,
RecursionType.Full,
null,
null,
null,
int.MaxValue,
false,
false).OfType<Changeset>().Select(z => z.ChangesetId).ToList();
Even if RecursionType.Full
is specified, the above code only returns changesets that were checked-in on the APP_A_1.2
branch itself. This is identical to the "History" command on Source Code Explorer view in Visual Studio.
Then I tried the following piece of code:
// Gets the list of all changesets ID from APP_A_1.2 branch
var branch1MergedChangeSets = myVersionControlServer.QueryMerges(
null,
null,
"$/PATH/APP_A_1.2/",
VersionSpec.Latest,
null,
null,
RecursionType.Full).Select(z => z.SourceVersion).ToList();
This returns changesets that were checked-in on APP_A_1.2
branch + those that were cheked-in on APP_A
branch before APP_A_1.2
was created. Much better, but not sufficient. I can't find a way to make the recursion work with branches that are "above" APP_A
(Main trunk
in my case)...
Anyone has an idea?
Also, any better ideas to get the changelog between two branches are welcome...
Thx.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
首先让我先问一个问题。在帖子的顶部你写:
“我的目标是能够生成 APP_A_1.3 和 APP_A_1.2 之间的变更日志。”
但是当你写下具体的更改时,你正在寻找你的列表:
应用于 APP_A_1.2 分支本身的变更集
创建 APP_A_1.2 之前在 APP_A 分支上应用的变更集
在合并到 APP_A 之前在 Main trunk 1.2 分支上应用的变更集
创建 Main trunk 1.2 之前在 Main trunk 分支上应用的变更集
这不是一个有效的列表,因为它将为您提供对 APP_A_1.3、APP_A_1.2、1.1 等到存储库开头做出贡献的所有更改。
我现在无法测试我的方法,但这就是我要做的:
- QueryHistory 将所有更改直接签入分支 1.3
- 使用 QueryMergesExtended 来跟踪合并到此分支中。 QueryMergesExtended (http://msdn.microsoft.com/en-us/library/ff736485.aspx) 是专门添加到 TFS 2010 中的,它比 QueryMerges 和 QueryMergesWithDetails 具有更高的性能和健壮性,以支持分支可视化工具
- 据我所知,您不需要在 QueryMergesExtended 中指定选项 FollowRenames,因为您在分支的根上查询合并
- 当您获取源更改列表(来自 APP_A)时,您需要检查每个更改集以查看它是否包含合并更改。如果是这样,您需要在 app_a 上查询合并以获取这些变更集。递归地执行此操作,直到遍历整个分支层次结构。
在副主题上,您可以稍后查看 QueryMergeRelationships (http://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.versioncontrol.client.versioncontrolserver.querymergerelationships.aspx) 为您提供 tfs 2010 中引入的分支对象列表(这是在源代码管理资源管理器中选择文件夹并单击转换为分支时发生的情况)。但是,如果您可以以不同的方式发现您的分支(对它们进行硬编码),则不需要。
希望这有帮助!
first let me first ask one question. At the top of the post you write:
"My goal is to be able to produce a changelog between APP_A_1.3 and APP_A_1.2."
but then when you write what changes specifically you are looking for you list:
changesets applied on APP_A_1.2 branch itself
changesets applied on APP_A branch before APP_A_1.2 was created
changesets applied on Main trunk 1.2 branch before it has been merged to APP_A
changesets applied on Main trunk branch before Main trunk 1.2 was created
This is not a valid list because it will give you all changes that contributed to APP_A_1.3, APP_A_1.2, 1.1 and so on to the beginning of the repository.
I'm not able to test my approach right now, but this is what I would do:
- QueryHistory to get all changes checked in directly into branch 1.3
- use QueryMergesExtended to follow merges into this branch. QueryMergesExtended (http://msdn.microsoft.com/en-us/library/ff736485.aspx) was added in TFS 2010 specifically to be much more performant and robust than QueryMerges and QueryMergesWithDetails, in order to support branch visualization tools
- afaik you don't need to specify option FollowRenames in QueryMergesExtended because you query merges on the root of the branch
- when you get list of source changes (from APP_A) you need to check each changeset to see of it contains merge changes. If so, you need to query merges on app_a for those changesets. Do so recursively until you walk whole branch hierarchy.
On the side topic, you can look later at the QueryMergeRelationships (http://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.versioncontrol.client.versioncontrolserver.querymergerelationships.aspx) which gives you branch object list introduced in tfs 2010 (this is what happens when in Source Control Explorer you select folder and click Convert to branch). However if you can discover your branch in different way (hardcode them) than it's not needed.
Hope this helps!
我终于想出了一个简单的解决方案。我对它并不完全满意,因为它实际上看起来像一个蛮力算法,但至少它有效。
我所做的是:
1)获取应用于我的TFS分支的根的每个变更集的列表(即
Main的“父路径”)主干
):2)对于每个检索到的变更集,我调用
TrackMerges
来查看变更集是否以某种方式影响我的分支。 TrackMerges 能够告诉我指定的变更集是否应用于我指定为函数参数的分支(它将返回这些分支上的目标变更集 ID)。如果变更集应用于目标分支(在我的例子中APP_A_1.3
)而不是源分支(APP_A_1.2
),那么这意味着它肯定是新的在我的APP_A_1.3
分支上。3)现在从“新变更集”列表中获取我的变更日志(工作项列表)非常简单:
我不认为这是最好的方法,但它工作正常并且保持简单。另外,我不需要对任何东西(分支名称/层次结构)进行硬编码,所以在我看来这还不错。希望它能帮助某人。
I finally came up with a simple solution. I'm not totally happy with it as it actually looks like a brute-force algorithm, but at least it works.
What I do is:
1) Get the list of every changeset that is applied on the very root of my TFS branches (i.e. the "parent path" of
Main Trunk
):2) For each retrieved changeset, I call
TrackMerges
to see if the changeset impacts in some way my branches.TrackMerges
is able to tell me if a specified changeset is applied on the branches I specify as parameter of the function (it'll return the target changeset ID on these branches). If a changeset is applied on the destination branch (in my caseAPP_A_1.3
) and not in the source branch (APP_A_1.2
), then it means it's definitely something new on myAPP_A_1.3
branch.3) Now it's very simple to get my changelog (the list of workitems) from the list of "new changesets":
I don't think it's the best possible approach, but it works fine and remains simple. Also, I didn't have to hardcode anything (branch names/hierarchy) so it's not too bad IMO. Hope it'll help someone.
是的,我自己也在解决这个问题。无论如何,我找到了一个 codeplex 项目来解决这个问题,当你比较标签时。
看看这是否有帮助: http://tfslabeldiff.codeplex.com/SourceControl/changeset/ view/7075#158224
我很惊讶这很难找到,但 TFS 的文档充其量是缺乏的。看起来应该很明显了!
Yeah, working on this problem myself too. I found a codeplex project that solves it, when you're diff-ing labels, anyhow.
See if this helps: http://tfslabeldiff.codeplex.com/SourceControl/changeset/view/7075#158224
I was pretty surprised how difficult this was to find, but the documentation for TFS is lacking at best. It seemed like it ought to be obvious!