示例#1
0
        private void LoadChangesetList(bool refresh = false)
        {
            if (_changesetLoadingTaskActive)
            {
                if (!refresh)
                {
                    return;
                }
            }

            _changesetLoadingTaskActive = true;
            Repository.Instance.BackgroundTaskManager.Start(
                Constants.Tasks.LoadChangesetListKey,
                refresh ? ChangesetsRefreshing : ChangesetsLoading,
                (task) =>
            {
                var results = new List <ChangesetListElement>();
                task.TrackProgress.ProgressInfo = "Loading changesets ...";
                lock (_changesetLock)
                {
                    int count = 0;
                    foreach (var changeset in _changesets)
                    {
                        task.TrackProgress.ProgressInfo = string.Format("Loading changesets ({0} done) ...", ++count);
                        var source = FindChangeset(changeset, MergeSource);
                        var target = FindChangeset(changeset, MergeTarget);

                        var changesetListElement =
                            new ChangesetListElement()
                        {
                            Changeset   = TfsItemCache.UpdateChangesetFromCache(new TfsChangesetWrapper(changeset)),
                            CanBeMerged = (target == null),

                            SourceExists      = (source != null),
                            SourceCheckinDate = (source != null) ? source.Changeset.CreationDate : DateTime.MinValue,
                            SourceCheckinId   = (source != null) ? source.Changeset.ChangesetId : 0,

                            TargetExists      = (target != null),
                            TargetCheckinDate = (target != null) ? new DateTime?(target.Changeset.CreationDate) : null,
                            TargetCheckinId   = (target != null) ? target.Changeset.ChangesetId : 0
                        };
                        DetermineWarningStatus(changesetListElement);
                        results.Add(changesetListElement);
                    }
                }
                Repository.Instance.BackgroundTaskManager.Post(
                    () =>
                {
                    _changesetLoadingTaskActive = false;
                    _changesetList = results;
                    RaisePropertyChanged("ChangesetList");
                    return(true);
                });
            });
        }
示例#2
0
        private void AutoMerge()
        {
            try
            {
                var confirm = new MessageBoxViewModel("vMerge: AutoMerge all changesets", "All changesets will be merged silently as long as no conflict arises. Are you really sure to proceed?", MessageBoxViewModel.MessageBoxButtons.None);
                var goOn    = new MessageBoxViewModel.MessageBoxButton("Merge silently");
                var cancel  = new MessageBoxViewModel.MessageBoxButton("Cancel");

                confirm.ConfirmButtons.Add(goOn);
                confirm.ConfirmButtons.Add(cancel);
                Repository.Instance.ViewManager.ShowModal(confirm);
                if (goOn.IsChecked)
                {
                    ChangesetListElement conflictingChangeset = null;
                    Repository.Instance.BackgroundTaskManager.RunWithCancelDialog(
                        (progressParams) =>
                    {
                        progressParams.TrackProgress.MaxProgress = ChangesetList.Where(item => item.CanBeMerged).Count();
                        foreach (var changeset in ChangesetList.Where(item => item.CanBeMerged).OrderBy(item => item.SourceCheckinId))
                        {
                            progressParams.TrackProgress.Increment();
                            progressParams.CancellationToken.ThrowIfCancellationRequested();

                            var copy = progressParams.CloneWithoutIncrements();
                            if (!PerformMerge(changeset, copy))
                            {
                                SimpleLogger.Log(SimpleLogLevel.Info, "Merge conflict in: " + changeset.SourceCheckinId + " " + changeset.SourceComment);
                                conflictingChangeset = changeset;
                                break;
                            }
                        }
                    }, "Merging changesets ...");

                    if (conflictingChangeset != null)
                    {
                        var comment = conflictingChangeset.SourceComment;
                        if (comment.Length > 80)
                        {
                            comment = comment.Substring(0, 77) + "...";
                        }
                        var cancelled = new MessageBoxViewModel("vMerge: AutoMerge all changesets", String.Format("AutoMerge has stopped due to a conflict caused by changeset #{0} (comment: \"{1}\").\r\nPlease merge the remaining changesets manually.", conflictingChangeset.SourceCheckinId, comment), MessageBoxViewModel.MessageBoxButtons.OK);
                        Repository.Instance.ViewManager.ShowModal(cancelled);
                    }

                    LoadAllAssociatedChangesetsIncludingMerges(true);
                }
            } catch (Exception ex)
            {
                SimpleLogger.Log(ex, true, false);
            }
        }
示例#3
0
        private void DetermineWarningStatus(ChangesetListElement changesetListElement)
        {
            if (changesetListElement.TargetCheckinId != 0)
            {
                return;
            }

            if (changesetListElement.SourceCheckinId == 0)
            {
                changesetListElement.HasWarning  = true;
                changesetListElement.WarningText =
                    "This changeset has not yet been merged to the selected source branch.";
                changesetListElement.CanBeMerged = false;
                return;
            }

            TfsChangesetWrapper sourceCS =
                TfsItemCache.GetChangesetFromCache(changesetListElement.SourceCheckinId);

            bool anyChangeNotInFilter
                = PathFilter == null ? false :
                  sourceCS.TfsChangeset.GetAllChanges()
                  .Any(change => !change.Change.Item.ServerItem.StartsWith(PathFilter));

            bool allChangesNotInFilter
                = PathFilter == null ? false :
                  sourceCS.TfsChangeset.GetAllChanges()
                  .All(change => !change.Change.Item.ServerItem.StartsWith(PathFilter));

            if (anyChangeNotInFilter || allChangesNotInFilter)
            {
                changesetListElement.HasWarning = true;
                if (allChangesNotInFilter)
                {
                    changesetListElement.WarningText =
                        "No change in this changeset is part of the merge due to the path filter selection.";
                    changesetListElement.CanBeMerged = false;
                }
                else if (anyChangeNotInFilter)
                {
                    changesetListElement.WarningText =
                        "Some changes in this changeset are not part of the merge due to the path filter selection.";
                }
            }
        }
示例#4
0
        bool PerformMerge(ChangesetListElement item, TrackProgressParameters externalProgress = null)
        {
            bool returnValue = false;

            if (item == null)
            {
                return(false);
            }

            var tempWorkspace  = Repository.Instance.TfsBridgeProvider.GetTemporaryWorkspace(MergeSource, MergeTarget);
            var mergeChangeset = TfsItemCache.GetChangesetFromCache(item.SourceCheckinId).TfsChangeset;

            bool finished = Repository.Instance.BackgroundTaskManager.RunWithCancelDialog(
                (progressParams) =>
            {
                tempWorkspace.Merge(
                    MergeTarget, PathFilter,
                    new ITfsChangeset[] { mergeChangeset }.AsEnumerable(),
                    progressParams.TrackProgress);
            }, String.Format("Merging changeset #{0} ...", item.SourceCheckinId), externalProgress);

            if (!finished)
            {
                tempWorkspace.UndoAllPendingChanges();
                return(false);
            }

            var checkInSummary = new CheckInSummaryViewModel();

            tempWorkspace.RefreshConflicts();
            checkInSummary.Changes =
                tempWorkspace.PendingChanges
                .Select(
                    change => new CheckInSummaryViewModel.PendingChangeWithConflict(
                        change,
                        tempWorkspace.Conflicts.Where(conflict => conflict.ServerPath == change.ServerPath).FirstOrDefault()))
                .ToList();

            while (tempWorkspace.Conflicts.Count != 0)
            {
                int oldConflictsCount = tempWorkspace.Conflicts.Count;
                Repository.Instance.TfsUIInteractionProvider.ResolveConflictsPerTF(tempWorkspace.MappedFolder);
                tempWorkspace.RefreshConflicts();
                if (tempWorkspace.Conflicts.Count == oldConflictsCount)
                {
                    MessageBoxViewModel mbvm = new MessageBoxViewModel("Cancel merge?", "There are conflicts remaining to be solved. Really cancel the merge?", MessageBoxViewModel.MessageBoxButtons.None);
                    var yesButton            = new MessageBoxViewModel.MessageBoxButton("_Yes");
                    mbvm.ConfirmButtons.Add(yesButton);
                    mbvm.ConfirmButtons.Add(new MessageBoxViewModel.MessageBoxButton("_No"));
                    Repository.Instance.ViewManager.ShowModal(mbvm);

                    if (yesButton.IsChecked)
                    {
                        finished = false;
                        break;
                    }
                }
            }

            if (finished)
            {
                checkInSummary.TemporaryWorkspace  = tempWorkspace;
                checkInSummary.OriginalChangesets  = new ITfsChangeset[] { item.Changeset.TfsChangeset }.ToList();
                checkInSummary.SourceChangesets    = new ITfsChangeset[] { mergeChangeset }.ToList();
                checkInSummary.AssociatedWorkItems = item.Changeset.TfsChangeset.RelatedWorkItems;
                checkInSummary.CheckInComment      = BuildCheckInComment(
                    item.Changeset.TfsChangeset, mergeChangeset);

                if (externalProgress == null)
                {
                    var view = Repository.Instance.ViewManager.CreateViewFor(checkInSummary);
                    view.Finished += CheckInDialogClosed;
                }
                else
                {
                    checkInSummary.Cancelled = false;
                    CommitMerge(checkInSummary, externalProgress);
                }
                returnValue = true;
            }
            else
            {
                tempWorkspace.UndoAllPendingChanges();
            }
            return(returnValue);
        }
示例#5
0
        bool PerformMerge(ChangesetListElement item, TrackProgressParameters externalProgress = null)
        {
            SimpleLogger.Checkpoint("PerformMerge: Starting");
            bool returnValue        = false;
            bool undoPendingChanges = true;

            if (item == null)
            {
                return(false);
            }

            SimpleLogger.Checkpoint("PerformMerge: Getting temporary workspace");
            var tempWorkspace = Repository.Instance.TfsBridgeProvider.GetTemporaryWorkspace(MergeSource, MergeTarget);

            SimpleLogger.Checkpoint("PerformMerge: Undoing pending changes in temporary workspace");
            tempWorkspace.UndoAllPendingChanges();

            try
            {
                var mergeChangeset = TfsItemCache.GetChangesetFromCache(item.SourceCheckinId).TfsChangeset;

                bool finished = false;
                try
                {
                    finished = Repository.Instance.BackgroundTaskManager.RunWithCancelDialog(
                        (progressParams) =>
                    {
                        tempWorkspace.Merge(
                            MergeTarget, PathFilter,
                            new ITfsChangeset[] { mergeChangeset }.AsEnumerable(),
                            progressParams.TrackProgress);
                    }, String.Format("Merging changeset #{0} ...", item.SourceCheckinId), externalProgress);
                }
                catch (AggregateException ex)
                {
                    bool otherExceptions = false;
                    foreach (var iex in ex.InnerExceptions)
                    {
                        if (iex is LocalPathTooLongException)
                        {
                            DisplayPathTooLongHelp();
                        }
                        else
                        {
                            SimpleLogger.Log(ex, false, false);
                            otherExceptions = true;
                        }
                    }
                    if (otherExceptions)
                    {
                        SimpleLogger.Log(ex, true);
                    }
                }
                catch (LocalPathTooLongException)
                {
                    DisplayPathTooLongHelp();
                    return(false);
                }
                catch (Exception ex)
                {
                    SimpleLogger.Log(ex);
                    return(false);
                }

                if (!finished)
                {
                    return(false);
                }

                SimpleLogger.Checkpoint("PerformMerge: Building check-in summary");
                var checkInSummary = new CheckInSummaryViewModel();
                SimpleLogger.Checkpoint("PerformMerge: Refreshing conflicts");
                tempWorkspace.RefreshConflicts();
                SimpleLogger.Checkpoint("PerformMerge: Refreshing pending changes");
                tempWorkspace.RefreshPendingChanges();
                checkInSummary.SourceBranch = MergeSource;
                checkInSummary.TargetBranch = MergeTarget;
                checkInSummary.Changes      =
                    tempWorkspace.PendingChanges
                    .Select(
                        change => new CheckInSummaryViewModel.PendingChangeWithConflict(
                            change,
                            tempWorkspace.Conflicts.Where(conflict => conflict.ServerPath == change.ServerPath).FirstOrDefault()))
                    .ToList();

                // Automerging but conflicts?
                if (externalProgress != null && tempWorkspace.Conflicts.Count != 0)
                {
                    return(false);
                }

                bool hadConflicts = ResolveConflicts(tempWorkspace, ref finished);

                if (finished)
                {
                    SimpleLogger.Checkpoint("PerformMerge: Finished");
                    if (!item.OriginalChangesetLoaded)
                    {
                        FindOriginalChangeset(item.SourceCheckinId);
                    }

                    checkInSummary.TemporaryWorkspace = tempWorkspace;

                    var originalCsWrapper = item.OriginalChangesetLoaded ? TfsItemCache.GetChangesetFromCache(item.OriginalChangesetId) : null;
                    var originalCs        = originalCsWrapper != null ? originalCsWrapper.TfsChangeset : null;
                    checkInSummary.OriginalChangesets  = new ITfsChangeset[] { originalCs ?? mergeChangeset }.ToList();
                    checkInSummary.SourceChangesets    = new ITfsChangeset[] { mergeChangeset }.ToList();
                    checkInSummary.AssociatedWorkItems = item.SourceChangeset.RelatedWorkItems;
                    checkInSummary.CheckInComment      = BuildCheckInComment(
                        item.SourceChangeset, mergeChangeset);

                    if (hadConflicts || (externalProgress == null && AutoMergeDirectly == false))
                    {
                        SimpleLogger.Checkpoint("PerformMerge: Showing check-in dialog");

                        if (Repository.Instance.Settings.FetchSettings <bool>(Constants.Settings.PerformNonModalMergeKey))
                        {
                            undoPendingChanges = false;
                            EmbeddedCheckInSummaryViewModel           = checkInSummary;
                            _temporaryWorkspace                       = tempWorkspace;
                            EmbeddedCheckInSummaryViewModel.Finished += EmbeddedCheckInSummaryViewModel_Finished;
                        }
                        else
                        {
                            Repository.Instance.ViewManager.ShowModal(checkInSummary);
                        }

                        if (!checkInSummary.Cancelled)
                        {
                            CommitMerge(checkInSummary);
                        }
                    }
                    else
                    {
                        SimpleLogger.Checkpoint("PerformMerge: Check-in automatically cancelled");
                        checkInSummary.Cancelled = false;
                        CommitMerge(checkInSummary, externalProgress);
                    }
                    returnValue = !hadConflicts;
                }
                else
                {
                    SimpleLogger.Checkpoint("PerformMerge: Not finished");
                }
            }
            finally
            {
                if (undoPendingChanges)
                {
                    SimpleLogger.Checkpoint("PerformMerge: Undoing pending changes");
                    tempWorkspace.UndoAllPendingChanges();
                }
                else
                {
                    SimpleLogger.Checkpoint("PerformMerge: NOT undoing pending changes");
                }
            }
            SimpleLogger.Checkpoint("PerformMerge: Returning");
            return(returnValue);
        }
示例#6
0
        private void LoadAllAssociatedChangesetsIncludingMergesTask(BackgroundTask task)
        {
            task.TrackProgress.ProgressInfo = "Loading ...";
            var results = new List <ChangesetListElement>();

            lock (_changesetLock)
            {
                int count = 0;

                task.TrackProgress.ProgressInfo = "Determining merge status ...";
                var candidates = Repository.Instance.TfsBridgeProvider.GetMergeCandidatesForBranchToBranch(MergeSource, MergeTarget, PathFilter).ToList();

                count = 0;
                foreach (var changeset in Changesets)
                {
                    task.TrackProgress.ProgressInfo = string.Format("Tracking changesets ({0} done) ...", ++count);
                    MergedChangeset mergedCs;
                    if (candidates.Any(mergecs => mergecs.Changeset.ChangesetId == changeset.Changeset.ChangesetId))
                    {
                        mergedCs = new MergedChangeset()
                        {
                            Source = changeset,
                            Target = null
                        };
                    }
                    else
                    {
                        mergedCs = changeset.FindMergesForActiveProject(MergeSource, (new ITfsBranch[1] {
                            MergeTarget
                        })).FirstOrDefault();

                        if (mergedCs.Source != null && mergedCs.Target.Changeset.ChangesetId == changeset.Changeset.ChangesetId)
                        {
                            var temp = mergedCs.Source;
                            mergedCs.Source = mergedCs.Target;
                            mergedCs.Target = temp;
                        }
                    }

                    if (mergedCs.Source != null)
                    {
                        var csl = new ChangesetListElement()
                        {
                            CanBeMerged       = mergedCs.Target == null,
                            SourceChangeset   = changeset,
                            SourceComment     = changeset.Description,
                            SourceCheckinDate = changeset.Changeset.CreationDate,
                            SourceCheckinId   = changeset.Changeset.ChangesetId,
                            SourceExists      = true,
                            TargetCheckinDate = (mergedCs.Target != null ? new DateTime?(mergedCs.Target.Changeset.CreationDate) : null),
                            TargetCheckinId   = (mergedCs.Target != null ? mergedCs.Target.Changeset.ChangesetId : 0),
                            TargetExists      = mergedCs.Target != null
                        };
                        results.Add(csl);
                    }
                }
            }

            Repository.Instance.BackgroundTaskManager.Post(
                () =>
            {
                _allAssociatedChangesetsIncludingMergesLoadingTaskActive = false;
                ChangesetsRefreshing.IsLoading = false;
                ChangesetsLoading.IsLoading    = false;
                ChangesetList = results;
                return(true);
            });
        }