在文件中查找:搜索团队基础架构服务器中的所有代码

104

有没有一种方法可以搜索TFS中每个文件的最新版本以查找特定字符串或正则表达式?这可能是我从Visual Source Safe想念的唯一东西...

目前,我对整个代码库执行“获取最新版本”,然后使用Windows搜索,但在超过75,000个文件且总共有1GB代码量的情况下,这会变得非常困难。

编辑: 尝试了提到的Powertools,但“通配符搜索”选项似乎只能搜索文件名而不能搜索内容。

更新: 我们已经在现有的MOSS(Search Server)安装中实施了自定义搜索选项。

12个回答

61

Team Foundation Server 2015(本地版本)和Visual Studio Team Services(云版)内置了搜索所有代码和工作项的支持。

您可以进行简单的字符串搜索,例如foo,布尔运算,例如foo OR bar,或更复杂的特定于语言的操作,例如class: WebRequest

代码搜索筛选器语法截图

您可以在这里阅读更多信息:https://www.visualstudio.com/en-us/docs/search/overview


3
请查看下面的回答,并给它点赞 ;) 从 TFS 2015 开始,可以使用“Code Search”插件实现此操作。https://marketplace.visualstudio.com/items?itemName=ms.vss-code-search - deadlydog
1
代码搜索目前仅适用于Visual Studio Team Services。对于Team Foundation Server的支持正在开发中,并将包含在下一个版本中。 - paparush
代码搜索现在可在 TFS 2017 或更新版本中使用。 - csrowell
1
如果您尝试切换到该文档的2015版本:“请求的页面对于Team Foundation Server 2015不可用。” - AaronLS

16

在我的情况下,使用C#编写一个小工具对我很有帮助。

对我有帮助的链接:

http://pascallaurin42.blogspot.com/2012/05/tfs-queries-searching-in-all-files-of.html

如何使用TFS API列出团队项目中的文件?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.Framework.Client;
using System.IO;

namespace TFSSearch
{
class Program
{
    static string[] textPatterns = new[] { "void main(", "exception", "RegisterScript" };  //Text to search
    static string[] filePatterns = new[] { "*.cs", "*.xml", "*.config", "*.asp", "*.aspx", "*.js", "*.htm", "*.html", 
                                           "*.vb", "*.asax", "*.ashx", "*.asmx", "*.ascx", "*.master", "*.svc"}; //file extensions

    static void Main(string[] args)
    {
        try
        {
            var tfs = TfsTeamProjectCollectionFactory
             .GetTeamProjectCollection(new Uri("http://{tfsserver}:8080/tfs/}")); // one some servers you also need to add collection path (if it not the default collection)

            tfs.EnsureAuthenticated();

            var versionControl = tfs.GetService<VersionControlServer>();


            StreamWriter outputFile = new StreamWriter(@"C:\Find.txt");
            var allProjs = versionControl.GetAllTeamProjects(true);
            foreach (var teamProj in allProjs)
            {
                foreach (var filePattern in filePatterns)
                {
                    var items = versionControl.GetItems(teamProj.ServerItem + "/" + filePattern, RecursionType.Full).Items
                                .Where(i => !i.ServerItem.Contains("_ReSharper"));  //skipping resharper stuff
                    foreach (var item in items)
                    {
                        List<string> lines = SearchInFile(item);
                        if (lines.Count > 0)
                        {
                            outputFile.WriteLine("FILE:" + item.ServerItem);
                            outputFile.WriteLine(lines.Count.ToString() + " occurence(s) found.");
                            outputFile.WriteLine();
                        }
                        foreach (string line in lines)
                        {
                            outputFile.WriteLine(line);
                        }
                        if (lines.Count > 0)
                        {
                            outputFile.WriteLine();
                        }
                    }
                }
                outputFile.Flush();
            }
        }
        catch (Exception e)
        {
            string ex = e.Message;
            Console.WriteLine("!!EXCEPTION: " + e.Message);
            Console.WriteLine("Continuing... ");
        }
        Console.WriteLine("========");
        Console.Read();
    }

    // Define other methods and classes here
    private static List<string> SearchInFile(Item file)
    {
        var result = new List<string>();

        try
        {
            var stream = new StreamReader(file.DownloadFile(), Encoding.Default);

            var line = stream.ReadLine();
            var lineIndex = 0;

            while (!stream.EndOfStream)
            {
                if (textPatterns.Any(p => line.IndexOf(p, StringComparison.OrdinalIgnoreCase) >= 0))
                    result.Add("=== Line " + lineIndex + ": " + line.Trim());

                line = stream.ReadLine();
                lineIndex++;
            }
        }
        catch (Exception e)
        {
            string ex = e.Message;
            Console.WriteLine("!!EXCEPTION: " + e.Message);
            Console.WriteLine("Continuing... ");
        }

        return result;
    }
}
}

13

另外还有一种替代方案,看起来更具吸引力。

  1. 设置一个搜索服务器 - 可以是任何Windows机器/服务器
  2. 设置一个 TFS通知服务*(Bissubscribe),以获取、删除、更新文件,每次进行checkin时都会发生。所以这是一个像TFS服务器上的监听器一样的Web服务,并在搜索服务器上更新/同步文件和文件夹。- 这将极大地提高精度(实时搜索),避免定期获取的一次性负载
  3. 在搜索服务器上设置一个索引服务/Windows索引搜索,用于根目录
  4. 公开一个Web服务以返回搜索结果

现在有了以上所有设置,您有几个选择客户端:

  1. 设置一个网页调用搜索服务并格式化结果以显示在网页上 - 也可以通过宏或插件将此网页集成到Visual Studio中
  2. 创建一个Windows客户端界面(winforms/wpf)来调用搜索服务并格式化结果,并在UI上显示它们 - 您也可以通过VSPackages或插件将此客户端工具集成到Visual Studio中

更新: 我确实采取了这种方法,效果很好。只是想补充一下。

参考链接:

  1. 使用此工具代替bissubscribe.exe
  2. 处理TFS事件
  3. 团队系统通知

10
如果安装了TFS 2008 PowerTools,则在Team Explorer右键菜单中会获得“在源代码控制中查找”操作。 TFS2008 Power Tools 是下载链接。

4
很有趣,它们被称为“电动工具”。有人会说像回滚这样的操作是“基本功能”。 :-) - Iain Holder
当然,你可以手动执行回滚操作,只是这不是一个一键操作。也许应该是这样的。 - Jeff Atwood
15
我认为只需要搜索文件/文件夹的名称。 - Kiddo
11
电动工具无法搜索文件内容,只能搜索文件/文件夹名称。 - Evgeniy Berezovsky

6

1
注意:Code Search目前仅适用于Visual Studio Team Services。对于Team Foundation Server的支持正在开发中,并将包含在下一个版本中。 - Jamie

6

好的,

  1. TFS2008 Power Tools没有查找文件中内容的功能。 "查找源代码控制工具提供了通过项目的状态或使用通配符表达式在源代码控制中定位文件和文件夹的能力。"

  2. 有一个Windows程序可以实现这个功能,发布在CodePlex上。我刚刚安装并测试了一下,效果很好。


它很不稳定而且速度慢,但似乎能够达到它所说的功能。 - Paul Michaels
我遇到了像下面链接中的人们一样的错误。还有其他人也遇到了这个问题吗?https://tfssearchcode.codeplex.com/workitem/32475 - strider

6
我们已经为Team Foundation Server源代码控制(而不是您提到的SourceSafe)建立了一个解决方案,类似于Grant建议的方案;安排TF Get,Search Server Express。然而,用于C#文件(文本)的IFilter未能给出我们想要的结果,因此我们将源文件转换为.htm文件。我们现在可以向文件添加其他元数据,例如:
  • 作者(我们将其定义为最后一次检入文件的人)
  • 颜色编码(在我们的待办事项清单上)
  • 更改数量表示潜在的设计问题(在我们的待办事项清单上)
  • 与VSTS IDE集成,如Koders SmartSearch功能
  • 等等。
我们希望有一个TFS源代码控制的协议处理程序和一个专用的源代码IFilter,以获得更加精准的解决方案。

1
有计划开源 .htm 转换工具吗? - technomalogical

3

另一个解决方案是使用“ctrl+shift+F”快捷键。你可以将搜索位置更改为本地目录而不是解决方案或项目。这只是取代了桌面搜索,你仍然需要获取最新的代码,但它将允许你在Visual Studio内进行搜索。


4
未涉及搜索TFS代码版本的问题。 - Craig
搜索未下载的内容是无用的。最好使用grep/findstr。 - Jamie

1

目前没有现成的方法来实现这个功能,但是有一个用户建议可以添加它:http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2037649-implement-indexed-full-text-search-of-work-items

虽然我怀疑它并不像翻转开关那么简单,但如果所有查看此问题的人都投票支持,微软可能会实现一些东西。

更新:刚刚阅读了Brian Harry's blog,这显示出他们已经关注此请求,并且Visual Studio Online版本在搜索git作为vcs使用的地方方面有限的支持:http://blogs.msdn.com/b/visualstudioalm/archive/2015/02/13/announcing-limited-preview-for-visual-studio-online-code-search.aspx。从这个可以推断出,这只是时间问题...
更新2:现在有一个由微软提供的扩展Code Search,它可以在代码和工作项中进行搜索。

1
假设你使用的是Notepad ++,一个经常被忽视的功能是“在文件中查找”,它非常快速,并带有过滤器、正则表达式、替换以及所有N++的好处。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接