# This file is a part of Julia. License is MIT: https://julialang.org/license function GitRevWalker(repo::GitRepo) w_ptr = Ref{Ptr{Void}}(C_NULL) @check ccall((:git_revwalk_new, :libgit2), Cint, (Ptr{Ptr{Void}}, Ptr{Void}), w_ptr, repo.ptr) return GitRevWalker(repo, w_ptr[]) end function Base.start(w::GitRevWalker) id_ptr = Ref(GitHash()) err = ccall((:git_revwalk_next, :libgit2), Cint, (Ptr{GitHash}, Ptr{Void}), id_ptr, w.ptr) err != Int(Error.GIT_OK) && return (nothing, true) return (id_ptr[], false) end Base.done(w::GitRevWalker, state) = Bool(state[2]) function Base.next(w::GitRevWalker, state) id_ptr = Ref(GitHash()) err = ccall((:git_revwalk_next, :libgit2), Cint, (Ptr{GitHash}, Ptr{Void}), id_ptr, w.ptr) err != Int(Error.GIT_OK) && return (state[1], (nothing, true)) return (state[1], (id_ptr[], false)) end Base.iteratorsize(::Type{GitRevWalker}) = Base.SizeUnknown() function push_head!(w::GitRevWalker) @check ccall((:git_revwalk_push_head, :libgit2), Cint, (Ptr{Void},), w.ptr) return w end function Base.push!(w::GitRevWalker, cid::GitHash) @check ccall((:git_revwalk_push, :libgit2), Cint, (Ptr{Void}, Ptr{GitHash}), w.ptr, Ref(cid)) return w end function Base.push!(w::GitRevWalker, range::AbstractString) @check ccall((:git_revwalk_push_range, :libgit2), Cint, (Ptr{Void}, Ptr{UInt8}), w.ptr, range) return w end function Base.sort!(w::GitRevWalker; by::Cint = Consts.SORT_NONE, rev::Bool=false) rev && (by |= Consts.SORT_REVERSE) ccall((:git_revwalk_sorting, :libgit2), Void, (Ptr{Void}, Cint), w.ptr, by) return w end repository(w::GitRevWalker) = w.owner function Base.map(f::Function, walker::GitRevWalker; oid::GitHash=GitHash(), range::AbstractString="", by::Cint = Consts.SORT_NONE, rev::Bool=false, count::Int=0) res = [] sort!(walker, by=by, rev=rev) if !iszero(oid) push!(walker, oid) elseif !isempty(range) push!(walker, range) else push_head!(walker) end s = start(walker) c = 0 repo = repository(walker) while !done(walker, s) val = f(s[1], repo) push!(res, val) val, s = next(walker, s) c +=1 count == c && break end return res end function Base.count(f::Function, walker::GitRevWalker; oid::GitHash=GitHash(), by::Cint = Consts.SORT_NONE, rev::Bool=false) c = 0 sort!(walker, by=by, rev=rev) if !iszero(oid) push!(walker, oid) else push_head!(walker) end s = start(walker) repo = repository(walker) while !done(walker, s) val = f(s[1], repo) _, s = next(walker, s) c += (val == true) end return c end