public IEnumerable<string> Sync(Diff diff, SyncOutput expectedOutput, IEnumerable<string> labelsToApplyOnPullRequests = null) { var labels = labelsToApplyOnPullRequests == null ? new string[]{ } : labelsToApplyOnPullRequests.ToArray(); if (labels.Any() && expectedOutput != SyncOutput.CreatePullRequest) { throw new InvalidOperationException(string.Format("Labels can only be applied in '{0}' mode.", SyncOutput.CreatePullRequest)); } var t = diff.Transpose(); var branchName = "SyncOMatic-" + DateTimeOffset.UtcNow.ToString("yyyyMMdd-HHmmss"); foreach (var updatesPerOwnerRepositoryBranch in t.Values) { var root = updatesPerOwnerRepositoryBranch.First().Item1.RootTreePart; var tt = new TargetTree(root); foreach (var change in updatesPerOwnerRepositoryBranch) { var source = change.Item2; var destination = change.Item1; tt.Add(destination, source); } var btt = BuildTargetTree(tt); var parentCommit = gw.RootCommitFrom(root); var c = gw.CreateCommit(btt, root.Owner, root.Repository, parentCommit.Sha); switch (expectedOutput) { case SyncOutput.CreateCommit: yield return "https://github.com/" + root.Owner + "/" + root.Repository + "/commit/" + c; break; case SyncOutput.CreateBranch: branchName = gw.CreateBranch(root.Owner, root.Repository, branchName, c); yield return "https://github.com/" + root.Owner + "/" + root.Repository + "/compare/" + UrlSanitize(root.Branch) + "..." + UrlSanitize(branchName); break; case SyncOutput.CreatePullRequest: branchName = gw.CreateBranch(root.Owner, root.Repository, branchName, c); var prNumber = gw.CreatePullRequest(root.Owner, root.Repository, branchName, root.Branch); gw.ApplyLabels(root.Owner, root.Repository, prNumber, labels); yield return "https://github.com/" + root.Owner + "/" + root.Repository + "/pull/" + prNumber; break; default: throw new NotSupportedException(); } } }