【发布时间】:2014-05-07 07:26:31
【问题描述】:
我已经多次看到这个问题(及其衍生问题):“我想知道 X 文件夹何时在 TFS 的给定分支中更改”。最典型的答案是“编写您自己的签入策略”或“在文件夹上设置警报”。这种方法有几个缺点(在我看来):
- 编写签入策略要求您将策略部署到所有客户端计算机。这在小型环境中还不错,但在更大的环境中可能会出现问题。
- 它需要开发和测试工作。在我的特定情况下,我没有任何开发人员有停机时间来解决这个问题。
- 必须在文件夹上手动设置警报,并且您不能指定通配符警报,以便在所有不同分支中的同一文件夹被修改时收到通知。
- 每次进行更改时都会触发警报;这很快就会变得难以管理
我克服这些缺点的解决方案是在 TFS 数据库中创建一个自定义存储过程,我每晚将其作为 SQL 代理作业运行。存储过程检查 TfsVersionControl 数据库中的表以确定给定文件夹中的哪些文件(如果有)已更改,并通过电子邮件将报告发送给相应的收件人。
SELECT
i.DisplayName AS [Developer],
cs.ChangeSetId AS [Changeset],
row3.Value AS [BranchName],
REPLACE(row8.Value, '>', '_') AS [FileName],
cs.CreationDate AS [CreatedDate],
REPLACE(LEFT(v.FullPath, LEN(v.FullPath) - 1), '>', '_') AS [FilePath]
FROM tbl_Version v
JOIN tbl_VersionedItem vi ON v.ItemId = vi.ItemId
JOIN tbl_ChangeSet cs ON v.VersionFrom = cs.ChangeSetId
JOIN tbl_Identity i ON cs.CommitterId = i.IdentityId
LEFT JOIN tbl_File f ON v.FileId = f.FileId
CROSS APPLY func_SplitString(v.FullPath, '\') row3
CROSS APPLY func_SplitString(v.FullPath, '\') row8
WHERE
v.FullPath LIKE '$\<project>\%\<folder_to_monitor>\%'
AND cs.CreationDate BETWEEN (GETUTCDATE() - 1) AND GETUTCDATE()
--The third row in the temp table should always be the branch
AND row3.ID = 3
--The last column will always be the filename, but it is a variable element in the path
AND row8.ID = (SELECT MAX(id) FROM func_SplitString(v.FullPath, '\'))
ORDER BY cs.ChangeSetId DESC
func_SplitString 只是一个拆分字符串并返回两列(ID,Value)宽的表的函数。我唯一不喜欢这个查询的是对 CROSS APPLY 的多次调用,但我想不出更好的方法来从 FullPath 中提取分支名称和文件名,而无需进行大量字符串操作。
一些简单的解释:
- v.FullPath LIKE '$\\%\\%' 第一个通配符用于查看给定团队项目中的所有分支。第二个通配符查找我要监控的文件夹下的所有文件和文件夹。
- AND row3.ID = 3 分支名称(在我的例子中)将始终是函数返回的临时表中的第三行。
- AND row8.ID = (SELECT MAX(id) FROM func_SplitString(v.FullPath, '\')) 在大多数情况下,文件名将位于函数返回的表的第 8 行,但在某些情况下可能或多或少。因此,我需要再次调用 split 函数来确定我的最大值是多少。
任何关于如何使这个查询更好的反馈将不胜感激,我希望其他人觉得它有用。
【问题讨论】:
标签: sql .net sql-server tfs