Example #1
0
        public Task <MergeInfo> MergeBranch(string source, string target, Author author, string message)
        {
            var signature    = getSignature(author);
            var targetBranch = _repo.Branches[target];
            var sourceBranch = _repo.Branches[source];

            if (isTransactionInProgress(target))
            {
                var exceptionMessage = $"There is a transaction in progress for branch {target}. Complete the transaction first.";
                _logger.Warn(exceptionMessage);
                throw new ArgumentException(exceptionMessage);
            }

            lock (getLock(target))
            {
                var mergeRes = _repo.ObjectDatabase.MergeCommits(sourceBranch.Tip, targetBranch.Tip, new MergeTreeOptions());
                if (mergeRes.Status != MergeTreeStatus.Succeeded)
                {
                    var logMessage = $"Could not merge {source} into {target} because of conflicts. Please merge manually";
                    _logger.Trace(logMessage);

                    return(Task.FromResult(new MergeInfo
                    {
                        Message = logMessage,
                        SourceBranch = source,
                        TargetBranch = target,
                        Status = MergeResult.Conflicts,
                        Conflicts = mergeRes.Conflicts.Select(c => new ConflictInfo
                        {
                            SourceSha = c.Ours?.Id.Sha,
                            TargetSha = c.Theirs?.Id.Sha,
                            Path = c.Ours?.Path ?? c.Theirs.Path,
                            Type = object.ReferenceEquals(c.Ours, null) || object.ReferenceEquals(c.Theirs, null) ? ConflictType.Remove : ConflictType.Change
                        }).ToList()
                    }));
                }

                _repo.Branches.Remove(sourceBranch);

                var previousCommit = targetBranch.Tip;
                var tree           = mergeRes.Tree;

                if (previousCommit != null && previousCommit.Tree.Id == tree.Id)
                {
                    return(Task.FromResult(MergeInfo.Succeeded(source, target, string.Empty)));
                }

                var ancestors = previousCommit != null ? new List <Commit> {
                    previousCommit
                } : new List <Commit>();
                var commit = _repo.ObjectDatabase.CreateCommit(signature, signature, message, tree, ancestors, false);

                _repo.Refs.UpdateTarget(_repo.Refs[targetBranch.CanonicalName], commit.Id);

                _logger.Trace($"Squashed and merged {source} into {target} and removed {source} with message {message}");

                push(target);

                return(Task.FromResult(MergeInfo.Succeeded(source, target, commit.Sha)));
            }
        }
Example #2
0
 public void FirstMergesShouldSuccedWithValidInfo() =>
 _firstMergeResult.ShouldBeEquivalentTo(MergeInfo.Succeeded("test2", "master", _commitBeforeSecondMerge));
Example #3
0
 public void SecondMergeShouldSuccedWithValidInfo() =>
 _secondMergeResult.ShouldBeEquivalentTo(MergeInfo.Succeeded("test", "master", _commitAfterSecondMerge));
Example #4
0
 public void MergeShouldSuccedWithValidInfo() =>
 _mergeResult.ShouldBeEquivalentTo(MergeInfo.Succeeded("test", "master", string.Empty));