Exemple #1
0
        public async Task <bool> FilterParents(CommitMetadata commit, ParentFilterContext context)
        {
            if (newParents.ContainsKey(commit.Original?.Sha))
            {
                commit.Parents = (await Task.WhenAll(newParents[commit.Original?.Sha].Select(context.Map))).Flatten().ToList();
                return(true);
            }

            return(false);
        }
Exemple #2
0
        public async Task <bool> FilterParents(CommitMetadata commit, ParentFilterContext context)
        {
            // Re-process merges to eliminate branches that don't contribute anything to the tree
            if (commit.Parents.Count > 1 && pruneMergesAggressive)
            {
                var treeSameTo = commit.Parents.Where(p => commit.Tree.Equals(p.Tree)).FirstOrDefault();

                if (treeSameTo != null)
                {
                    // eliminate the parents that are not treesame as they contribute nothing
                    commit.Parents = commit.Parents.Where(p => p.Tree.Equals(treeSameTo.Tree)).Distinct().ToList();

                    // If it's demoted from a merge, it's a pointless commit now
                    // as it's treesame to its only parent. So dump out early and drop it
                    if (commit.Parents.Count == 1)
                    {
                        return(false);
                    }
                }
            }

            if (commit.Parents.Count == 2 && pruneMerges)
            {
                // Heuristic to quickly eliminate the common case of a triangle
                var p1 = commit.Parents[0];
                var p2 = commit.Parents[1];

                if (p2.Parents.Contains(p1))
                {
                    // p1 is redundant as it's reachable from p2
                    commit.Parents.Remove(p1);
                }
                else if (p1.Parents.Contains(p2))
                {
                    // p2 is redundant since reachable from p1
                    commit.Parents.Remove(p2);
                }
            }

            if (commit.Parents.Count > 1 && pruneMerges)
            {
                var procInfo = new ProcessStartInfo("git", "show-branch --independent " + string.Join(" ", commit.Parents.Select(x => x.Sha)))
                {
                    RedirectStandardOutput = true,
                    RedirectStandardError  = true,
                    UseShellExecute        = false
                };

                using (var proc = await RunProcessAsync(procInfo).ConfigureAwait(false))
                {
                    var newParentShas = proc.StandardOutput.ReadToEnd().Split(' ', '\r', '\n').Where(x => !string.IsNullOrWhiteSpace(x)).Select(x => x.Trim()).Distinct().ToSet();

                    if (proc.ExitCode != 0)
                    {
                        throw new Exception("git show-branch failed! " + proc.StandardError.ReadToEnd());
                    }

                    commit.Parents = commit.Parents.Where(p => newParentShas.Contains(p.Sha)).ToList();
                }
            }

            if (commit.Parents.Count == 0)
            {
                return(!commit.Tree.IsEmpty); // Don't include null trees if we're a root
            }

            if (commit.Parents.Count == 1 && commit.Tree.Equals(commit.Parents[0].Tree))
            {
                return(false); // Skip unchanged
            }

            return(true);
        }