Skip to content

Commit

Permalink
upstream and lookup_branch throw if not found (#20127)
Browse files Browse the repository at this point in the history
* upstream and lookup_branch throw if not found
* Add docs
* Fix double-nullable
  • Loading branch information
kshyatt authored and simonbyrne committed Jan 28, 2017
1 parent 34d0f15 commit 4530c58
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 35 deletions.
36 changes: 18 additions & 18 deletions base/libgit2/libgit2.jl
Original file line number Diff line number Diff line change
Expand Up @@ -219,22 +219,22 @@ function branch!(repo::GitRepo, branch_name::AbstractString,
force::Bool=false, # force branch creation
set_head::Bool=true) # set as head reference on exit
# try to lookup branch first
branch_ref = force ? nothing : lookup_branch(repo, branch_name)
if branch_ref === nothing
branch_rmt_ref = isempty(track) ? nothing : lookup_branch(repo, "$track/$branch_name", true)
branch_ref = force ? Nullable{GitReference}() : lookup_branch(repo, branch_name)
if isnull(branch_ref)
branch_rmt_ref = isempty(track) ? Nullable{GitReference}() : lookup_branch(repo, "$track/$branch_name", true)
# if commit is empty get head commit oid
commit_id = if isempty(commit)
if branch_rmt_ref === nothing
if isnull(branch_rmt_ref)
with(head(repo)) do head_ref
with(peel(GitCommit, head_ref)) do hrc
GitHash(hrc)
end
end
else
tmpcmt = with(peel(GitCommit, branch_rmt_ref)) do hrc
tmpcmt = with(peel(GitCommit, Base.get(branch_rmt_ref))) do hrc
GitHash(hrc)
end
close(branch_rmt_ref)
close(Base.get(branch_rmt_ref))
tmpcmt
end
else
Expand All @@ -244,10 +244,10 @@ function branch!(repo::GitRepo, branch_name::AbstractString,
cmt = get(GitCommit, repo, commit_id)
new_branch_ref = nothing
try
new_branch_ref = create_branch(repo, branch_name, cmt, force=force)
new_branch_ref = Nullable(create_branch(repo, branch_name, cmt, force=force))
finally
close(cmt)
new_branch_ref === nothing && throw(GitError(Error.Object, Error.ERROR, "cannot create branch `$branch_name` with `$commit_id`"))
isnull(new_branch_ref) && throw(GitError(Error.Object, Error.ERROR, "cannot create branch `$branch_name` with `$commit_id`"))
branch_ref = new_branch_ref
end
end
Expand All @@ -257,7 +257,7 @@ function branch!(repo::GitRepo, branch_name::AbstractString,
try
with(GitConfig, repo) do cfg
set!(cfg, "branch.$branch_name.remote", Consts.REMOTE_ORIGIN)
set!(cfg, "branch.$branch_name.merge", name(branch_ref))
set!(cfg, "branch.$branch_name.merge", name(Base.get(branch_ref)))
end
catch
warn("Please provide remote tracking for branch '$branch_name' in '$(path(repo))'")
Expand All @@ -266,15 +266,15 @@ function branch!(repo::GitRepo, branch_name::AbstractString,

if set_head
# checkout selected branch
with(peel(GitTree, branch_ref)) do btree
with(peel(GitTree, Base.get(branch_ref))) do btree
checkout_tree(repo, btree)
end

# switch head to the branch
head!(repo, branch_ref)
head!(repo, Base.get(branch_ref))
end
finally
close(branch_ref)
close(Base.get(branch_ref))
end
return
end
Expand Down Expand Up @@ -452,14 +452,14 @@ function merge!(repo::GitRepo;
else
with(head(repo)) do head_ref
tr_brn_ref = upstream(head_ref)
if tr_brn_ref === nothing
if isnull(tr_brn_ref)
throw(GitError(Error.Merge, Error.ERROR,
"There is no tracking information for the current branch."))
end
try
[GitAnnotated(repo, tr_brn_ref)]
[GitAnnotated(repo, Base.get(tr_brn_ref))]
finally
close(tr_brn_ref)
close(Base.get(tr_brn_ref))
end
end
end
Expand Down Expand Up @@ -494,14 +494,14 @@ a `GitError`. This is roughly equivalent to the following command line statement
function rebase!(repo::GitRepo, upstream::AbstractString="", newbase::AbstractString="")
with(head(repo)) do head_ref
head_ann = GitAnnotated(repo, head_ref)
upst_ann = if isempty(upstream)
upst_ann = if isempty(upstream)
brn_ref = LibGit2.upstream(head_ref)
if brn_ref === nothing
if isnull(brn_ref)
throw(GitError(Error.Rebase, Error.ERROR,
"There is no tracking information for the current branch."))
end
try
GitAnnotated(repo, brn_ref)
GitAnnotated(repo, Base.get(brn_ref))
finally
close(brn_ref)
end
Expand Down
38 changes: 30 additions & 8 deletions base/libgit2/reference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,17 @@ function head!(repo::GitRepo, ref::GitReference)
return ref
end

"""
lookup_branch(repo::GitRepo, branch_name::AbstractString, remote::Bool=false) -> Nullable{GitReference}
Determine if the branch specified by `branch_name` exists in the repository `repo`.
If `remote` is `true`, `repo` is assumed to be a remote git repository. Otherwise, it
is part of the local filesystem.
`lookup_branch` returns a `Nullable`, which will be null if the requested branch does
not exist yet. If the branch does exist, the `Nullable` contains a `GitReference` to
the branch.
"""
function lookup_branch(repo::GitRepo,
branch_name::AbstractString,
remote::Bool=false)
Expand All @@ -169,31 +180,42 @@ function lookup_branch(repo::GitRepo,
err = ccall((:git_branch_lookup, :libgit2), Cint,
(Ptr{Ptr{Void}}, Ptr{Void}, Ptr{UInt8}, Cint),
ref_ptr_ptr, repo.ptr, branch_name, branch_type)
if err == Int(Error.ENOTFOUND)
return nothing
elseif err != Int(Error.GIT_OK)
if err != Int(Error.GIT_OK)
if err == Int(Error.ENOTFOUND)
return Nullable{GitReference}()
end
if ref_ptr_ptr[] != C_NULL
close(GitReference(repo, ref_ptr_ptr[]))
end
throw(Error.GitError(err))
end
return GitReference(repo, ref_ptr_ptr[])
return Nullable{GitReference}(GitReference(repo, ref_ptr_ptr[]))
end

"""
upstream(ref::GitReference) -> Nullable{GitReference}
Determine if the branch specified by `ref` has a specified upstream branch.
`upstream` returns a `Nullable`, which will be null if the requested branch does
not have an upstream counterpart. If the upstream branch does exist, the `Nullable`
contains a `GitReference` to the upstream branch.
"""
function upstream(ref::GitReference)
isempty(ref) && return nothing
ref_ptr_ptr = Ref{Ptr{Void}}(C_NULL)
err = ccall((:git_branch_upstream, :libgit2), Cint,
(Ref{Ptr{Void}}, Ptr{Void},), ref_ptr_ptr, ref.ptr)
if err == Int(Error.ENOTFOUND)
return nothing
elseif err != Int(Error.GIT_OK)
if err != Int(Error.GIT_OK)
if err == Int(Error.ENOTFOUND)
return Nullable{GitReference}()
end
if ref_ptr_ptr[] != C_NULL
close(GitReference(ref.repo, ref_ptr_ptr[]))
end
throw(Error.GitError(err))
end
return GitReference(ref.repo, ref_ptr_ptr[])
return Nullable{GitReference}(GitReference(ref.repo, ref_ptr_ptr[]))
end

repository(ref::GitReference) = ref.repo
Expand Down
10 changes: 5 additions & 5 deletions base/pkg/entry.jl
Original file line number Diff line number Diff line change
Expand Up @@ -312,25 +312,25 @@ function pin(pkg::AbstractString, head::AbstractString)
end
ref = LibGit2.lookup_branch(repo, branch)
try
if ref !== nothing
if !isnull(ref)
if LibGit2.revparseid(repo, branch) != id
throw(PkgError("Package $pkg: existing branch $branch has " *
"been edited and doesn't correspond to its original commit"))
end
info("Package $pkg: checking out existing branch $branch")
else
info("Creating $pkg branch $branch")
ref = LibGit2.create_branch(repo, branch, commit)
ref = Nullable(LibGit2.create_branch(repo, branch, commit))
end

# checkout selected branch
with(LibGit2.peel(LibGit2.GitTree, ref)) do btree
with(LibGit2.peel(LibGit2.GitTree, get(ref))) do btree
LibGit2.checkout_tree(repo, btree)
end
# switch head to the branch
LibGit2.head!(repo, ref)
LibGit2.head!(repo, get(ref))
finally
close(ref)
close(get(ref))
end
finally
close(commit)
Expand Down
8 changes: 4 additions & 4 deletions test/libgit2.jl
Original file line number Diff line number Diff line change
Expand Up @@ -324,17 +324,17 @@ mktempdir() do dir
@test LibGit2.name(brref) == "refs/heads/master"
@test LibGit2.shortname(brref) == master_branch
@test LibGit2.ishead(brref)
@test LibGit2.upstream(brref) === nothing
@test isnull(LibGit2.upstream(brref))
@test repo.ptr == LibGit2.repository(brref).ptr
@test brnch == master_branch
@test LibGit2.headname(repo) == master_branch
LibGit2.branch!(repo, test_branch, string(commit_oid1), set_head=false)

@test LibGit2.lookup_branch(repo, test_branch, true) === nothing
tbref = LibGit2.lookup_branch(repo, test_branch, false)
@test isnull(LibGit2.lookup_branch(repo, test_branch, true))
tbref = Base.get(LibGit2.lookup_branch(repo, test_branch, false))
try
@test LibGit2.shortname(tbref) == test_branch
@test LibGit2.upstream(tbref) === nothing
@test isnull(LibGit2.upstream(tbref))
finally
close(tbref)
end
Expand Down

0 comments on commit 4530c58

Please sign in to comment.