/// <summary> /// Does the main merge operation for selected items and checks-in every changeset. /// </summary> /// <param name="mfrm">The UserControl.</param> /// <param name="lvcoll">The Collection of ListViewItems.</param> /// <param name="trg">The target path.</param> internal static void DoMerge(UserControl mfrm, IEnumerable<ListViewItem> lvcoll, string trg) { Workspace wrkspc = Utilities.vcext.Explorer.Workspace; if (!ServerItemExists(trg)) { MessageBox.Show("Target server path is cloacked or doesn't exist.", Utilities.AppTitle); return; } if (wrkspc.GetPendingChanges().Length > 0) { MessageBox.Show("Please resolve all pending changes before going on.", Utilities.AppTitle); return; } //object prgmerge = CreateProgressMerge(vcsrv); //ShowProgressMerge(prgmerge, mfrm); int idx = 0; bool bcanceled = false; int icanceled; var dlg = Utilities.CreateThreadedWaitDialog("Merging changesets", "Stating changesets merge...", "status", 100); ErrorHandler.ThrowOnFailure(dlg.UpdateProgress("Merging changesets", "Stating changesets merge...", "status", idx++, 100, false, out bcanceled)); if (bcanceled) return; foreach (var lvItem in lvcoll) { string MergeTypeText = lvItem.SubItems[MergeTypeIndex].Text; if (MergeTypeText == "none") continue; Changeset ch = Utilities.vcsrv.GetChangeset((lvItem.Tag as ListViewItemTag).ChangesetID); Utilities.OutputCommandString("Preparing for merge changeset: " + ch.ChangesetId); if (LinkWorkItems) { foreach (var workItm in ch.WorkItems) Utilities.OutputCommandString("Associated WorkItem: " + workItm.Id); } ErrorHandler.ThrowOnFailure(dlg.UpdateProgress("Merging changesets", "Merging changeset: " + ch.ChangesetId, "status", idx++, 100, false, out bcanceled)); if (bcanceled) return; var chverspc = new ChangesetVersionSpec(ch.ChangesetId); Utilities.OutputCommandString("Changeset Version: " + chverspc.DisplayString); MergeOptionsEx mergeType = (MergeTypeText == "baseless" ? MergeOptionsEx.Baseless : MergeTypeText == "force" ? MergeOptionsEx.ForceMerge : MergeOptionsEx.None); mergeType |= mergeOptions; GetStatus sts = wrkspc.Merge((lvItem.Tag as ListViewItemTag).sourcePath, trg, chverspc, chverspc, LockLevel.Unchanged, RecursionType.Full, mergeType); Utilities.OutputCommandString("Merge summary: MergeOptionsEx=" + mergeType + ", NoActionNeeded=" + sts.NoActionNeeded + ", NumFailures=" + sts.NumFailures + ", NumOperations=" + sts.NumOperations + ", NumUpdated=" + sts.NumUpdated + ", NumWarnings=" + sts.NumWarnings); if (mergeOptions != MergeOptionsEx.NoMerge) { while (wrkspc.QueryConflicts(ch.Changes.Select(x => x.Item.ServerItem).ToArray(), true).Length > 0) { //foreach (var conflict in conflicts) wrkspc.ResolveConflict(conflict); DialogResult res = MessageBox.Show("Merge conflicts where found. Resolve them or click Cancel to break merge operaton.", "Merge conflicts", MessageBoxButtons.OKCancel); if (res == DialogResult.Cancel) { ErrorHandler.ThrowOnFailure(dlg.EndWaitDialog(out icanceled)); return; } if (mfrm.InvokeRequired) { var asynchres = mfrm.BeginInvoke(new MethodInvoker(Utilities.ShowResolveConflictsDlg)); mfrm.EndInvoke(asynchres); } else { Utilities.ShowResolveConflictsDlg(); } } var pendingCh = wrkspc.GetPendingChanges();//ch.Changes.Select(x => new ItemSpec(x.Item.ServerItem, RecursionType.Full, x.Item.DeletionId)).ToArray(), true).ToArray(); if (pendingCh.Length == 0) { Utilities.OutputCommandString("No pending changes found."); continue; } var wrkitmch = (LinkWorkItems ? ch.WorkItems.Select(x => new WorkItemCheckinInfo(x, WorkItemCheckinAction.Associate)).ToArray() : null); foreach (var pendChItem in pendingCh) Utilities.OutputCommandString("Found pending change " + pendChItem.ChangeTypeName + ": " + pendChItem.SourceServerItem); int newchid = wrkspc.CheckIn(pendingCh, ch.Committer, ch.Comment, ch.CheckinNote, wrkitmch, null, CheckinOptions.SuppressEvent); Utilities.OutputCommandString("Created new changeset: " + newchid); } if (idx == 100) idx = 0; } ErrorHandler.ThrowOnFailure(dlg.EndWaitDialog(out icanceled)); //CloseProgressMerge(prgmerge); }