Skip to content

Commit

Permalink
Add RevWalker
Browse files Browse the repository at this point in the history
  • Loading branch information
jairbubbles committed May 20, 2023
1 parent 8c32b61 commit 0a6c5bf
Show file tree
Hide file tree
Showing 5 changed files with 293 additions and 57 deletions.
41 changes: 41 additions & 0 deletions LibGit2Sharp.Tests/RepositoryFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -775,5 +775,46 @@ public void ReadingReferenceTargetFromListRemoteReferencesThrows(string url)
});
}
}

[Fact]
public void RevWalkRepository()
{
string path = SandboxBareTestRepo();
using (var repo = new Repository(path))
using (var walker = new RevWalker(repo))
{
walker.Sorting(CommitSortStrategies.Topological);

Assert.Empty(GetCommits().ToList());

walker.PushRef("HEAD");
Assert.Equal(7, GetCommits().Count());

walker.HideRef("HEAD");
Assert.Empty(GetCommits());

walker.Reset();

walker.PushGlob("refs/heads/*");
Assert.Equal(12, GetCommits().Count());

walker.HideGlob("refs/*");
Assert.Empty(GetCommits());

IEnumerable<Commit> GetCommits()
{
while (true)
{
var objectId = walker.Next();
if (objectId == null)
break;

var commit = repo.Lookup<Commit>(objectId);
yield return commit;
}
}
}

}
}
}
77 changes: 25 additions & 52 deletions LibGit2Sharp/CommitLog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,19 +108,34 @@ public IEnumerable<LogEntry> QueryBy(string path, CommitFilter filter)
private class CommitEnumerator : IEnumerator<Commit>
{
private readonly Repository repo;
private readonly RevWalkerHandle handle;
private readonly RevWalker walker;
private ObjectId currentOid;

public CommitEnumerator(Repository repo, CommitFilter filter)
{
this.repo = repo;
handle = Proxy.git_revwalk_new(repo.Handle);
repo.RegisterForCleanup(handle);

Sort(filter.SortBy);
Push(filter.SinceList);
Hide(filter.UntilList);
FirstParentOnly(filter.FirstParentOnly);
walker = new RevWalker(repo);

walker.Sorting(filter.SortBy);

foreach (ObjectId actedOn in repo.Committishes(filter.SinceList).TakeWhile(o => o != null))
{
walker.Push(actedOn);
}

if(filter.UntilList != null)
{
foreach (ObjectId actedOn in repo.Committishes(filter.UntilList).TakeWhile(o => o != null))
{
walker.Hide(actedOn);
}
}

if (filter.FirstParentOnly)
{
walker.SimplifyFirstParent();
}
}

#region IEnumerator<Commit> Members
Expand All @@ -137,21 +152,19 @@ object IEnumerator.Current

public bool MoveNext()
{
ObjectId id = Proxy.git_revwalk_next(handle);

ObjectId id = walker.Next();
if (id == null)
{
return false;
}

currentOid = id;

return true;
}

public void Reset()
{
Proxy.git_revwalk_reset(handle);
walker.Reset();
}

#endregion
Expand All @@ -164,47 +177,7 @@ public void Dispose()

private void Dispose(bool disposing)
{
handle.SafeDispose();
}

private delegate void HidePushSignature(RevWalkerHandle handle, ObjectId id);

private void InternalHidePush(IList<object> identifier, HidePushSignature hidePush)
{
IEnumerable<ObjectId> oids = repo.Committishes(identifier).TakeWhile(o => o != null);

foreach (ObjectId actedOn in oids)
{
hidePush(handle, actedOn);
}
}

private void Push(IList<object> identifier)
{
InternalHidePush(identifier, Proxy.git_revwalk_push);
}

private void Hide(IList<object> identifier)
{
if (identifier == null)
{
return;
}

InternalHidePush(identifier, Proxy.git_revwalk_hide);
}

private void Sort(CommitSortStrategies options)
{
Proxy.git_revwalk_sorting(handle, options);
}

private void FirstParentOnly(bool firstParent)
{
if (firstParent)
{
Proxy.git_revwalk_simplify_first_parent(handle);
}
walker.SafeDispose();
}
}
}
Expand Down
16 changes: 16 additions & 0 deletions LibGit2Sharp/Core/NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1686,6 +1686,14 @@ IntPtr data
[DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)]
internal static extern unsafe int git_revwalk_hide(git_revwalk* walker, ref GitOid commit_id);

[DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)]
internal static extern unsafe int git_revwalk_hide_glob(git_revwalk* walker,
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string glob);

[DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)]
internal static extern unsafe int git_revwalk_hide_ref(git_revwalk* walker,
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string refname);

[DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)]
internal static extern unsafe int git_revwalk_new(out git_revwalk* walker, git_repository* repo);

Expand All @@ -1695,6 +1703,14 @@ IntPtr data
[DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)]
internal static extern unsafe int git_revwalk_push(git_revwalk* walker, ref GitOid id);

[DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)]
internal static extern unsafe int git_revwalk_push_glob(git_revwalk* walker,
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string glob);

[DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)]
internal static extern unsafe int git_revwalk_push_ref(git_revwalk* walker,
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string refname);

[DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)]
internal static extern unsafe int git_revwalk_reset(git_revwalk* walker);

Expand Down
37 changes: 32 additions & 5 deletions LibGit2Sharp/Core/Proxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2752,6 +2752,18 @@ public static unsafe void git_revwalk_hide(RevWalkerHandle walker, ObjectId comm
Ensure.ZeroResult(res);
}

public static unsafe void git_revwalk_hide_glob(RevWalkerHandle walker, string glob)
{
int res = NativeMethods.git_revwalk_hide_glob(walker, glob);
Ensure.ZeroResult(res);
}

public static unsafe void git_revwalk_hide_ref(RevWalkerHandle walker, string refName)
{
int res = NativeMethods.git_revwalk_hide_ref(walker, refName);
Ensure.ZeroResult(res);
}

public static unsafe RevWalkerHandle git_revwalk_new(RepositoryHandle repo)
{
git_revwalk* handle;
Expand Down Expand Up @@ -2783,19 +2795,34 @@ public static unsafe void git_revwalk_push(RevWalkerHandle walker, ObjectId id)
Ensure.ZeroResult(res);
}

public static unsafe void git_revwalk_push_glob(RevWalkerHandle walker, string glob)
{
int res = NativeMethods.git_revwalk_push_glob(walker, glob);
Ensure.ZeroResult(res);
}

public static unsafe void git_revwalk_push_ref(RevWalkerHandle walker, string refName)
{
int res = NativeMethods.git_revwalk_push_ref(walker, refName);
Ensure.ZeroResult(res);
}

public static unsafe void git_revwalk_reset(RevWalkerHandle walker)
{
NativeMethods.git_revwalk_reset(walker);
int res = NativeMethods.git_revwalk_reset(walker);
Ensure.ZeroResult(res);
}

public static unsafe int git_revwalk_sorting(RevWalkerHandle walker, CommitSortStrategies options)
public static unsafe void git_revwalk_sorting(RevWalkerHandle walker, CommitSortStrategies options)
{
return NativeMethods.git_revwalk_sorting(walker, options);
int res = NativeMethods.git_revwalk_sorting(walker, options);
Ensure.ZeroResult(res);
}

public static unsafe int git_revwalk_simplify_first_parent(RevWalkerHandle walker)
public static unsafe void git_revwalk_simplify_first_parent(RevWalkerHandle walker)
{
return NativeMethods.git_revwalk_simplify_first_parent(walker);
int res = NativeMethods.git_revwalk_simplify_first_parent(walker);
Ensure.ZeroResult(res);
}

#endregion
Expand Down

0 comments on commit 0a6c5bf

Please sign in to comment.