Skip to content

Commit

Permalink
Minor LibGit2 API improvement
Browse files Browse the repository at this point in the history
Use the _bypath function in GitTree getindex rather than opencoding
it using the tree walker.
  • Loading branch information
Keno committed Apr 13, 2020
1 parent 8b6cadb commit 5821fb1
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 31 deletions.
2 changes: 2 additions & 0 deletions stdlib/LibGit2/src/commit.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license

repository(c::GitCommit) = c.owner

"""
message(c::GitCommit, raw::Bool=false)
Expand Down
62 changes: 31 additions & 31 deletions stdlib/LibGit2/src/tree.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license

function GitTree(c::GitCommit)
tree_out = Ref{Ptr{Cvoid}}(C_NULL)
@check ccall((:git_commit_tree, :libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}), tree_out, c)
GitTree(repository(c), tree_out[])
end

"""
treewalk(f, tree::GitTree, post::Bool=false)
Expand Down Expand Up @@ -122,14 +128,13 @@ tree_entry = tree[1]
blob = LibGit2.GitBlob(tree_entry)
```
"""
function GitObject(e::GitTreeEntry) end
function (::Type{T})(te::GitTreeEntry) where T<:GitObject
ensure_initialized()
repo = repository(te)
obj_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL)
@check ccall((:git_tree_entry_to_object, :libgit2), Cint,
(Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Ref{Nothing}),
obj_ptr_ptr, repo.ptr, te.ptr)
(Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Ptr{Cvoid}),
obj_ptr_ptr, repo, te)
return T(repo, obj_ptr_ptr[])
end

Expand All @@ -146,6 +151,23 @@ function Base.show(io::IO, tree::GitTree)
println(io, "Number of entries: ", count(tree))
end

function _getindex(tree::GitTree, target::AbstractString)
if basename(target) == ""
# get rid of any trailing separator
target = dirname(target)
end
if isempty(target) || target == "/"
return tree
end

entry = Ref{Ptr{Cvoid}}(C_NULL)
err = ccall((:git_tree_entry_bypath, :libgit2), Cint, (Ptr{Ptr{Cvoid}}, Ptr{Cvoid}, Cstring), entry, tree, target)
err == Int(Error.ENOTFOUND) && return nothing
err < 0 && throw(Error.GitError(err))
entry = GitTreeEntry(tree, entry[], true #= N.B.: Most other lookups need false here =#)
return GitObject(entry)
end

"""
getindex(tree::GitTree, target::AbstractString) -> GitObject
Expand All @@ -161,33 +183,11 @@ runtests = subtree["runtests.jl"]
```
"""
function Base.getindex(tree::GitTree, target::AbstractString)
if basename(target) == ""
# get rid of any trailing separator
target = dirname(target)
end
if target == "" || target == "/"
return tree
end
e = _getindex(tree, target)
e === nothing && throw(KeyError(target))
return e
end

local oid = nothing
function _getindex_callback(root::String, entry::GitTreeEntry)::Cint
path = joinpath(root, filename(entry))
if path == target
# we found the target, save the oid and stop the walk
oid = entryid(entry)
# workaround for issue: https://github.com/libgit2/libgit2/issues/4693
ensure_initialized()
ccall((:giterr_set_str, :libgit2), Cvoid,
(Cint, Cstring), Cint(Error.Callback),
"git_tree_walk callback returned -1")
return -1
elseif entrytype(entry) == GitTree && !startswith(target, path)
# this subtree isn't relevant, so skip it
return 1
end
return 0
end
treewalk(_getindex_callback, tree)
oid === nothing && throw(KeyError(target))
return GitObject(repository(tree), oid)
function Base.haskey(tree::GitTree, target::AbstractString)
return _getindex(tree, target) !== nothing
end
2 changes: 2 additions & 0 deletions stdlib/LibGit2/src/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1007,6 +1007,7 @@ for (typ, owntyp, sup, cname) in [
return obj
end
end
@eval Base.unsafe_convert(::Type{Ptr{Cvoid}}, x::$typ) = x.ptr
else
@eval mutable struct $typ <: $sup
owner::$owntyp
Expand All @@ -1021,6 +1022,7 @@ for (typ, owntyp, sup, cname) in [
return obj
end
end
@eval Base.unsafe_convert(::Type{Ptr{Cvoid}}, x::$typ) = x.ptr
if isa(owntyp, Expr) && owntyp.args[1] === :Union && owntyp.args[3] === :Nothing
@eval begin
$typ(ptr::Ptr{Cvoid}, fin::Bool=true) = $typ(nothing, ptr, fin)
Expand Down

0 comments on commit 5821fb1

Please sign in to comment.