Je vyžadována podpora jazyka JavaScript
Některé stránky na tomto webu vyžadují podporu jazyka JavaScript. Váš webový prohlížeč jazyk JavaScript nepodporuje nebo jazyk JavaScript není povolen.
Chcete-li zjistit, zda webový prohlížeč podporuje jazyk JavaScript nebo jazyk JavaScript chcete povolit, přečtěte si nápovědu k vašemu webovému prohlížeči.
SourceControlHelper.cs
Download fileToto je zdrojový kód souboru SourceControlHelper.cs
Source Control helper class working on TFS workspace.
using System;
using System.IO;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Reflection;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.VersionControl.Common;
using Microsoft.VisualStudio.TeamFoundation.VersionControl;
using Microsoft.TeamFoundation;
namespace IMP.TFSSCExplorerExtension.TFS
{
//VersionControlServer.SupportedFeatures is an indicator of what server version you are talking to
// 42684268421 - Microsoft.TeamFoundation.VersionControl.Common.SupportedFeatures Flags
// 7 Team Foundation Server 2008 RTM - 111 - GetLatestOnCheckout, OneLevelMapping, Destroy
// 31 Team Foundation Server 2008 SP1 - 11111 - +CreateBranch, GetChangesForChangeset
// 895 Team Foundation Server 2010 RTM - 1101111111 - +ProxySuite, LocalVersions, BatchedCheckins, WorkspacePermissions
// 1919 Team Foundation Server 2010 SP1 - 11101111111 - +CheckinDates
//Microsoft.TeamFoundation.VersionControl.Common.SupportedFeatures Flags
// None = 0,
// GetLatestOnCheckout = 1,
// OneLevelMapping = 2,
// Destroy = 4,
// CreateBranch = 8,
// GetChangesForChangeset = 16,
// ProxySuite = 32,
// LocalVersions = 64,
// BatchedCheckins = 256,
// WorkspacePermissions = 512,
// CheckinDates = 1024,
internal static class SourceControlHelper
{
#region member varible and default property initialization
private static VersionControlServer s_HasRepositoryExtensionsVCS;
private static bool s_HasRepositoryExtensions;
#endregion
#region action methods
#region Source control actions
public static void Merge(Workspace workspace, IEnumerable<Tuple<string, string>> itemsToMerge)
{
foreach (var itemToMerge in itemsToMerge)
{
TrackMessage(string.Format("Merging {0} --> {1}", itemToMerge.Item1, itemToMerge.Item2));
try
{
var status = workspace.Merge(itemToMerge.Item1, itemToMerge.Item2, null, null, LockLevel.None, RecursionType.None, MergeOptions.None);
if (status.NumConflicts != 0)
{
TrackWarning("Merge operation encountered a conflict.");
}
else if (status.NoActionNeeded)
{
TrackMessage(string.Format("File {0} has no changes to merge.", itemToMerge.Item1));
}
}
catch (Microsoft.TeamFoundation.VersionControl.Client.NoMergeRelationshipException)
{
//The item ... is not a branch of ...
TrackMessage(string.Format("A merge relationship does not exists, a baseless merge will be performed.", itemToMerge.Item1));
var status = workspace.Merge(itemToMerge.Item1, itemToMerge.Item2, null, null, LockLevel.None, RecursionType.None, MergeOptionsEx.Baseless);
if (status.NumConflicts != 0)
{
bool resolved = false;
var conflicts = workspace.QueryConflicts(new string[] { itemToMerge.Item2 }, false);
if (conflicts.Length == 1)
{
var conflict = conflicts[0];
//Take source version
if (!conflict.IsResolved && !conflict.NameChanged && !conflict.RequiresExplicitAcceptMerge && conflict.YourChangeType == ChangeType.None)
{
conflict.Resolution = Resolution.AcceptTheirs;
workspace.ResolveConflict(conflict);
if (conflict.IsResolved)
{
resolved = true;
if (UndoUnchangedItem(workspace, itemToMerge.Item2))
{
TrackMessage(string.Format("File {0} has no changes to merge.", itemToMerge.Item1));
}
}
}
}
if (!resolved)
{
TrackWarning("Merge operation encountered a conflict.");
}
}
else if (status.NoActionNeeded)
{
TrackMessage(string.Format("File {0} has no changes to merge.", itemToMerge.Item1));
}
else
{
if (UndoUnchangedItem(workspace, itemToMerge.Item2))
{
TrackMessage(string.Format("File {0} has no changes to merge.", itemToMerge.Item1));
}
}
}
catch (Microsoft.TeamFoundation.VersionControl.Client.MappingException ex)
{
TrackWarning(ex.Message);
}
}
}
public static void BranchToFolder(Workspace workspace, IEnumerable<string> items, string folder)
{
BranchToFolder(workspace, items, folder, VersionSpec.Latest);
}
public static void BranchToFolder(Workspace workspace, IEnumerable<string> items, string folder, VersionSpec versionSpec)
{
foreach (var item in items)
{
string fileName = VersionControlPath.GetFileName(item);
string folderPath = VersionControlPath.Combine(folder, fileName);
workspace.PendBranch(item, folderPath, versionSpec);
}
}
public static void MoveToFolder(Workspace workspace, IEnumerable<string> items, string folder)
{
try
{
foreach (var item in items)
{
string fileName = VersionControlPath.GetFileName(item);
string folderPath = VersionControlPath.Combine(folder, fileName);
workspace.PendRename(item, folderPath);
}
}
catch (System.ComponentModel.Win32Exception ex)
{
//Access is denied
//This file is currently not available for use on this computer
TrackWarning(ex.Message);
}
}
public static void CopyToFolder(Workspace workspace, IEnumerable<VersionControlExplorerItem> items, string folder)
{
string folderLocalPath;
try
{
folderLocalPath = workspace.GetLocalItemForServerItem(folder);
}
catch (Microsoft.TeamFoundation.VersionControl.Client.MappingException ex)
{
TrackWarning(ex.Message);
return;
}
if (!System.IO.Directory.Exists(folderLocalPath))
{
TrackMessage(string.Format("Folder {0} not found", folderLocalPath));
return;
}
foreach (var item in items)
{
string localPath = null;
try
{
localPath = item.LocalPath;
if (string.IsNullOrEmpty(localPath) && item.TargetServerPath != null)
{
localPath = workspace.GetLocalItemForServerItem(item.TargetServerPath);
}
}
catch (Microsoft.TeamFoundation.VersionControl.Client.MappingException ex)
{
TrackWarning(ex.Message);
continue;
}
if (string.IsNullOrEmpty(localPath))
{
TrackMessage(string.Format("Local item path cannot be loaded", localPath));
continue;
}
if (item.IsFolder)
{
if (!System.IO.Directory.Exists(localPath))
{
TrackMessage(string.Format("Folder {0} not found", localPath));
continue;
}
string targetFolder = System.IO.Path.Combine(folderLocalPath, System.IO.Path.GetFileName(localPath));
CopyFiles(localPath, targetFolder, true, true);
workspace.PendAdd(targetFolder, true);
continue;
}
if (!System.IO.File.Exists(localPath))
{
TrackMessage(string.Format("File {0} not found", localPath));
continue;
}
string targetFile = System.IO.Path.Combine(folderLocalPath, System.IO.Path.GetFileName(localPath));
try
{
System.IO.File.Copy(localPath, targetFile, true);
}
catch (System.UnauthorizedAccessException ex)
{
//Access to the path ... is denied - Ignore
TrackWarning(ex.Message);
continue;
}
//Ensure that the file is writeable
var fileAttributes = System.IO.File.GetAttributes(targetFile);
System.IO.File.SetAttributes(targetFile, fileAttributes & ~System.IO.FileAttributes.ReadOnly);
workspace.PendAdd(targetFile);
}
}
public static void Destroy(VersionControlServer vcs, IEnumerable<string> items, bool keepHistory)
{
try
{
foreach (var item in items)
{
var flags = DestroyFlags.Silent | DestroyFlags.StartCleanup;
if (keepHistory)
{
flags |= DestroyFlags.KeepHistory;
}
vcs.Destroy(new ItemSpec(item, RecursionType.Full), VersionSpec.Latest, null, flags);
}
}
catch (Exception ex)
{
TrackWarning(ex.Message);
}
}
/// <summary>
/// Undo changes to unchanged files in the workspace
/// </summary>
/// <param name="workspace">Workspace</param>
public static void UndoUnchanged(Workspace workspace)
{
//Get pending changes
PendingChange[] pendingChanges = workspace.GetPendingChanges();
if (pendingChanges.Length == 0)
{
return;
}
var spec = new ChangesetVersionSpec(workspace.VersionControlServer.GetLatestChangesetId());
var sourceArray = ItemSpec.FromPendingChanges(pendingChanges);
var pendingChangesItems = new ItemSet[0];
if (sourceArray.Length > 0)
{
pendingChangesItems = workspace.VersionControlServer.GetItems(sourceArray, spec, DeletedState.Any, ItemType.Any);
}
//Build redundant change list
var itemsToUndo = new List<ItemSpec>();
var itemsToGet = new List<string>();
for (int j = 0; j < pendingChanges.Length; j++)
{
var pendingChange = pendingChanges[j];
if (pendingChange.IsAdd || pendingChange.IsDelete || pendingChange.IsMerge || (pendingChange.ChangeType & ~ChangeType.Lock) == ChangeType.Edit)
{
Item item = null;
foreach (Item currentItem in pendingChangesItems[j].Items)
{
if (pendingChange.ItemType == currentItem.ItemType && (pendingChange.IsDelete || currentItem.DeletionId == 0))
{
if (pendingChange.IsDelete && currentItem.DeletionId == 0)
{
item = null;
break;
}
if (!pendingChange.IsDelete || item == null || currentItem.DeletionId >= item.DeletionId)
{
item = currentItem;
}
}
}
if (item != null)
{
bool additemToUndo = false;
bool addItemToGet = false;
if (pendingChange.ItemType == ItemType.File)
{
if (pendingChange.IsDelete)
{
additemToUndo = true;
addItemToGet = true;
TrackMessage(string.Format("{0}: {1}", pendingChange.ChangeTypeName, pendingChange.LocalItem));
}
else if (IsMatchesContent(pendingChange.LocalItem, item.HashValue))
{
additemToUndo = true;
if (pendingChange.IsAdd || pendingChange.IsDelete)
{
addItemToGet = true;
}
TrackMessage(string.Format("{0} (contents match): {1}", pendingChange.ChangeTypeName, pendingChange.LocalItem));
}
}
else if (pendingChange.IsAdd || pendingChange.IsDelete)
{
additemToUndo = true;
addItemToGet = true;
TrackMessage(string.Format("{0}: {1}", pendingChange.ChangeTypeName, pendingChange.LocalItem));
}
if (additemToUndo)
{
itemsToUndo.Add(new ItemSpec(pendingChange));
}
if (addItemToGet)
{
itemsToGet.Add(pendingChange.LocalItem);
}
}
}
}
if (itemsToUndo.Count == 0)
{
//No redundant pending changes
TrackMessage("There are no redundant pending changes.");
return;
}
//Undo redundant pending changes
TrackMessage("Undoing redundant changes...");
workspace.Undo(itemsToUndo.ToArray());
if (itemsToGet.Count > 0)
{
//Force get undone adds
TrackMessage("Forcing a get for undone adds and deletes...");
workspace.Get(itemsToGet.ToArray(), spec, RecursionType.None, GetOptions.GetAll | GetOptions.Overwrite);
}
}
#endregion
#region Branch functions
public static ExtendedItem GetExtendedItem(VersionControlServer vcs, string path)
{
var itemSpecs = new ItemSpec[] { new ItemSpec(path, RecursionType.None) };
var getItemsOptions = GetBranchObjectSupported(vcs) ? GetItemsOptions.IncludeBranchInfo : GetItemsOptions.None;
getItemsOptions |= GetItemsOptions.IncludeSourceRenames;
try
{
var extendedItems = vcs.GetExtendedItems(itemSpecs, DeletedState.Any, ItemType.Any, getItemsOptions, null)[0]; //[podle itemSpecs.Length prvků]
if (extendedItems.Length > 0)
{
return extendedItems[0]; //[podle RecursionType]
}
}
catch (System.Xml.XmlException)
{
//Unexpected end of file.
//The data at the root level is invalid. Line 1, position 1.
}
catch (System.IndexOutOfRangeException)
{
//Index was outside the bounds of the array.
}
catch (System.NotSupportedException)
{
//Stream does not support reading.
}
catch (System.IO.IOException)
{
//Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
}
return null;
}
public static HashSet<string> GetAllBranchesList(VersionControlServer vcs, string path)
{
var list = new HashSet<string>();
FillAllBranchesList(vcs, new ItemIdentifier(path), list);
return list;
}
public static BranchHistoryTreeItem GetBranchHistory(VersionControlServer vcs, string path)
{
try
{
return GetBranchHistoryRequestedItem(GetBranchHistoryTree(vcs, path));
}
catch (System.NotSupportedException)
{
//Stream does not support reading.
}
catch (System.IO.InvalidDataException)
{
//Unknown block type. Stream might be corrupted.
}
catch (System.IO.IOException)
{
//Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
}
return null;
}
#endregion
#region Others functions
public static bool IsFolderCloaked(Workspace workspace, string serverItem)
{
if (workspace != null)
{
WorkingFolder folder = workspace.TryGetWorkingFolderForServerItem(serverItem);
if (folder == null)
{
return false;
}
if (folder.IsCloaked)
{
return true;
}
}
return false;
}
public static void Cloak(Workspace workspace, string serverItem)
{
workspace.Cloak(serverItem);
workspace.Get(new string[] { serverItem }, VersionSpec.Latest, RecursionType.Full, GetOptions.None);
}
public static void UnCloak(Workspace workspace, string serverItem)
{
string localItem = null;
WorkingFolder mapping = null;
foreach (WorkingFolder workingFolder in workspace.Folders)
{
if (workingFolder.Type == WorkingFolderType.Cloak)
{
if (serverItem != null && (VersionControlPath.Equals(workingFolder.ServerItem, serverItem) || VersionControlPath.Equals(workingFolder.DisplayServerItem, serverItem)))
{
localItem = workingFolder.LocalItem;
mapping = workingFolder;
break;
}
if (localItem != null && Microsoft.TeamFoundation.Common.FileSpec.Equals(workingFolder.LocalItem, localItem))
{
serverItem = workingFolder.ServerItem;
mapping = workingFolder;
break;
}
}
}
if (mapping != null)
{
workspace.DeleteMapping(mapping);
}
}
public static bool HasRepositoryExtensions(VersionControlServer vcs)
{
if (vcs == null)
{
s_HasRepositoryExtensionsVCS = null;
s_HasRepositoryExtensions = false;
return false;
}
if (vcs != s_HasRepositoryExtensionsVCS)
{
try
{
#if VS2010
//vcs.Repository.Extensions != null;
var versionControlServerType = vcs.GetType();
var repositoryProperty = versionControlServerType.GetProperty("Repository", BindingFlags.NonPublic | BindingFlags.Instance);
object repository = repositoryProperty.GetValue(vcs, new object[0]);
var extensionsProperty = repository.GetType().GetProperty("Extensions", BindingFlags.NonPublic | BindingFlags.Instance);
object extensions = extensionsProperty.GetValue(repository, new object[0]);
s_HasRepositoryExtensionsVCS = vcs;
s_HasRepositoryExtensions = extensions != null;
#else
s_HasRepositoryExtensionsVCS = vcs;
s_HasRepositoryExtensions = vcs.WebServiceLevel >= WebServiceLevel.Tfs2010;
#endif
}
catch (Exception)
{
s_HasRepositoryExtensionsVCS = vcs;
s_HasRepositoryExtensions = false;
}
}
return s_HasRepositoryExtensions;
}
public static bool PendingChangeItemsDirtyCheck(Workspace workspace)
{
try
{
//Get pending changes
PendingChange[] pendingChanges = workspace.GetPendingChanges();
if (pendingChanges.Length == 0)
{
return false;
}
for (int j = 0; j < pendingChanges.Length; j++)
{
var pendingChange = pendingChanges[j];
if (pendingChange.IsEdit && !string.IsNullOrEmpty(pendingChange.LocalItem) && IsItemDirty(pendingChange.LocalItem))
{
return true;
}
}
}
catch (System.IO.IOException)
{
//Unable to read data from the transport connection: The connection was closed.
}
return false;
}
#endregion
#endregion
#region private member functions
private static string GetParentPath(string serverItem)
{
int index = serverItem.LastIndexOf('/');
if (index != -1)
{
if (index == 1)
{
return "$/";
}
return serverItem.Substring(0, index);
}
return null;
}
/// <summary>
/// Undo changes in item
/// </summary>
/// <param name="workspace">Workspace</param>
private static bool UndoUnchangedItem(Workspace workspace, string sourceItem)
{
var spec = new ChangesetVersionSpec(workspace.VersionControlServer.GetLatestChangesetId());
var itemSet = workspace.VersionControlServer.GetItems(new ItemSpec[] { new ItemSpec(sourceItem, RecursionType.None) }, spec, DeletedState.Any, ItemType.Any)[0];
if (itemSet.Items.Length == 0)
{
return false;
}
Item item = itemSet.Items[0];
string localItem = workspace.GetLocalItemForServerItem(item.ServerItem);
if (item.ItemType == ItemType.File && IsMatchesContent(localItem, item.HashValue))
{
//Undo item
workspace.Undo(item.ServerItem);
return true;
}
return false;
}
private static void CopyFiles(string sourcePath, string destPath, bool overwrite, bool noReadOnly)
{
var dir = new System.IO.DirectoryInfo(sourcePath);
if (!System.IO.Directory.Exists(destPath))
{
System.IO.Directory.CreateDirectory(destPath);
}
foreach (var file in dir.GetFiles())
{
string targetFile = System.IO.Path.Combine(destPath, file.Name);
file.CopyTo(targetFile, overwrite);
if (noReadOnly)
{
//Ensure that the file is writeable
var fileAttributes = System.IO.File.GetAttributes(targetFile);
System.IO.File.SetAttributes(targetFile, fileAttributes & ~System.IO.FileAttributes.ReadOnly);
}
}
foreach (var subDir in dir.GetDirectories())
{
string targetDirPath = System.IO.Path.Combine(destPath, subDir.Name);
CopyFiles(System.IO.Path.Combine(sourcePath, subDir.Name), targetDirPath, overwrite, noReadOnly);
}
}
private static bool IsMatchesContent(string path, byte[] hash)
{
try
{
if (!string.IsNullOrEmpty(path) && hash.Length > 0 && File.Exists(path))
{
byte[] buffer = ComputeMD5Hash(path);
return BitConverter.ToString(hash).Equals(BitConverter.ToString(buffer));
}
}
catch (IOException)
{
}
return false;
}
private static byte[] ComputeMD5Hash(string fileName)
{
using (var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
{
try
{
using (var md = new MD5CryptoServiceProvider())
{
return md.ComputeHash(stream);
}
}
catch (InvalidOperationException)
{
return new byte[0];
}
}
}
private static void TrackMessage(string message)
{
TFSSCExplorerExtensionPackage.ReportFailure(String.Format("TFSSCExplorerExtension Message: {0}", message));
}
private static void TrackWarning(string message)
{
TFSSCExplorerExtensionPackage.ReportFailure(String.Format("TFSSCExplorerExtension Warning: {0}", message));
}
private static bool IsItemDirty(string item)
{
Assembly visualStudioVersionControlsAssembly = typeof(VersionControlExt).Assembly;
//Microsoft.VisualStudio.TeamFoundation.VersionControl.ClientHelperVS.IsItemDirty(item);
var clientHelperVSType = visualStudioVersionControlsAssembly.GetType("Microsoft.VisualStudio.TeamFoundation.VersionControl.ClientHelperVS");
return (bool)clientHelperVSType.InvokeMember("IsItemDirty", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Static, null, null, new object[] { item });
}
private static void FillAllBranchesList(VersionControlServer vcs, ItemIdentifier item, HashSet<string> list)
{
var branches = vcs.QueryBranchObjects(item, RecursionType.Full);
foreach (var branche in branches)
{
if (branche.Properties.ParentBranch != null && !list.Contains(branche.Properties.ParentBranch.Item))
{
FillAllBranchesList(vcs, branche.Properties.ParentBranch, list);
}
list.Add(branche.Properties.RootItem.Item);
foreach (var child in branche.ChildBranchesNoClone)
{
list.Add(child.Item);
}
}
}
private static BranchHistoryTreeItem[] GetBranchHistoryTree(VersionControlServer vcs, string path)
{
var item = GetExtendedItem(vcs, path);
if (item == null)
{
return null;
}
var version = new ChangesetVersionSpec(item.VersionLatest);
BranchHistoryTreeItem[][] branchHistory = vcs.GetBranchHistory(new ItemSpec[] { new ItemSpec(path, RecursionType.None) }, version);
if (((branchHistory.Length > 0) && (branchHistory[0].GetLength(0) > 0)) && (branchHistory[0][0].Children.Count > 0))
{
return branchHistory[0];
}
return null;
}
private static BranchHistoryTreeItem GetBranchHistoryRequestedItem(System.Collections.IEnumerable branches)
{
if (branches == null)
{
return null;
}
foreach (BranchHistoryTreeItem item in branches)
{
if (item.Relative.IsRequestedItem)
{
return item;
}
var requestedItem = GetBranchHistoryRequestedItem(item.Children);
if (requestedItem != null)
{
return requestedItem;
}
}
return null;
}
private static bool GetBranchObjectSupported(VersionControlServer vcs)
{
if (vcs == null)
{
return false;
}
return (vcs.WebServiceLevel >= WebServiceLevel.Tfs2010);
}
#endregion
}
}