/// <summary> /// commits pending changes for a changeset that have been merged to the specified target and associates specified work items and comment /// </summary> /// <param name="changeset"></param> /// <param name="environment"></param> /// <param name="comment"></param> /// <returns></returns> public Changeset CommitChangeset(Changeset changeset, MergeEnvironment environment, string comment) { var tfs = TfsTeamDataAccess.GetTfsTeamProjectCollection(); var versionControl = tfs.GetService <VersionControlServer>(); var workspace = versionControl.GetWorkspace(Workstation.Current.Name, tfs.AuthorizedIdentity.UniqueName); var tfsChangeset = versionControl.GetChangeset(changeset.Id); var changes = (from change in tfsChangeset.Changes select change).ToList(); var relationship = GetMergeRelationship(changeset, environment); var pending = workspace.GetPendingChanges(changes .Select(m => new ItemSpec(m.Item.ServerItem.ToLower() .Replace(string.Format("/{0}/", changeset.Branch.Name.ToLower()), string.Format("/{0}/", relationship.Target.Name)), RecursionType.None)).ToArray(), false, int.MaxValue, null, true).ToList(); var pendingChangesetChanges = pending.ToArray(); //.Where(p => p.IsMerge && p.MergeSources.Any(source => changes.Any(change => string.Compare(change.Item.ServerItem, source.ServerItem, StringComparison.OrdinalIgnoreCase) == 0))).ToArray(); return(Commit(workspace, pendingChangesetChanges, comment, changeset.WorkItems)); }
/// <summary> /// determines merge relationship for a changeset and target environment /// </summary> /// <param name="changeset"></param> /// <param name="environment"></param> /// <returns></returns> private static MergeRelationship GetMergeRelationship(Changeset changeset, MergeEnvironment environment) { return(GetMergeRelationship(changeset.Branch, environment)); }
/// <summary> /// merges a changeset for the specified environment /// </summary> /// <param name="changeset"></param> /// <param name="environment"></param> /// <returns></returns> public MergeStatus MergeChangeset(Changeset changeset, MergeEnvironment environment) { var tfs = TfsTeamDataAccess.GetTfsTeamProjectCollection(); var versionControl = tfs.GetService <VersionControlServer>(); var workspace = versionControl.GetWorkspace(Workstation.Current.Name, tfs.AuthorizedIdentity.UniqueName); var tfsChangeset = versionControl.GetChangeset(changeset.Id); var statusList = new List <MergeStatus>(); tfsChangeset.Changes.ToList().ForEach(change => { var sourcePath = change.Item.ServerItem.Substring(0, change.Item.ServerItem.LastIndexOf("/", StringComparison.Ordinal)); sourcePath = !sourcePath.EndsWith("/") ? sourcePath + "/" : sourcePath; var mergeRelationship = GetMergeRelationship(changeset, environment); if (mergeRelationship == null) { statusList.Add(new MergeStatus { NumFailures = 1, Message = string.Format("There are no merge relationships configured for {0}", changeset.Branch.Name) }); return; } var targetPath = sourcePath.ToLower().Replace(string.Format("/{0}/", changeset.Branch.Name.ToLower()), string.Format("/{0}/", mergeRelationship.Target.Name)); if (string.Compare(sourcePath, targetPath, StringComparison.OrdinalIgnoreCase) == 0) // this happens with feature branches. They will get picked up on next "changeset". { return; } // Get Latest first string[] itemsSpec = { targetPath }; workspace.Get(itemsSpec, VersionSpec.Latest, RecursionType.Full, GetOptions.Overwrite); // Get ready to Merge. MergeStatus status; var verSpec = new ChangesetVersionSpec(tfsChangeset.ChangesetId); try { status = MapMergeStatus(workspace.Merge(sourcePath, targetPath, verSpec, verSpec, LockLevel.None, RecursionType.Full, MergeOptions.None)); } catch (Exception e) { status = new MergeStatus { NumFailures = 1, Message = e.Message }; } var conflicts = workspace.QueryConflicts(new[] { targetPath }, true); conflicts.ToList().ForEach(conflict => { workspace.MergeContent(conflict, false); if (conflict.ContentMergeSummary.TotalConflicting > 0) { return; } // Conflict was resolved. Does not require a human! conflict.Resolution = Resolution.AcceptMerge; // If the conflict is successfully resolved, the IsResolved property is set to true. // If resolving this conflict caused other conflicts to be deleted besides the current conflict, the list of other deleted conflicts appears in resolvedConflicts. Conflict[] resolvedConflicts; workspace.ResolveConflict(conflict, out resolvedConflicts); if (!conflict.IsResolved) { return; } var totalResolved = resolvedConflicts.Count(); status.NumResolvedConflicts = status.NumResolvedConflicts + 1 + totalResolved; status.NumConflicts = status.NumConflicts - 1 - totalResolved; }); statusList.Add(status); }); return(new MergeStatus // create summary of all merges for this changeset { HaveResolvableWarnings = statusList.Any(s => s.HaveResolvableWarnings), NoActionNeeded = statusList.All(s => s.NoActionNeeded), NumBytes = statusList.Sum(s => s.NumBytes), NumConflicts = statusList.Sum(s => s.NumConflicts), NumFailures = statusList.Sum(s => s.NumFailures), NumFiles = statusList.Sum(s => s.NumFiles), NumOperations = statusList.Sum(s => s.NumOperations), NumResolvedConflicts = statusList.Sum(s => s.NumResolvedConflicts), NumUpdated = statusList.Sum(s => s.NumUpdated), NumWarnings = statusList.Sum(s => s.NumWarnings) }); }