diff --git a/base/libgit2/blob.jl b/base/libgit2/blob.jl index 437b806bbfa96..216cb5d77ff12 100644 --- a/base/libgit2/blob.jl +++ b/base/libgit2/blob.jl @@ -8,6 +8,16 @@ function Base.length(blob::GitBlob) return ccall((:git_blob_rawsize, :libgit2), Int64, (Ptr{Void},), blob.ptr) end +""" +Use a heuristic to guess if a file is binary: searching for NULL bytes and +looking for a reasonable ratio of printable to non-printable characters among +the first 8000 bytes. +""" +function isbinary(blob::GitBlob) + bin_flag = ccall((:git_blob_is_binary, :libgit2), Int64, (Ptr{Void},), blob.ptr) + return bin_flag == 1 +end + function lookup(repo::GitRepo, oid::GitHash) blob_ptr_ptr = Ref{Ptr{Void}}(C_NULL) @check ccall((:git_blob_lookup, :libgit2), Cint, @@ -15,3 +25,25 @@ function lookup(repo::GitRepo, oid::GitHash) blob_ptr_ptr, repo.ptr, Ref(oid)) return GitBlob(blob_ptr_ptr[]) end + +function GitBlob(repo::GitRepo, path::AbstractString) + blob_id_ptr = Ref(GitHash()) + @check ccall((:git_blob_create_fromdisk, :libgit2), Cint, + (Ptr{GitHash}, Ptr{Void}, Ptr{UInt8}), blob_id_ptr, + repo.ptr, path) + blob = get(GitBlob, repo, blob_id_ptr[]) + return blob +end + +function Base.show(io::IO, blob::GitBlob) + if !isbinary(blob) + conts = split(content(blob), "\n") + showlen = max(len(conts), 3) + print(io, "GitBlob:\nBlob id: ", GitHash(blob.ptr), "\nContents:\n") + for i in 1:showlen + print(io, conts[i],"\n") + end + else + print(io, "GitBlob:\nBlob id: ", GitHash(blob.ptr), "\nContents are binary.") + end +end diff --git a/base/libgit2/types.jl b/base/libgit2/types.jl index 3221a7eb54c1d..98252da1362bd 100644 --- a/base/libgit2/types.jl +++ b/base/libgit2/types.jl @@ -348,7 +348,7 @@ end LibGit2.RebaseOperation Describes a single instruction/operation to be performed during the rebase. -Matches the `git_rebase_operation` struct. +Matches the [`git_rebase_operation`](https://libgit2.github.com/libgit2/#HEAD/type/git_rebase_operation_t) struct. """ immutable RebaseOperation optype::Cint @@ -361,7 +361,7 @@ Base.show(io::IO, rbo::RebaseOperation) = print(io, "RebaseOperation($(string(rb LibGit2.StatusOptions Options to control how `git_status_foreach_ext()` will issue callbacks. -Matches the `git_status_options` struct. +Matches the [`git_status_opt_t`](https://libgit2.github.com/libgit2/#HEAD/type/git_status_opt_t) struct. """ @kwdef immutable StatusOptions version::Cuint = 1 diff --git a/test/libgit2.jl b/test/libgit2.jl index 049816b43f65e..1ca1bacb8fba3 100644 --- a/test/libgit2.jl +++ b/test/libgit2.jl @@ -429,6 +429,24 @@ mktempdir() do dir close(repo) end end + + @testset "blobs" begin + repo = LibGit2.GitRepo(cache_repo) + try + # clear out the "GitHash( )" part + hash_string = sprint(show, commit_oid1)[9:end] + hash_string = strip(hash_string, ')') + blob_file = joinpath(cache_repo,".git/objects", hash_string[1:2], hash_string[3:end]) + blob = LibGit2.GitBlob(repo, blob_file) + @test LibGit2.isbinary(blob) + blob_show_strs = split(sprint(show, blob), "\n") + @test blob_show_strs[1] == "GitBlob:" + @test contains(blob_show_strs[2], "Blob id:") + @test blob_show_strs[3] == "Contents are binary." + finally + close(repo) + end + end end @testset "Fetch from cache repository" begin