我曾經多次看到這個問題(及衍生物):「我想知道XFS文件夾在TFS的某個分支中何時發生變化」。最典型的答案將以「編寫自己的簽入策略」或「在文件夾中設置警報」爲結束。這種方法有幾個缺陷(在我看來):當TFS中的文件夾發生變化時執行通知
- 編寫簽入策略要求您將策略部署到所有客戶端計算機。這在小環境中並不壞,但在更大的環境中可能會有問題。
- 它需要開發和測試工作。在我的特殊情況下,我沒有任何停機時間的開發人員正在解決此問題。
- 警報必須在文件夾上手動設置,並且不能指定通配符警報,以便在所有不同分支中的相同文件夾被修改時得到通知。
- 警報每次發生更改時都會觸發;這很快變得難以管理
我克服這些缺點的解決方案是在TFS數據庫中創建一個自定義存儲過程,我每晚作爲SQL Agent作業運行。存儲過程將檢查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 '$ \ <項目> \%\ < folder_to_monitor> \%'的第一個通配符被用來看看所有分支在給定的團隊項目。第二個通配符會查找我要監視的文件夾下的所有文件和文件夾。
- AND row3.ID = 3分支名稱(在我的情況下)將始終是函數返回的臨時表中的第三行。
- AND row8.ID =(SELECT MAX(id)FROM func_SplitString(v.FullPath,'\'))在大多數情況下,文件名將位於函數返回的表的第8行,但有些情況可能會更多或更少。因此我需要再次調用split函數來確定我的最大值是多少。
如何使這個查詢更好將不勝感激,我希望別人發現它有用的任何反饋。
缺點是公平點,但是這是針對TFS 2008的,所以我覺得微軟在其生命週期的這個階段推動Schema變化的風險很低。我當然希望有一些直接集成到TFS中的東西,但正如我所說的,目前我沒有任何資源可以促進開發。 – dparsons