Visual Studio TFS 加载项:将文件标记为删除
我一直在为我的公司编写一个 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");
I've been writing a VB Add-in for my company that will go into TFS and automatically mark files that end with ".delete" for deletion. To do this, I'd like to create a workspace "Temp" which maps to my D:\TFSTemp in my local and a folder in TFS. Then, I'd like to download only the .delete files to my local (to avoid having to get latest on all the files in the server), map them from my local to the server, mark them for deletion (workspace.PendDelete()) and then check them all in at once.
My problem is I am not sure I am setting up the correct mapping needed. I am able to download all the .delete files, yet when I invoke Workspace.GetPendingChanges(), the array is not being populated, which is why I suspect I might be not setting it up correctly.
I understand it is a complicated add-in, so please ask me questions if my code does not make sense to you.
//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");
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在将项目获取到本地工作区之前,您无法挂起删除操作。
您当前正在执行
DownloadFile
,它将仅获取文件的内容 - 它不会更新您的工作区以反映您在本地拥有该文件。您应该在等待删除之前调用该文件的Workspace.Get
。另一项:您不应该对文件使用完全递归(不知道后果),您可能应该使用
RecursionType.None
。文件上的完全递归执行模式匹配,并将包括给定路径下具有该文件名的所有文件。 (即,$/file.txt 的完整递归将匹配 $/file.txt、$/A/file.txt、$/A/B/file.txt 等)You can't pend a delete until you've done a get of the item into your local workspace.
You're currently doing a
DownloadFile
, which will simply get the contents of the file - it will not update your workspace to reflect that you have the file locally. You should instead callWorkspace.Get
for that file before pending your delete.One other item: you should not be using full recursion for files (without being aware of the consequences), you should probably be using
RecursionType.None
. Full recursion on a file performs pattern matching and will include all files with that filename beneath the given path. (Ie, full recursion for $/file.txt will match $/file.txt, $/A/file.txt, $/A/B/file.txt, etc.)