From 852cfa6f4777d54b5f7dbfbe0fceafc63ae22165 Mon Sep 17 00:00:00 2001 From: Yichao Yu Date: Sun, 10 Sep 2023 14:28:20 -0400 Subject: [PATCH] Add support for getting commit parent Required for walking the commit graph. --- stdlib/LibGit2/src/commit.jl | 42 ++++++++++++++++++++++++++++ stdlib/LibGit2/test/libgit2-tests.jl | 8 ++++++ 2 files changed, 50 insertions(+) diff --git a/stdlib/LibGit2/src/commit.jl b/stdlib/LibGit2/src/commit.jl index 5d3c666af4bbb7..32c3f380730757 100644 --- a/stdlib/LibGit2/src/commit.jl +++ b/stdlib/LibGit2/src/commit.jl @@ -147,3 +147,45 @@ function commit(repo::GitRepo, msg::AbstractString; end return commit_id end + +""" + parentcount(c::GitCommit) + +Get the number of parents of this commit. + +See also [`parent`](@ref), [`parent_id`](@ref). +""" +parentcount(c::GitCommit) = + Int(ccall((:git_commit_parentcount, :libgit2), Cuint, (Ptr{Cvoid},), c)) + +""" + parent(c::GitCommit, n) + +Get the `n`-th (1-based) parent of the commit. + +See also [`parentcount`](@ref), [`parent_id`](@ref). +""" +function parent(c::GitCommit, n) + ptr_ref = Ref{Ptr{Cvoid}}() + @check ccall((:git_commit_parent, :libgit2), Cint, + (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Cuint), ptr_ref, c, n - 1) + return GitCommit(c.owner, ptr_ref[]) +end + +""" + parent_id(c::GitCommit, n) + +Get the oid of the `n`-th (1-based) parent for a commit. + +See also [`parentcount`](@ref), [`parent`](@ref). +""" +function parent_id(c::GitCommit, n) + oid_ptr = ccall((:git_commit_parent_id, :libgit2), Ptr{GitHash}, + (Ptr{Cvoid}, Cuint), c, n - 1) + if oid_ptr == C_NULL + # 0-based indexing mimicking the error message from libgit2 + throw(GitError(Error.Invalid, Error.ENOTFOUND, + "parent $(n - 1) does not exist")) + end + return unsafe_load(oid_ptr) +end diff --git a/stdlib/LibGit2/test/libgit2-tests.jl b/stdlib/LibGit2/test/libgit2-tests.jl index 7dbbd10af6f678..99bd18b4e17501 100644 --- a/stdlib/LibGit2/test/libgit2-tests.jl +++ b/stdlib/LibGit2/test/libgit2-tests.jl @@ -928,6 +928,14 @@ mktempdir() do dir @test cmtr.email == test_sig.email @test LibGit2.message(cmt) == commit_msg1 + # test that the parent is correct + @test LibGit2.parentcount(cmt) == 0 + LibGit2.with(LibGit2.GitCommit(repo, commit_oid3)) do cmt3 + @test LibGit2.parentcount(cmt3) == 1 + @test LibGit2.parent_id(cmt3, 1) == commit_oid1 + @test LibGit2.GitHash(LibGit2.parent(cmt3, 1)) == commit_oid1 + end + # test showing the commit showstr = split(sprint(show, cmt), "\n") # the time of the commit will vary so just test the first two parts