예제 #1
0
        List <BranchCommit> GetMergeCommitsForBranch(Branch branch, Branch[] excludedBranches)
        {
            if (mergeBaseCommitsCache.ContainsKey(branch))
            {
                Logger.WriteDebug($"Cache hit for getting merge commits for branch {branch.CanonicalName}.");
                return(mergeBaseCommitsCache[branch]);
            }

            var currentBranchConfig = configuration.GetConfigForBranch(branch.NameWithoutRemote());
            var regexesToCheck      = currentBranchConfig == null
                ? new[] { ".*" } // Match anything if we can't find a branch config
                : currentBranchConfig.SourceBranches.Select(sb => configuration.Branches[sb].Regex);
            var branchMergeBases = Repository.Branches
                                   .ExcludingBranches(excludedBranches)
                                   .Where(b =>
            {
                if (b == branch)
                {
                    return(false);
                }
                var branchCanBeMergeBase = regexesToCheck.Any(regex => Regex.IsMatch(b.FriendlyName, regex));

                return(branchCanBeMergeBase);
            })
                                   .Select(otherBranch =>
            {
                if (otherBranch.Tip == null)
                {
                    Logger.WriteWarning(string.Format(missingTipFormat, otherBranch.FriendlyName));
                    return(BranchCommit.Empty);
                }

                var findMergeBase = FindMergeBase(branch, otherBranch);
                return(new BranchCommit(findMergeBase, otherBranch));
            })
                                   .Where(b => b.Commit != null)
                                   .OrderByDescending(b => b.Commit.Committer.When)
                                   .ToList();

            mergeBaseCommitsCache.Add(branch, branchMergeBases);

            return(branchMergeBases);
        }
예제 #2
0
        /// <summary>
        /// Find the merge base of the two branches, i.e. the best common ancestor of the two branches' tips.
        /// </summary>
        public Commit FindMergeBase(Branch branch, Branch otherBranch)
        {
            var key = Tuple.Create(branch, otherBranch);

            if (mergeBaseCache.ContainsKey(key))
            {
                Logger.WriteDebug($"Cache hit for merge base between '{branch.FriendlyName}' and '{otherBranch.FriendlyName}'.");
                return(mergeBaseCache[key].MergeBase);
            }

            using (Logger.IndentLog($"Finding merge base between '{branch.FriendlyName}' and '{otherBranch.FriendlyName}'."))
            {
                // Otherbranch tip is a forward merge
                var commitToFindCommonBase = otherBranch.Tip;
                var commit = branch.Tip;
                if (otherBranch.Tip.Parents.Contains(commit))
                {
                    commitToFindCommonBase = otherBranch.Tip.Parents.First();
                }

                var findMergeBase = Repository.ObjectDatabase.FindMergeBase(commit, commitToFindCommonBase);
                if (findMergeBase != null)
                {
                    Logger.WriteInfo($"Found merge base of {findMergeBase.Sha}");
                    // We do not want to include merge base commits which got forward merged into the other branch
                    Commit forwardMerge;
                    do
                    {
                        // Now make sure that the merge base is not a forward merge
                        forwardMerge = Repository.Commits
                                       .QueryBy(new CommitFilter
                        {
                            IncludeReachableFrom = commitToFindCommonBase,
                            ExcludeReachableFrom = findMergeBase
                        })
                                       .FirstOrDefault(c => c.Parents.Contains(findMergeBase));

                        if (forwardMerge != null)
                        {
                            // TODO Fix the logging up in this section
                            var second = forwardMerge.Parents.First();
                            Logger.WriteDebug("Second " + second.Sha);
                            var mergeBase = Repository.ObjectDatabase.FindMergeBase(commit, second);
                            if (mergeBase == null)
                            {
                                Logger.WriteWarning("Could not find mergbase for " + commit);
                            }
                            else
                            {
                                Logger.WriteDebug("New Merge base " + mergeBase.Sha);
                            }
                            if (mergeBase == findMergeBase)
                            {
                                Logger.WriteDebug("Breaking");
                                break;
                            }
                            findMergeBase          = mergeBase;
                            commitToFindCommonBase = second;
                            Logger.WriteInfo($"Merge base was due to a forward merge, next merge base is {findMergeBase}");
                        }
                    } while (forwardMerge != null);
                }

                // Store in cache.
                mergeBaseCache.Add(key, new MergeBaseData(branch, otherBranch, Repository, findMergeBase));

                Logger.WriteInfo($"Merge base of {branch.FriendlyName}' and '{otherBranch.FriendlyName} is {findMergeBase}");
                return(findMergeBase);
            }
        }
예제 #3
0
        private static bool Log(LogLevel loglevel, Func <string> messagefunc, Exception exception, object[] formatparameters)
        {
            // Create the main message. Careful of string format errors.
            string message;

            if (messagefunc == null)
            {
                message = null;
            }
            else
            {
                if (formatparameters == null || formatparameters.Length == 0)
                {
                    message = messagefunc();
                }
                else
                {
                    try
                    {
                        message = string.Format(messagefunc(), formatparameters);
                    }
                    catch (FormatException)
                    {
                        message = messagefunc();
                        Logger.WriteError(string.Format("LoggerWrapper.Log(): Incorrectly formatted string: message: '{0}'; formatparameters: {1}", message, string.Join(";", formatparameters)));
                    }
                }
            }

            if (exception != null)
            {
                // Append the exception to the end of the message.
                message = string.IsNullOrEmpty(message) ? exception.ToString() : string.Format("{0}\n{1}", message, exception);
            }

            if (!string.IsNullOrEmpty(message))
            {
                switch (loglevel)
                {
                case LogLevel.Trace:
                case LogLevel.Debug:
                    Logger.WriteDebug(message);
                    break;

                case LogLevel.Info:
                    Logger.WriteInfo(message);
                    break;

                case LogLevel.Warn:
                    Logger.WriteWarning(message);
                    break;

                case LogLevel.Error:
                case LogLevel.Fatal:
                    Logger.WriteError(message);
                    break;
                }
            }

            return(true);
        }