From 93f60a9461974011bf71b27cf9cdf54b0efc221a Mon Sep 17 00:00:00 2001 From: Tyler Boone Date: Tue, 20 Aug 2019 13:08:04 -0700 Subject: [PATCH 1/2] improving performance of listing commits with a path --- LibGit2Sharp/Core/FileHistory.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/LibGit2Sharp/Core/FileHistory.cs b/LibGit2Sharp/Core/FileHistory.cs index 5c10a1a24..988a39cbb 100644 --- a/LibGit2Sharp/Core/FileHistory.cs +++ b/LibGit2Sharp/Core/FileHistory.cs @@ -163,6 +163,16 @@ private static void DetermineParentPaths(IRepository repo, Commit currentCommit, private static string ParentPath(IRepository repo, Commit currentCommit, string currentPath, Commit parentCommit) { + // optimization: if the SHA of the parent commit's TreeEntry is the same as this commit's TreeEntry then + // they are the same and there is no need to diff the commit + TreeEntry parentTreeEntry = parentCommit.Tree[currentPath]; + TreeEntry thisTreeEntry = currentCommit.Tree[currentPath]; + if (parentTreeEntry != null && parentTreeEntry.Target.Sha == thisTreeEntry.Target.Sha) + { + return currentPath; + } + + // something in the tree is different, so we need to diff the commits to look for renames using (var treeChanges = repo.Diff.Compare(parentCommit.Tree, currentCommit.Tree)) { var treeEntryChanges = treeChanges.FirstOrDefault(c => c.Path == currentPath); From d87e5041e0fc85c85d77739935807401fe1d6aad Mon Sep 17 00:00:00 2001 From: Tyler Boone Date: Tue, 20 Aug 2019 13:08:37 -0700 Subject: [PATCH 2/2] caching TreeEntries to improve perfomance --- LibGit2Sharp/Tree.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/LibGit2Sharp/Tree.cs b/LibGit2Sharp/Tree.cs index ca7055183..8bcccea0b 100644 --- a/LibGit2Sharp/Tree.cs +++ b/LibGit2Sharp/Tree.cs @@ -39,6 +39,8 @@ internal Tree(Repository repo, ObjectId id, string path) /// public virtual int Count { get { return lazyCount.Value; } } + private Dictionary _treeCache; + /// /// Gets the pointed at by the in this instance. /// @@ -46,9 +48,19 @@ internal Tree(Repository repo, ObjectId id, string path) /// null if nothing has been found, the otherwise. public virtual TreeEntry this[string relativePath] { - get { return RetrieveFromPath(relativePath); } + get + { + TreeEntry ret; + if (_treeCache == null) _treeCache = new Dictionary(); + else if (_treeCache.TryGetValue(relativePath, out ret)) return ret; + + ret = RetrieveFromPath(relativePath); + _treeCache[relativePath] = ret; + return ret; + } } + private unsafe TreeEntry RetrieveFromPath(string relativePath) { if (string.IsNullOrEmpty(relativePath))