private RevisionSummaryCacheItem[] CalculateRevisionSummary(IList<TreeEntryModel> entries, IEnumerable<Commit> ancestors, RevisionSummaryCacheItem[] summary) { if (summary != null) { foreach (var entry in entries) { var commitModel = entry.Commit; var item = summary.First(s => s.Name == entry.Name); commitModel.Sha = item.Sha; commitModel.CommitMessageShort = item.MessageShort; commitModel.Author = new Signature(item.AuthorName, item.AuthorEmail, item.AuthorWhen); commitModel.Committer = new Signature(item.CommitterName, item.CommitterEmail, item.CommitterWhen); } return summary; } // null, continue search current reference // true, have found, done // false, search has been interrupted, but waiting for next match var status = new bool?[entries.Count]; var done = entries.Count; Commit lastCommit = null; foreach (var ancestor in ancestors) { for (var index = 0; index < entries.Count; index++) { if (status[index] == true) continue; var entryModel = entries[index]; var ancestorEntry = ancestor[entryModel.Path]; if (ancestorEntry != null && ancestorEntry.Target.Sha == entryModel.Sha) { var commitModel = entryModel.Commit; commitModel.Sha = ancestor.Sha; commitModel.CommitMessageShort = ancestor.MessageShort.RepetitionIfEmpty(NoCommitMessage); commitModel.Author = ancestor.Author; commitModel.Committer = ancestor.Committer; status[index] = null; } else if (status[index] == null) { var over = true; foreach (var parent in lastCommit.Parents) // Backtracking { if (parent.Sha == ancestor.Sha) continue; var entry = parent[entryModel.Path]; if (entry != null && entry.Target.Sha == entryModel.Sha) { over = false; break; } } status[index] = over; if (over) done--; } } if (done == 0) break; lastCommit = ancestor; } return entries.Select(s => new RevisionSummaryCacheItem { Name = s.Name, Sha = s.Commit.Sha, MessageShort = s.Commit.CommitMessageShort, AuthorName = s.Commit.Author.Name, AuthorEmail = s.Commit.Author.Email, AuthorWhen = s.Commit.Author.When, CommitterName = s.Commit.Committer.Name, CommitterEmail = s.Commit.Committer.Email, CommitterWhen = s.Commit.Committer.When, }).ToArray(); }
protected override void Init() { result = new RevisionSummaryCacheItem[0]; }