libgit2sharp icon indicating copy to clipboard operation
libgit2sharp copied to clipboard

Add RevWalker

Open jairbubbles opened this issue 2 years ago • 0 comments

  • Add class wrapper other https://github.com/libgit2/libgit2/blob/main/include/git2/revwalk.h to allow reusing it for multiple traversals
  • Expose git_revwalk_push_glob / git_revwalk_hide_glob and git_revwalk_push_ref / git_revwalk_hide_ref which allows to select commits more efficiently
  • Use the wrapper in the CommitLog

This allows more flexibility than CommitLog and allows to traverse the repository multiple times more efficiently.

using var repository = new Repository(@"<repo_path>");
using var revWalker = new RevWalker(repository);

// Store commits in a cache to speed up multiple walks on same repository
var commitsCache = new Dictionary<ObjectId, Commit>();
 
revWalker.Reset();
revWalker.Sorting(CommitSortStrategies.Topological);

revWalker.PushGlob("refs/tags/*");

var commits = GetCommits().ToArray();

// Subsequent walk will reuse commits cache and internal RevWalker cache
revWalker.Reset();
revWalker.PushRef("HEAD");

commits = GetCommits().ToArray();
 
IEnumerable<Commit> GetCommits()
{
    while (true)
    {
        var objectId = revWalker.Next();
        if (objectId == null)
            break;
    
        if (!commitsCache.TryGetValue(objectId, out var commit))
        {
            commit = repository.Lookup<Commit>(objectId);
            commitsCache[objectId] = commit;
        }

        yield return commit;
    }
}
 

jairbubbles avatar May 20 '23 19:05 jairbubbles