【问题标题】:TFS: How to view all files in many changesets?TFS:如何查看许多变更集中的所有文件?
【发布时间】:2010-11-09 14:36:53
【问题描述】:

我有 Visual Studio 2008 和 TFS。
我可以在 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 用户:A 日期:今天 评论:修复名称:class1.vb 更改:合并,编辑文件夹 C:\work

ChangesetId:1 用户:A 日期:今天 评论:修复名称:class2.vb 更改:合并,编辑文件夹 C:\work

ChangesetId:2 用户:B 日期:今天 评论:Fix2 名称:class3.vb 更改:合并,编辑文件夹 C:\PetProject

ChangesetId:2 用户:B 日期:今天 评论:Fix2 名称:class4.vb 更改:合并,编辑文件夹 C:\PetProject

我可以查询 TFS 数据库中的某个表以获取此列表,还是可以在 TFS 中的某处看到它?

【问题讨论】:

  • 您尝试过 tf history 还是 tf changeset

标签: tfs


【解决方案1】:

您可以从命令行获取此信息。它一次只做一个更改,但您可以编写一个脚本来为所有这些更改:

 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 编写一些代码

【讨论】:

  • 好的 - 但是如何在源代码管理资源管理器中获取特定文件夹和子文件夹的所有变更集?
【解决方案2】:

您可能正在寻找tf history 命令:

tf history /server:http://tfs:8080 "$/path/to/what/you/want" /recursive /noprompt /format:detailed

如果您有很多更改,您可以使用/version: 进行限制,或者您可以使用/stopafter:xx 将结果限制为仅“xx”条目。我相信数据会以相反的日期顺序返回,因此您首先会获得所有最新的更改。

【讨论】:

  • 日期范围如何限制?
【解决方案3】:

这将在签入时提供附加到所有更改集的特定工作项的文件列表。至少它解决了我的目的。

参考:http://obscureproblemsandgotchas.com/uncategorized/how-to-get-all-files-modified-for-work/

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; }
}

【讨论】:

    猜你喜欢
    • 2010-10-06
    • 1970-01-01
    • 2011-09-02
    • 2010-10-29
    • 1970-01-01
    • 2011-03-09
    • 1970-01-01
    • 1970-01-01
    • 2017-05-31
    相关资源
    最近更新 更多