我有Visual Studio 2008和TFS 我可以单击Source Coontrol Explorer中的特定文件夹,然后单击查看历史记录。
然后我看到所有变更集的列表。
然后我可以双击一个更改集并查看该更改集中更改的文件和文件夹路径(Changeset的详细信息)
我想在Source Control Explorer中查看特定文件夹的许多变更集的所有文件和路径的列表。
示例:
ChangesetId:1用户:A日期:今天评论:修复
ChangesetId:2用户:B日期:今天评论:Fix2
如果我点击Changeset 1,我会看到:
名称:class1.vb更改:合并,编辑文件夹C:\ work
名称:class2.vb更改:合并,编辑文件夹C:\ work
如果我点击Changeset 2,我会看到:
名称:class3.vb更改:合并,编辑文件夹C:\ PetProject
名称:class4.vb更改:合并,编辑文件夹C:\ PetProject
我想在一个列表中看到的是:
ChangesetId:1用户:日期:今天评论:修复名称:class1.vb更改:合并,编辑文件夹C:\ work
ChangesetId:1用户:日期:今日评论:修复名称:class2.vb更改:合并,编辑文件夹C:\ work
ChangesetId:2用户:B日期:今日评论:Fix2名称:class3.vb更改:合并,编辑文件夹C:\ PetProject
ChangesetId:2用户:B日期:今日评论:Fix2名称:class4.vb更改:合并,编辑文件夹C:\ PetProject
我可以查询TFS数据库中的某些表来获取此列表,还是可以在TFS中的某处查看它?
答案 0 :(得分:10)
您可以从命令行获取此信息。它一次只能做一次更改,但你可以编写一个脚本来为所有这些做一遍:
tf changeset /noprompt 55421
输出如下内容:
Changeset: 55421
User: dsmith
Date: 09 November 2010 12:41:25
Comment:
Fix to threading bug in connector
Items:
edit $/Project/products/App/Dev/Source Code/Utils.cpp
edit $/Project/products/App/Dev/Source Code/Connector.cpp
edit $/Project/products/App/Dev/Source Code/Utils.h
Check-in Notes:
Code Reviewer:
Performance Reviewer:
Security Reviewer:
如果你必须完全按照你的指定输出,那么你最好用TFS SDK编写一些代码
答案 1 :(得分:9)
您可能正在寻找tf history
命令:
tf history /server:http://tfs:8080 "$/path/to/what/you/want" /recursive /noprompt /format:detailed
如果您有很多更改,可以使用/version:
进行限制,或者可以/stopafter:xx
将结果限制为仅限'xx'条目。我相信,数据以反向日期顺序返回,因此您首先获得所有最新的更改。
答案 2 :(得分:0)
这将提供签入时附加到所有变更集的特定工作项目的文件列表。至少它为我解决了目的。
参考:bull.js
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.TeamFoundation;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
/// <summary>
/// Wrapper class for performing basic TFS queries
/// </summary>
public class TfsUtilities
{
public string TfsUri { get; private set; }
TfsTeamProjectCollection Server { get; set; }
VersionControlServer VersionCS { get; set; }
WorkItemStore Store { get; set; }
/// <summary>
/// Initialize this class to work with the specified Server (URI)
/// </summary>
/// <param name="tfsUri">The URI for the desired TFS server</param>
public TfsUtilities(string tfsUri)
{
TfsUri = tfsUri;
Server = GetServer();
VersionCS = Server.GetService(typeof(VersionControlServer)) as VersionControlServer;
Store = new WorkItemStore(Server);
}
/// <summary>
/// Get a reference to the specified server
/// </summary>
/// <returns>TFS Server at Collection Level</returns>
private TfsTeamProjectCollection GetServer()
{
return TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(TfsUri));
}
/// <summary>
/// Get items recursively in TFS via a direct TFS path.
/// </summary>
/// <param name="tfsPath">A path in the current TFS server</param>
/// <returns>All items found</returns>
public ItemSet GetTeamProjectItems(string tfsPath)
{
ItemSet items = VersionCS.GetItems(@"$" + tfsPath, RecursionType.Full);
//ItemSet items = version.GetItems(@"$ProjectNameFileName.cs", RecursionType.Full);
foreach (Item item in items.Items)
System.Console.WriteLine(item.ServerItem);
return items;
}
/// <summary>
/// Query for all or a specific work item in a team project
/// </summary>
/// <param name="teamProject">team project name</param>
/// <param name="workItemID">Optional - work item ID</param>
/// <returns>Work Item Collection</returns>
public WorkItemCollection GetWorkItems(string teamProject, int workItemID = 0)
{
string strSQL =
" SELECT [System.Id], [System.WorkItemType]," +
" [System.State], [System.AssignedTo], [System.Title] " +
" FROM WorkItems " +
" WHERE [System.TeamProject] = '" + teamProject +"' ";
if (workItemID > 0)
strSQL += " AND [System.Id] = " + workItemID;
strSQL += " ORDER BY [System.WorkItemType], [System.Id]";
WorkItemCollection workItems = Store.Query(strSQL);
foreach(WorkItem item in workItems)
Console.WriteLine(item.Id);
return workItems;
}
/// <summary>
/// Get all of the Files/Items that were modified and associated with a Work Item
/// </summary>
/// <param name="teamProject">Name of the Team Project</param>
/// <param name="workItemID">The work item ID</param>
/// <returns>List of changes</returns>
public List<FileItem> GetAllFilesModifiedForWorkItem(string teamProject, int workItemID)
{
WorkItemCollection workItems = GetWorkItems(teamProject, workItemID);
if (workItems.Count == 0)
{
Console.WriteLine("No Items found for Work Item ID: " + workItemID);
return null;
}
WorkItem item = workItems[0];
Console.WriteLine("Work Item {0} has {1} Links", workItemID, item.Links.Count);
if(item.Links.Count == 0)
return null;
List<Changeset> lstChangesets = GetChangesets(item.Links);
Console.WriteLine("Work Item {0} has {1} Changesets", workItemID, lstChangesets.Count);
if (lstChangesets.Count == 0)
return null;
List<FileItem> lstItems = GetItemsForChangeset(lstChangesets);
Console.WriteLine("Work Item {0} has {1} Items (changes)", workItemID, lstItems.Count);
if (lstItems.Count == 0)
return null;
return lstItems;
}
/// <summary>
/// Get all of the items, regardless of duplicates, changed for each provided changeset
/// </summary>
/// <param name="changesets"></param>
/// <returns></returns>
public List<FileItem> GetItemsForChangeset(List<Changeset> changesets)
{
List<FileItem> lst = new List<FileItem>();
foreach (Changeset obj in changesets)
{
Console.WriteLine("Changeset {0} has {1} Items", obj.ChangesetId, obj.Changes.Length);
lst.AddRange(GetItemsForChangeset(obj));
}
return lst;
}
/// <summary>
/// Get all of the changed files/items associated with this changeset
/// </summary>
/// <param name="changeset"></param>
/// <returns></returns>
public List<FileItem> GetItemsForChangeset(Changeset changeset)
{
FileItem t = null;
List<FileItem> lst = new List<FileItem>();
foreach (Change obj in changeset.Changes)
{
t = new FileItem() { CheckinDate = obj.Item.CheckinDate, ChangeType = obj.ChangeType, TfsPath = obj.Item.ServerItem };
Console.WriteLine("Item {0} : {1} - {2} - {3}", obj.Item.ItemId, t.CheckinDate, t.ChangeType, t.TfsPath);
lst.Add(t);
}
return lst;
}
/// <summary>
/// Get all of the Changesets from a collection of links (Links in a Work Item)
/// </summary>
/// <param name="workItemLinks">The links of a work item</param>
/// <returns>All of the found changesets - can be returned empty</returns>
public List<Changeset> GetChangesets(LinkCollection workItemLinks)
{
Changeset cs = null;
List<Changeset> lst = new List<Changeset>();
foreach (Link obj in workItemLinks)
{
cs = ConvertToChangeSet(obj);
if (cs != null)
lst.Add(cs);
}
return lst;
}
/// <summary>
/// Convert the provided Link to a Changeset.
/// If the conversion cannot be made, null is returned.
/// </summary>
/// <param name="workItemLink">Work Item Link</param>
/// <returns>Changeset or null</returns>
public Changeset ConvertToChangeSet(Link workItemLink)
{
Changeset cs = null;
ExternalLink externalLink = workItemLink as ExternalLink;
if (externalLink != null)
{
ArtifactId artifact = LinkingUtilities.DecodeUri(externalLink.LinkedArtifactUri);
if (String.Equals(artifact.ArtifactType, "Changeset", StringComparison.Ordinal))
{
// Convert the artifact URI to Changeset object.
cs = VersionCS.ArtifactProvider.GetChangeset(new Uri(externalLink.LinkedArtifactUri));
}
}
return cs;
}
//http://stackoverflow.com/questions/3619078/what-is-the-fastest-method-of-retrieving-tfs-team-projects-using-the-tfs-sdk-api
/// <summary>
/// Get all of the Team Project Names for the current TFS Server's Collection
/// </summary>
/// <returns>List of team project names</returns>
public List<string> GetTeamProjectNames()
{
return Server.GetService<VersionControlServer>()
.GetAllTeamProjects(false)
.Select(x => x.Name)
.ToList();
}
}
//Code for the FileItem class (not entirely necessary)
using System;
using Microsoft.TeamFoundation.VersionControl.Client;
public class FileItem
{
public DateTime CheckinDate { get; set; }
public string ChangeTypeString
{
get { return ChangeType.ToString(); }
}
public ChangeType ChangeType { get; set; }
public string TfsPath { get; set; }
}