【问题标题】:Visual Studio Add-In for TFS: Marking Files for Deletion用于 TFS 的 Visual Studio 加载项:将文件标记为删除
【发布时间】:2011-10-05 16:00:09
【问题描述】:

我一直在为我的公司编写一个 VB 插件,它将进入 TFS 并自动标记以“.delete”结尾的文件以进行删除。为此,我想创建一个工作区“Temp”,它映射到我本地的 D:\TFSTemp 和 TFS 中的文件夹。然后,我只想将 .delete 文件下载到我的本地(以避免必须获取服务器中所有文件的最新信息),将它们从我的本地映射到服务器,将它们标记为删除(workspace.PendDelete( )) 然后一次性检查它们。

我的问题是我不确定我是否设置了所需的正确映射。我能够下载所有 .delete 文件,但是当我调用 Workspace.GetPendingChanges() 时,数组没有被填充,这就是我怀疑我可能没有正确设置它的原因。

我知道这是一个复杂的插件,所以如果我的代码对您没有意义,请向我提问。

//establish connection to tfs
                TeamFoundationServer server = new TeamFoundationServer(TFS1);
                //test file to output to
                StreamWriter xw = new StreamWriter(@"C:\Documents and Settings\A087649\Desktop\FileList.txt");
                //get a working object in tfs
                VersionControlServer sourceControl = server.GetService(typeof(VersionControlServer)) as VersionControlServer;

                int numberOfFiles = 0;
                int numToDelete = 0;

                try
                {
                    //load config file
                     //LoadConfig();

                    //path where we are going to look in tfs          
                    String path = @"$/PAIT_ECOMPARE/Dev/TFSTool/Prod/Offeringdata/AU/CT";
                    //array of item objects in that path
                    ItemSet items = sourceControl.GetItems(path, RecursionType.Full);
                    numberOfFiles = items.Items.Length;
                    Workspace workspace = sourceControl.CreateWorkspace("Temp");
                    WorkingFolder workingFolder = new WorkingFolder(path, @"D:\TFSTemp\");
                    workspace.CreateMapping(workingFolder);

                    //instance of own created class that represents the progressbar and log output
                    TFSToolLoad ProgressBar = new TFSToolLoad();
                    ProgressBar.SetValues(numberOfFiles);
                    ProgressBar.TopMost = true;


                    foreach (Item item in items.Items)
                    {
                        ProgressBar.Show();
                        //get only the file path to the file
                        serverPath = item.ServerItem;
                        //get changeset Id
                        changeSetID = item.ChangesetId;                            
                        if (serverPath.EndsWith(".delete"))
                        {
                            //get file name only and local path
                            fileName = Path.GetFileName(serverPath);
                            localPath = @"D:\TFSTemp\"+ fileName;
                            //get latest on the file
                            workspace.Get(new GetRequest(serverPath, RecursionType.None, VersionSpec.Latest), GetOptions.None);
                            workspace.PendDelete(serverPath, RecursionType.None);

                            numToDelete++;
                         }
                        ProgressBar.Step();
                    }

                    ProgressBar.SetText
                       ("Number of Files Marked for Delete: " + numToDelete+"\n");

                    //if there are any pending changes, check them in and merge them into staging
                    if (numToDelete > 0)
                    {
                        //check in all the changes
                        ProgressBar.SetText("Checking in changes...\n");
                        PendingChange[] pendingChanges = workspace.GetPendingChanges();

                        //if there are any pending changes, check them in and merge them into staging
                        workspace.CheckIn(pendingChanges, "Automated TFS tool cleanup");
                        ProgressBar.SetText("Done\n Merging changes into Staging...");

                        //merge
                        //set up merge by changeset id
                        ChangesetVersionSpec changeSet = new ChangesetVersionSpec(changeSetID);
                       //map to target server path before merging, otherwise it won't work
                        Workspace eCompareAdmin = sourceControl.GetWorkspace(@"D:\PAIT_ECOMPARE");
                        string mainPath = @"$/PAIT_ECOMPARE/Dev/TFSTool";
                        string stagingPath = @"$/PAIT_ECOMPARE/Dev/TFSToolStaging";
//Problem:
                        eCompareAdmin.Merge(mainPath, stagingPath, changeSet, changeSet);
                        PendingChange[] mergeChanges = eCompareAdmin.GetPendingChanges();
                        workspace.CheckIn(mergeChanges, "Automated TFS Cleanup");
                        ProgressBar.SetText("Done\n");

【问题讨论】:

  • 谢谢爱德华!我还有最后一期。执行合并后,我想检查对目标分支的这些更改,但是当我执行 GetPendingChanges() 时,数组再次返回 0。我整天都在调试,似乎无法弄清楚这一点。我错过了什么?我已经更新了上面的代码以反映我的更改。
  • 这是一个很好的问题 - Workspace.PendDelete() 调用是否成功?成功时返回非零值,失败时返回零值。
  • 是的,PendDelete 正在工作,我什至正在检查这些更改。似乎合并正在工作,但我无法确定这一点。

标签: c# tfs add-in delete-file


【解决方案1】:

在将项目获取到本地工作区之前,您无法挂起删除。

您当前正在执行DownloadFile,它只会获取文件的内容 - 它不会更新您的工作区以反映您在本地拥有该文件。在等待删除之前,您应该为该文件调用 Workspace.Get

另一项:您不应该对文件使用完全递归(不知道后果),您可能应该使用RecursionType.None。文件的完全递归执行模式匹配,并将包含给定路径下具有该文件名的所有文件。 (即 $/file.txt 的完全递归将匹配 $/file.txt、$/A/file.txt、$/A/B/file.txt 等)

【讨论】:

  • 感谢您的及时回复。我可以问你是否有办法获取()单个文件而不是服务器中的所有文件?如果有,怎么做?
  • 当然,你可以使用 Workspace.Get(new GetRequest(@"$/Path/To/File", RecursionType.None, VersionSpec.Latest), GetOptions.None);获取整个服务器实际上非常困难:您必须映射 $/。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-24
  • 1970-01-01
  • 1970-01-01
  • 2010-12-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多