Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add GitShortHash type, remove some get methods #20104

Merged
merged 11 commits into from
Jan 31, 2017
22 changes: 15 additions & 7 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@
# the name of the function, which is used to ensure that the deprecation warning
# is only printed the first time for each call place.

macro deprecate(old,new)
macro deprecate(old,new,ex=true)
meta = Expr(:meta, :noinline)
if isa(old,Symbol)
oldname = Expr(:quote,old)
newname = Expr(:quote,new)
Expr(:toplevel,
Expr(:export,esc(old)),
ex ? Expr(:export,esc(old)) : nothing,
:(function $(esc(old))(args...)
$meta
depwarn(string($oldname," is deprecated, use ",$newname," instead."),
Expand Down Expand Up @@ -1552,8 +1552,6 @@ _promote_eltype_op(op, A, B, C, D...) = (@_inline_meta; _promote_eltype_op(op, e
_promote_eltype_op(args...)
end

# Rename LibGit2.Oid to LibGit2.GitHash (part of #19839)
eval(Base.LibGit2, :(Base.@deprecate_binding Oid GitHash))

function unsafe_wrap(::Type{String}, p::Union{Ptr{UInt8},Ptr{Int8}}, len::Integer, own::Bool=false)
Base.depwarn("unsafe_wrap(String, ...) is deprecated; use `unsafe_string` instead.", :unsafe_wrap)
Expand All @@ -1572,9 +1570,6 @@ unsafe_wrap(::Type{String}, p::Cstring, len::Integer, own::Bool=false) =
@deprecate finalize(sa::LibGit2.StrArrayStruct) close(sa)
@deprecate finalize(sa::LibGit2.Buffer) close(sa)

# Rename LibGit2.GitAnyObject to LibGit2.GitUnknownObject (part of #19839)
eval(LibGit2, :(Base.@deprecate_binding GitAnyObject GitUnknownObject))

## produce, consume, and task iteration
# NOTE: When removing produce/consume, also remove field Task.consumers and related code in
# task.jl and event.jl
Expand Down Expand Up @@ -1826,6 +1821,19 @@ function colon{T<:Dates.Period}(start::T, stop::T)
colon(start, T(1), stop)
end

# LibGit2 refactor (#19839)
eval(Base.LibGit2, quote
Base.@deprecate_binding Oid GitHash
Base.@deprecate_binding GitAnyObject GitUnknownObject

@deprecate owner(x) repository(x) false
@deprecate get{T<:GitObject}(::Type{T}, repo::GitRepo, x) T(repo, x) false
@deprecate get{T<:GitObject}(::Type{T}, repo::GitRepo, oid::GitHash, oid_size::Int) T(repo, GitShortHash(oid, oid_size)) false
@deprecate revparse(repo::GitRepo, objname::AbstractString) GitObject(repo, objname) false
@deprecate object(repo::GitRepo, te::GitTreeEntry) GitObject(repo, te) false
@deprecate commit(ann::GitAnnotated) GitHash(ann) false
end)

# when this deprecation is deleted, remove all calls to it, and all
# negate=nothing keyword arguments, from base/dates/adjusters.jl
eval(Dates, quote
Expand Down
25 changes: 15 additions & 10 deletions base/libgit2/blob.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# This file is a part of Julia. License is MIT: http://julialang.org/license

function content(blob::GitBlob)
return ccall((:git_blob_rawcontent, :libgit2), Ptr{Void}, (Ptr{Void},), blob.ptr)
unsafe_string(ccall((:git_blob_rawcontent, :libgit2), Ptr{UInt8}, (Ptr{Void},), blob.ptr))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this is binary content, it could easily have embedded nuls or be invalid utf-8, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. We can deal with the NUL issue by calling it with a length argument (which I presume is git_blob_rawsize). But I don't know how we could deal with non-UTF8 data.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have it return an array of bytes?

end

function Base.length(blob::GitBlob)
Expand All @@ -26,24 +26,29 @@ function lookup(repo::GitRepo, oid::GitHash)
return GitBlob(blob_ptr_ptr[])
end

function GitBlob(repo::GitRepo, path::AbstractString)
blob_id_ptr = Ref(GitHash())
"""
LibGit2.addblob!(repo::GitRepo, path::AbstractString)

Reads the file at `path` and adds it to the object database of `repo` as a loose blob.
Returns the `GitHash` of the resulting blob.
"""
function addblob!(repo::GitRepo, path::AbstractString)
id_ref = 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
(Ptr{GitHash}, Ptr{Void}, Cstring),
id_ref, repo.ptr, path)
return id_ref[]
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")
showlen = max(length(conts), 3)
print(io, "GitBlob:\nBlob id: ", GitHash(blob), "\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.")
print(io, "GitBlob:\nBlob id: ", GitHash(blob), "\nContents are binary.\n")
end
end
6 changes: 3 additions & 3 deletions base/libgit2/commit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,13 @@ function commit(repo::GitRepo, msg::AbstractString;
commit_id = GitHash()

# get necessary objects
tree = get(GitTree, repo, tree_id)
tree = GitTree(repo, tree_id)
auth_sig = convert(GitSignature, author)
comm_sig = convert(GitSignature, committer)
parents = GitCommit[]
try
for parent in parent_ids
push!(parents, get(GitCommit, repo, parent))
for id in parent_ids
push!(parents, GitCommit(repo, id))
end
commit_id = commit(repo, refname, msg, auth_sig, comm_sig, tree, parents...)
finally
Expand Down
13 changes: 7 additions & 6 deletions base/libgit2/consts.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ module Consts
const REMOTE_ORIGIN = "origin"

# objs
const OBJ_ANY = Cint(-2)
const OBJ_BAD = Cint(-1)
const OBJ_COMMIT = Cint(1)
const OBJ_TREE = Cint(2)
const OBJ_BLOB = Cint(3)
const OBJ_TAG = Cint(4)
@enum(OBJECT,
OBJ_ANY = -2,
OBJ_BAD = -1,
OBJ_COMMIT = 1,
OBJ_TREE = 2,
OBJ_BLOB = 3,
OBJ_TAG = 4)

#revwalk
const SORT_NONE = Cint(0)
Expand Down
23 changes: 13 additions & 10 deletions base/libgit2/index.jl
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,19 @@ function repository(idx::GitIndex)
end
end

function read_tree!(idx::GitIndex, tree_id::GitHash)
repo = repository(idx)
tree = get(GitTree, repo, tree_id)
try
@check ccall((:git_index_read_tree, :libgit2), Cint,
(Ptr{Void}, Ptr{Void}), idx.ptr, tree.ptr)
finally
close(tree)
end
end
"""
LibGit2.read_tree!(idx::GitIndex, tree::GitTree)
LibGit2.read_tree!(idx::GitIndex, treehash::AbstractGitHash)

Read the tree `tree` (or the tree pointed to by `treehash` in the repository owned by
`idx`) into the index `idx`. The current index contents will be replaced.
"""
function read_tree!(idx::GitIndex, tree::GitTree)
@check ccall((:git_index_read_tree, :libgit2), Cint,
(Ptr{Void}, Ptr{Void}), idx.ptr, tree.ptr)
end
read_tree!(idx::GitIndex, hash::AbstractGitHash) =
read_tree!(idx, GitTree(repository(idx), hash))

function add!{T<:AbstractString}(idx::GitIndex, files::T...;
flags::Cuint = Consts.INDEX_ADD_DEFAULT)
Expand Down
88 changes: 28 additions & 60 deletions base/libgit2/libgit2.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ end
function iscommit(id::AbstractString, repo::GitRepo)
res = true
try
c = get(GitCommit, repo, id)
c = GitCommit(repo, id)
if c === nothing
res = false
else
Expand Down Expand Up @@ -94,9 +94,8 @@ See `git diff-index <treeish> [-- <path>]`
"""
function isdiff(repo::GitRepo, treeish::AbstractString, paths::AbstractString=""; cached::Bool=false)
tree_oid = revparseid(repo, "$treeish^{tree}")
iszero(tree_oid) && error("invalid treeish $treeish") # this can be removed by #20104
result = false
tree = get(GitTree, repo, tree_oid)
tree = GitTree(repo, tree_oid)
try
diff = diff_tree(repo, tree, paths, cached=cached)
result = count(diff) > 0
Expand All @@ -112,8 +111,8 @@ function diff_files(repo::GitRepo, branch1::AbstractString, branch2::AbstractStr
filter::Set{Cint}=Set([Consts.DELTA_ADDED, Consts.DELTA_MODIFIED, Consts.DELTA_DELETED]))
b1_id = revparseid(repo, branch1*"^{tree}")
b2_id = revparseid(repo, branch2*"^{tree}")
tree1 = get(GitTree, repo, b1_id)
tree2 = get(GitTree, repo, b2_id)
tree1 = GitTree(repo, b1_id)
tree2 = GitTree(repo, b2_id)
files = AbstractString[]
try
diff = diff_tree(repo, tree1, tree2)
Expand Down Expand Up @@ -241,7 +240,7 @@ function branch!(repo::GitRepo, branch_name::AbstractString,
GitHash(commit)
end
iszero(commit_id) && return
cmt = get(GitCommit, repo, commit_id)
cmt = GitCommit(repo, commit_id)
new_branch_ref = nothing
try
new_branch_ref = create_branch(repo, branch_name, cmt, force=force)
Expand Down Expand Up @@ -298,28 +297,17 @@ function checkout!(repo::GitRepo, commit::AbstractString = "";
end

# search for commit to get a commit object
obj = get(GitUnknownObject, repo, GitHash(commit))
obj === nothing && return
try
peeled = peel(obj, Consts.OBJ_COMMIT)
peeled === nothing && return
opts = force ? CheckoutOptions(checkout_strategy = Consts.CHECKOUT_FORCE) :
CheckoutOptions()
try
# detach commit
obj_oid = GitHash(peeled)
ref = GitReference(repo, obj_oid, force=force,
msg="libgit2.checkout: moving from $head_name to $(string(obj_oid))")
close(ref)

# checkout commit
checkout_tree(repo, peeled, options = opts)
finally
close(peeled)
end
finally
close(obj)
end
obj = GitObject(repo, GitHash(commit))
peeled = peel(GitCommit, obj)

opts = force ? CheckoutOptions(checkout_strategy = Consts.CHECKOUT_FORCE) : CheckoutOptions()
# detach commit
obj_oid = GitHash(peeled)
ref = GitReference(repo, obj_oid, force=force,
msg="libgit2.checkout: moving from $head_name to $(string(obj_oid))")

# checkout commit
checkout_tree(repo, peeled, options = opts)
end

""" git clone [-b <branch>] [--bare] <url> <dir> """
Expand All @@ -343,42 +331,22 @@ end

""" git reset [<committish>] [--] <pathspecs>... """
function reset!(repo::GitRepo, committish::AbstractString, pathspecs::AbstractString...)
obj = revparse(repo, !isempty(committish) ? committish : Consts.HEAD_FILE)
obj = GitObject(repo, isempty(committish) ? Consts.HEAD_FILE : committish)
# do not remove entries in the index matching the provided pathspecs with empty target commit tree
obj === nothing && throw(GitError(Error.Object, Error.ERROR, "`$committish` not found"))
try
head = reset!(repo, Nullable(obj), pathspecs...)
return head
finally
close(obj)
end
return head_oid(repo)
reset!(repo, Nullable(obj), pathspecs...)
end

""" git reset [--soft | --mixed | --hard] <commit> """
function reset!(repo::GitRepo, commit::GitHash, mode::Cint = Consts.RESET_MIXED)
obj = get(GitUnknownObject, repo, commit)
# object must exist for reset
obj === nothing && throw(GitError(Error.Object, Error.ERROR, "Commit `$(string(commit))` object not found"))
try
head = reset!(repo, obj, mode)
return head
finally
close(obj)
end
return head_oid(repo)
end
""" git reset [--soft | --mixed | --hard] <id> """
reset!(repo::GitRepo, id::GitHash, mode::Cint = Consts.RESET_MIXED) =
reset!(repo, GitObject(repo, id), mode)

""" git cat-file <commit> """
function cat{T<:GitObject}(repo::GitRepo, ::Type{T}, object::AbstractString)
obj_id = revparseid(repo, object)
iszero(obj_id) && return nothing

obj = get(T, repo, obj_id)
function cat(repo::GitRepo, spec)
obj = GitObject(repo, spec)
if isa(obj, GitBlob)
return unsafe_string(convert(Ptr{UInt8}, content(obj)))
content(obj)
else
return nothing
nothing
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does this correspond to?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the resulting object is a commit, tag or tree. Arguably this is another function that could be removed altogether.

end
end

Expand Down Expand Up @@ -442,10 +410,10 @@ function merge!(repo::GitRepo;
remotename = with(GitConfig, repo) do cfg
LibGit2.get(String, cfg, "branch.$branchname.remote")
end
obj = with(GitReference(repo, "refs/remotes/$remotename/$branchname")) do ref
oid = with(GitReference(repo, "refs/remotes/$remotename/$branchname")) do ref
LibGit2.GitHash(ref)
end
with(get(GitCommit, repo, obj)) do cmt
with(GitCommit(repo, oid)) do cmt
LibGit2.create_branch(repo, branchname, cmt)
end
return true
Expand Down Expand Up @@ -543,7 +511,7 @@ end
""" Returns all commit authors """
function authors(repo::GitRepo)
return with(GitRevWalker(repo)) do walker
map((oid,repo)->with(get(GitCommit, repo, oid)) do cmt
map((oid,repo)->with(GitCommit(repo, oid)) do cmt
author(cmt)::Signature
end,
walker) #, by = Consts.SORT_TIME)
Expand Down
42 changes: 16 additions & 26 deletions base/libgit2/merge.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,13 @@ function GitAnnotated(repo::GitRepo, fh::FetchHead)
end

function GitAnnotated(repo::GitRepo, comittish::AbstractString)
obj = revparse(repo, comittish)
try
cmt = peel(obj, Consts.OBJ_COMMIT)
cmt === nothing && return nothing
return GitAnnotated(repo, GitHash(cmt))
finally
close(obj)
end
obj = GitObject(repo, comittish)
cmt = peel(GitCommit, obj)
return GitAnnotated(repo, GitHash(cmt))
end

function commit(ann::GitAnnotated)
return GitHash(ccall((:git_annotated_commit_id, :libgit2), Ptr{GitHash}, (Ptr{Void},), ann.ptr))
function GitHash(ann::GitAnnotated)
unsafe_load(ccall((:git_annotated_commit_id, :libgit2), Ptr{GitHash}, (Ptr{Void},), ann.ptr))
end

function merge_analysis(repo::GitRepo, anns::Vector{GitAnnotated})
Expand All @@ -52,23 +47,18 @@ end

"""Fastforward merge changes into current head """
function ffmerge!(repo::GitRepo, ann::GitAnnotated)
ann_cmt_oid = commit(ann)
cmt = get(GitCommit, repo, ann_cmt_oid)
cmt === nothing && return false # could not find commit tree
try
checkout_tree(repo, cmt)
with(head(repo)) do head_ref
cmt_oid = GitHash(cmt)
msg = "libgit2.merge: fastforward $(string(cmt_oid)) into $(name(head_ref))"
new_head_ref = if reftype(head_ref) == Consts.REF_OID
target!(head_ref, cmt_oid, msg=msg)
else
GitReference(repo, cmt_oid, fullname(head_ref), msg=msg)
end
close(new_head_ref)
cmt = GitCommit(repo, GitHash(ann))

checkout_tree(repo, cmt)
with(head(repo)) do head_ref
cmt_oid = GitHash(cmt)
msg = "libgit2.merge: fastforward $(string(cmt_oid)) into $(name(head_ref))"
new_head_ref = if reftype(head_ref) == Consts.REF_OID
target!(head_ref, cmt_oid, msg=msg)
else
GitReference(repo, cmt_oid, fullname(head_ref), msg=msg)
end
finally
close(cmt)
close(new_head_ref)
end
return true
end
Expand Down
Loading