/// <summary> /// The list of merge targets /// </summary> public IEnumerable <ITfsBranch> GetPossibleMergeTargetBranches(ITfsBranch sourceBranch, BranchSearchOptions searchOptions = BranchSearchOptions.Both) { if (sourceBranch.IsSubBranch) { return(sourceBranch.ChildBranches.AsEnumerable()); } var result = new ObservableCollection <ITfsBranch>(); var listOfForeignBranchesReferencingSourceBranch = (searchOptions == BranchSearchOptions.Both || searchOptions == BranchSearchOptions.Upwards) ? CompleteBranchList .Where(item => item.ChildBranchNames.Any(cb => cb == sourceBranch.Name)) : Enumerable.Empty <ITfsBranch>(); var listOfSourceBranchChildren = (searchOptions == BranchSearchOptions.Both || searchOptions == BranchSearchOptions.Downwards) ? sourceBranch.ChildBranchNames .Select(cb => CompleteBranchList.Where(item => item.Name == cb).FirstOrDefault()) : Enumerable.Empty <ITfsBranch>(); return(listOfForeignBranchesReferencingSourceBranch .Union(listOfSourceBranchChildren) .Where(item => item != null) .OrderBy(item => item.Name)); }
/// <summary> /// Acquires the list of possible merge candidates from the given source to destination branch /// </summary> /// <param name="source">The source branch</param> /// <param name="destination">The target branch</param> /// <returns>List of changesets</returns> public IEnumerable <ITfsChangeset> GetMergeCandidatesForBranchToBranch(ITfsBranch source, ITfsBranch destination, string sourcePathFilter = null) { string sourcePath = null, targetPath = null; if (sourcePathFilter != null) { sourcePath = sourcePathFilter; } else { sourcePath = source.ServerPath; } if (sourcePath != source.ServerPath) { targetPath = GetPathInTargetBranch(destination, sourcePath); if (targetPath == null) { sourcePath = source.ServerPath; targetPath = destination.ServerPath; } } else { targetPath = destination.ServerPath; } return (VersionControlServer.GetMergeCandidates(sourcePath, targetPath, RecursionType.Full) .Select(item => new TfsChangeset(item.Changeset))); }
public IEnumerable <TfsChangesetWrapper> QueryChangesets(ITfsBranch sourceBranch, ITfsBranch targetBranch, string sourcePathFilter = null) { return (Model.Repository.Instance.TfsBridgeProvider .GetMergeCandidatesForBranchToBranch(sourceBranch, targetBranch, sourcePathFilter) .Select(item => UpdateChangesetFromCache(new TfsChangesetWrapper(item)))); }
private ITfsChangeset FindChangeset(ITfsChangeset source, ITfsBranch where) { if (source.GetAffectedBranchesForActiveProject().Contains(where)) { return(source); } var foundLinks = AllAssociatedChangesetsIncludingMerges.Where(link => link.Source != null && link.Source.TfsChangeset.Changeset.ChangesetId == source.Changeset.ChangesetId); // This could be more optimized. foreach (var foundLink in foundLinks) { if (foundLink.Target.TfsChangeset.GetAffectedBranchesForActiveProject().Contains(where)) { return(foundLink.Target.TfsChangeset); } } foreach (var foundLink in foundLinks) { var found = FindChangeset(foundLink.Target.TfsChangeset, where); if (found != null) { return(found); } } return(null); }
public void PrepareRefresh() { _availableSourceBranches = null; _sourceBranch = null; _targetBranches = null; _targetBranch = null; _selectedQuery = null; }
public IReadOnlyList <ITfsChange> GetChangesForBranch(ITfsBranch branch) { BuildChangePerBranchDictionary(); List <ITfsChange> changes; if (_changesPerBranch.TryGetValue(branch.Name, out changes) == false) { return(null); } return(changes); }
/// <summary> /// Tries to find the matching item in the target branch. /// </summary> /// <param name="targetBranch">The target branch</param> /// <param name="serverItem">The item</param> /// <returns>The serverItem path in the target branch if found, null otherwise</returns> public string GetPathInTargetBranch(ITfsBranch targetBranch, string serverItem) { var res = VersionControlServer.GetBranchHistory(new ItemSpec[] { new ItemSpec(serverItem, RecursionType.None) }, LatestVersionSpec.Latest); var targetTo = res[0].SelectMany(item => item.Children.Cast <BranchHistoryTreeItem>()).Where(item => item.Relative.BranchToItem.ServerItem.StartsWith(targetBranch.Name, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault(); var targetFrom = res[0].SelectMany(item => item.Children.Cast <BranchHistoryTreeItem>()).Where(item => item.Relative.BranchFromItem.ServerItem.StartsWith(targetBranch.Name, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault(); return(targetTo != null ? targetTo.Relative.BranchToItem.ServerItem : (targetFrom != null ? targetFrom.Relative.BranchFromItem.ServerItem : null)); }
public IEnumerable <MergedChangeset> FindMergesForActiveProject(ITfsBranch source, IEnumerable <ITfsBranch> potentialMergeSourceBranches = null) { var branches = GetAffectedBranchesForActiveProject().ToList(); if (!branches.Contains(source)) { yield break; } if (potentialMergeSourceBranches == null) { potentialMergeSourceBranches = branches; } ExtendedMerge[] results = null; try { results = Repository.Instance.TfsBridgeProvider.VersionControlServer .TrackMerges( new int[] { Changeset.ChangesetId }, source.BranchObject.Properties.RootItem, potentialMergeSourceBranches.Select(branch => branch.BranchObject.Properties.RootItem).ToArray(), null); } catch (Exception) { yield break; } var tempDictionary = new Dictionary <int, ITfsChangeset>(); foreach (var item in results) { ITfsChangeset sourceCS, targetCS; if (tempDictionary.TryGetValue(item.SourceChangeset.ChangesetId, out sourceCS) == false) { sourceCS = new TfsChangeset(Repository.Instance.TfsBridgeProvider.VersionControlServer.GetChangeset(item.SourceChangeset.ChangesetId)); tempDictionary[item.SourceChangeset.ChangesetId] = sourceCS; } if (tempDictionary.TryGetValue(item.TargetChangeset.ChangesetId, out targetCS) == false) { targetCS = new TfsChangeset(Repository.Instance.TfsBridgeProvider.VersionControlServer.GetChangeset(item.TargetChangeset.ChangesetId)); tempDictionary[item.TargetChangeset.ChangesetId] = targetCS; } yield return(new MergedChangeset() { Source = sourceCS, Target = targetCS }); } }
/// <summary> /// Creates a temporary workspace /// </summary> /// <returns>Temporary workspace</returns> public ITfsTemporaryWorkspace GetTemporaryWorkspace(ITfsBranch source, ITfsBranch target) { lock (_locker) { if (_temporaryWorkspaces == null) { _temporaryWorkspaces = new Dictionary <ITfsBranch, Dictionary <ITfsBranch, ITfsTemporaryWorkspace> >(); } if (!_temporaryWorkspaces.ContainsKey(source)) { _temporaryWorkspaces[source] = new Dictionary <ITfsBranch, ITfsTemporaryWorkspace>(); } if (_temporaryWorkspaces[source].ContainsKey(target)) { try { var existingWs = _temporaryWorkspaces[source][target]; var ws = VersionControlServer.QueryWorkspaces(existingWs.TfsWorkspace.Name, TfsTeamProjectCollection.ConfigurationServer.AuthorizedIdentity.UniqueName, Environment.MachineName); if (ws.Any()) { return(existingWs); } } catch (Exception) { } } string randomWorkspaceName; string localMapping; bool found = false; do { randomWorkspaceName = "vMerge" + Process.GetCurrentProcess().Id.ToString() + "." + Guid.NewGuid().ToString().Replace("-", "").Replace("{", "").Replace("}", "").Substring(0, 6); var ws = VersionControlServer.QueryWorkspaces(randomWorkspaceName, TfsTeamProjectCollection.ConfigurationServer.AuthorizedIdentity.UniqueName, Environment.MachineName); found = ws.Any(); localMapping = Path.Combine(GetBasePath(), randomWorkspaceName); if (Directory.Exists(localMapping)) { found = false; } } while (found); var tfsWorkspace = VersionControlServer.CreateWorkspace(randomWorkspaceName); tfsWorkspace.Map("$/", localMapping); var workspace = new TfsTemporaryWorkspace(this, tfsWorkspace, source, localMapping, target.Name); _temporaryWorkspaces[source][target] = workspace; return(workspace); } }
public static void ShowNoMergeCandidatesMessageBox(ITfsBranch from, ITfsBranch to) { var mbvm = new MessageBoxViewModel( "No merge candidates", String.Format( "There are no pending merges from branch\r\n" + "{0}\r\n" + "to branch\r\n" + "{1}", from.Name, to.Name), MessageBoxViewModel.MessageBoxButtons.OK); Repository.Instance.ViewManager.ShowModal(mbvm); }
private void LoadChangesets(ITfsBranch sourceBranch, ITfsBranch targetBranch, string sourcePathFilter, BackgroundTask task) { task.TrackProgress.ProgressInfo = "Loading merge candidates ..."; var changesets = new ObservableCollection <TfsChangesetWrapper>(TfsItemCache.QueryChangesets(sourceBranch, targetBranch, sourcePathFilter)); Repository.Instance.BackgroundTaskManager.Post( () => { if (!task.Cancelled.IsCancellationRequested) { SetContent(changesets); } return(true); }); }
internal TfsTemporaryWorkspace(TfsBridgeProvider host, Workspace tfsWorkspace, ITfsBranch sourceBranch, string mappedFolder, string targetFolder) { TfsBridgeProvider = host; SourceBranch = sourceBranch; MappedFolder = mappedFolder; TargetFolder = targetFolder; Conflicts = new List <ITfsMergeConflict>(); PendingChanges = new List <ITfsPendingChange>(); TfsWorkspace = tfsWorkspace; //TfsWorkspace.VersionControlServer.ResolvedConflict += VersionControlServer_ResolvedConflict; //TfsWorkspace.VersionControlServer.Conflict += VersionControlServer_Conflict; //TfsWorkspace.VersionControlServer.NewPendingChange += VersionControlServer_NewPendingChange; //TfsWorkspace.VersionControlServer.PendingChangeCandidatesChanged += VersionControlServer_PendingChangeCandidatesChanged; //TfsWorkspace.VersionControlServer.PendingChangesChanged += VersionControlServer_PendingChangesChanged; }
private ITfsBranch GetSpecificSubBranch(string serverPath) { ITfsBranch subBranch = null; WeakReference cachedSubBranchWeak; lock (_locker) { if (CachedSubBranches.TryGetValue(serverPath, out cachedSubBranchWeak)) { // Intentionally null? if (cachedSubBranchWeak == null) { return(null); } subBranch = cachedSubBranchWeak.Target as ITfsBranch; } } if (subBranch != null) { return(subBranch); } subBranch = CompleteBranchList.FirstOrDefault(cb => cb.ServerPath == serverPath); if (subBranch == null) { subBranch = new TfsBranch(VersionControlServer, serverPath, true); if (subBranch.ChildBranches.Count == 0) { subBranch = null; } } cachedSubBranchWeak = subBranch != null ? new WeakReference(subBranch) : null; lock (_locker) { if (false == CachedSubBranches.ContainsKey(serverPath)) { CachedSubBranches[serverPath] = cachedSubBranchWeak; } } return(subBranch); }
private void LoadWorkItems(ITfsBranch sourceBranch, ITfsBranch targetBranch, string pathFilter, BackgroundTask task) { task.TrackProgress.ProgressInfo = "Loading merge candidates ..."; var changesets = new List <TfsChangesetWrapper>(TfsItemCache.QueryChangesets(sourceBranch, targetBranch, pathFilter)); task.TrackProgress.ProgressInfo = "Loading work items ..."; task.TrackProgress.MaxProgress = changesets.Count; var workItems = new ObservableCollection <TfsWorkItemWrapper>( TfsItemCache.QueryWorkItems(changesets, task.TrackProgress, task.Cancelled.Token)); Repository.Instance.BackgroundTaskManager.Post( () => { if (!task.Cancelled.IsCancellationRequested) { SetContent(workItems); } return(true); }); }
public bool Merge(ITfsBranch targetBranch, string pathFilter, IEnumerable <ITfsChangeset> changesetsAsEnumerable, ITrackProgress trackProgress = null) { SimpleLogger.Checkpoint("Merge: {0}, {1}", targetBranch != null ? targetBranch.Name : null, pathFilter); if (pathFilter != null && !SourceBranch.Name.StartsWith(pathFilter, StringComparison.InvariantCultureIgnoreCase)) { throw new ArgumentException("If a PathFilter is provided, it needs to be below the SourceBranch"); } var changesets = new List <ITfsChangeset>(changesetsAsEnumerable); var files = new List <string>(); if (trackProgress != null) { trackProgress.MaxProgress = changesets.Count * 2 + 2; trackProgress.CurrentProgress = 0; trackProgress.ProgressInfo = "Acquiring file list ..."; } foreach (var changeset in changesets) { SimpleLogger.Checkpoint("Merge: Processing changeset #{0}", changeset != null ? changeset.Changeset.ChangesetId : -1); foreach (var change in changeset.Changes.Select(c => c.Change)) { SimpleLogger.Checkpoint("Merge: change {0}, filter {1}", change.Item.ServerItem, pathFilter); if (pathFilter != null && change.Item.ServerItem.StartsWith(pathFilter, StringComparison.InvariantCultureIgnoreCase) == false) { continue; } files.Add(change.Item.ServerItem); } ++trackProgress.CurrentProgress; } GetRequest[] getRequests = files.Distinct().Select(file => new GetRequest(file, RecursionType.None, VersionSpec.Latest)).ToArray(); if (trackProgress != null) { trackProgress.ProgressInfo = "Getting files ..."; ++trackProgress.CurrentProgress; } SimpleLogger.Checkpoint("Merge: Getting files"); GetStatus gs = TfsWorkspace.Get(getRequests, GetOptions.None); if (trackProgress != null) { trackProgress.ProgressInfo = "Performing merges ..."; ++trackProgress.CurrentProgress; } var resultingConflicts = new List <ITfsMergeConflict>(); foreach (var changeset in changesets) { if (trackProgress != null) { ++trackProgress.CurrentProgress; } var csvs = new ChangesetVersionSpec(changeset.Changeset.ChangesetId); SimpleLogger.Checkpoint("Merge: Performing merge on CS# {0}", changeset != null ? changeset.Changeset.ChangesetId : -1); var mergeResult = TfsWorkspace.Merge( pathFilter ?? SourceBranch.Name, targetBranch.Name, csvs, csvs, LockLevel.None, RecursionType.Full, MergeOptions.ForceMerge); if (mergeResult.NumFailures > 0) { foreach (var failure in mergeResult.GetFailures()) { if (failure.Code == "TF14078" || failure.Message.Contains("TF14078")) { throw new LocalPathTooLongException(failure.Message); } throw new InvalidOperationException(failure.Message); } } } if (trackProgress != null) { trackProgress.CurrentProgress = trackProgress.MaxProgress; } SimpleLogger.Checkpoint("Merge: Refreshing conflicts"); RefreshConflictsWorker(default(CancellationToken)); SimpleLogger.Checkpoint("Merge: Finished"); return(Conflicts.Count != 0); }
private void FindMergesForChangesetAndBranch(List <MergedChangesetLink> results, ITfsChangeset changeset, ITfsBranch rootBranch) { var merges = changeset.FindMergesForActiveProject(rootBranch, _potentialMergeSourceBranches) .Select( item => new MergedChangesetLink() { Source = TfsItemCache.UpdateChangesetFromCache(new TfsChangesetWrapper(item.Source)), Target = TfsItemCache.UpdateChangesetFromCache(new TfsChangesetWrapper(item.Target)) }); results.Add( new MergedChangesetLink() { Source = null, Target = TfsItemCache.UpdateChangesetFromCache(new TfsChangesetWrapper(changeset)) }); results.AddRange(merges); }
/// <summary> /// Acquires the full list of changesets from the given branch /// </summary> /// <param name="branch">The branch</param> /// <returns>List of changesets</returns> public IEnumerable <ITfsChangeset> GetAllChangesetsForBranch(ITfsBranch branch) { throw new NotImplementedException(); }
public ITfsChangeset HasBeenMergedInto(ITfsBranch target) { throw new NotImplementedException(); }