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

upstream and lookup_branch throw if not found #20127

Merged
merged 3 commits into from
Jan 28, 2017
Merged

Conversation

kshyatt
Copy link
Contributor

@kshyatt kshyatt commented Jan 19, 2017

No description provided.

@kshyatt kshyatt added the libgit2 The libgit2 library or the LibGit2 stdlib module label Jan 19, 2017
@kshyatt kshyatt requested a review from simonbyrne January 19, 2017 15:54
@@ -169,10 +169,8 @@ function lookup_branch(repo::GitRepo,
err = ccall((:git_branch_lookup, :libgit2), Cint,
Copy link
Contributor

Choose a reason for hiding this comment

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

I asked on the libgit2 slack, and they said that if an allocating function returns an error then you don't need to free the resulting pointer. So you can just replace this by an @check ccall(...)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oh awesome I can fix my close pr then too :D

Copy link
Contributor Author

@kshyatt kshyatt Jan 19, 2017

Choose a reason for hiding this comment

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

I will fix this in the other PR btw #20128

@@ -185,10 +183,8 @@ function upstream(ref::GitReference)
ref_ptr_ptr = Ref{Ptr{Void}}(C_NULL)
err = ccall((:git_branch_upstream, :libgit2), Cint,
Copy link
Contributor

Choose a reason for hiding this comment

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

and same here as well

@@ -207,7 +207,14 @@ 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)
Copy link
Contributor

Choose a reason for hiding this comment

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

should the force argument still be used?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh yeah probably

@tkelman
Copy link
Contributor

tkelman commented Jan 21, 2017

I think changing this to return a nullable would be preferable to throwing and forcing try-catches everywhere, unless there's a better way of asking in advance whether these lookup operations are going to succeed

@simonbyrne
Copy link
Contributor

simonbyrne commented Jan 21, 2017

I think errors are okay. Most calls to these functions end up checking if it was an error and throwing otherwise (or they don't handle it at all and cause more problems).

Also, these functions are unlikely to be in tight loops, so the performance advantages of Nullable here are not so relevant.

@tkelman
Copy link
Contributor

tkelman commented Jan 21, 2017

A try-catch shouldn't be the only way of asking if something exists.

@simonbyrne
Copy link
Contributor

Agreed, but then we should have separate functions, at least until we've figured out a standard Julia idiom for this.

try
branch_ref = lookup_branch(repo, branch_name)
catch err
if !isa(err, LibGit2.GitError) && err.code != LibGit2.ENOTFOUND
Copy link
Contributor

Choose a reason for hiding this comment

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

shouldn't need this now?

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

function upstream(ref::GitReference)
Copy link
Contributor

Choose a reason for hiding this comment

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

Should document the return value, since Nullable is a bit unexpected. Or maybe call it tryupstream?

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 = Nullable{GitReference}(force ? nothing : lookup_branch(repo, branch_name))
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 lookup_branch return here?

Copy link
Contributor

Choose a reason for hiding this comment

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

if it returns a not-found Nullable, does this end up wrapping it in two layers of Nullable or one?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh nice, good catch

if err != Int(Error.GIT_OK)
if err == Int(Error.ENOTFOUND)
return Nullable{GitReference}()
elseif err != Int(Error.ENOTFOUND) && ref_ptr_ptr[] != C_NULL
Copy link
Contributor

Choose a reason for hiding this comment

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

it can't be ENOTFOUND since it would have just returned?

if err != Int(Error.GIT_OK)
if err == Int(Error.ENOTFOUND)
return Nullable{GitReference}()
elseif err != Int(Error.ENOTFOUND) && ref_ptr_ptr[] != C_NULL
Copy link
Contributor

Choose a reason for hiding this comment

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

same here, would have just returned if it was ENOTFOUND

throw(GitError(Error.Rebase, Error.ERROR,
"There is no tracking information for the current branch."))
end
try
GitAnnotated(repo, brn_ref)
GitAnnotated(repo, get(brn_ref))
Copy link
Contributor

Choose a reason for hiding this comment

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

will this need to be Base.get? if so, was this not covered by tests?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Doesn't need to be Base.get inside base/libgit2, I don't think. It does need to be Base.get in test/libgit2

Copy link
Contributor

Choose a reason for hiding this comment

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

there's still a LibGit2.get that isn't nullable-related, 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.

Soon to be removed. If that breaks this we can just keep importing Base.get?

Copy link
Contributor

Choose a reason for hiding this comment

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

There are a lot of other places where you've used Base.get for nullable unpacking here though - does the LibGit2 module currently import Base.get ? If so it's extending a different concept in a way it probably shouldn't be. If not, then this line is calling the wrong get

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 so it's extending a different concept in a way it probably shouldn't be.

Yes, we all agree, which is why it's being got rid of, which @simonbyrne has an open PR to do.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Anyway I'll make this a Base.get for consistency. This code path is not tested, something we can deal with in a separate PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think it's being imported:

$ git grep -n import base/libgit2
base/libgit2/libgit2.jl:5:import Base: merge!, cat, ==
base/libgit2/types.jl:2:import Base.@kwdef
base/libgit2/types.jl:3:import .Consts: GIT_SUBMODULE_IGNORE, GIT_MERGE_FILE_FAVOR, GIT_MERGE_FILE
base/libgit2/types.jl:590:import Base.securezero!

Copy link
Contributor

Choose a reason for hiding this comment

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

My point wasn't LibGit2.get is bad, that much is obvious. It was the "does the LibGit2 module currently import Base.get ?" question, because the yes/no answer to that determines whether or not this code is correct right now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I did a grep and it appears not to. So the code was incorrect, and I've fixed it, and this code path is not tested currently.

@@ -219,9 +219,9 @@ 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 = Nullable{GitReference}(force ? nothing : lookup_branch(repo, branch_name))
branch_ref = force ? Nullable{GitReference}() : lookup_branch(repo, branch_name)
Copy link
Contributor

Choose a reason for hiding this comment

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

this looks better than relying on the conversion from nothing to a null anyway IMO

end

# checkout selected branch
with(LibGit2.peel(LibGit2.GitTree, ref)) do btree
with(LibGit2.peel(LibGit2.GitTree, get(ref))) do btree
Copy link
Contributor

Choose a reason for hiding this comment

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

Base.get

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think in pkg/ we don't need the Base. part because something is importing it. Look up earlier in the file at the get(ENV calls.

LibGit2.checkout_tree(repo, btree)
end
# switch head to the branch
LibGit2.head!(repo, ref)
LibGit2.head!(repo, get(ref))
Copy link
Contributor

Choose a reason for hiding this comment

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

Base.get

finally
close(ref)
close(get(ref))
Copy link
Contributor

Choose a reason for hiding this comment

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

Base.get

@kshyatt
Copy link
Contributor Author

kshyatt commented Jan 27, 2017

CI passed and I don't think we need Base.get in base/pkg/entry because it's been imported already for ENV. Good to squash?

@tkelman
Copy link
Contributor

tkelman commented Jan 27, 2017

wasn't explicitly imported there, but since Pkg is a submodule of Base and doesn't define its own locally-shadowing get then it resolves to the usual Base one, unlike inside LibGit2

@simonbyrne
Copy link
Contributor

Ah right. In that case, LGTM.

@simonbyrne simonbyrne merged commit 4530c58 into master Jan 28, 2017
@simonbyrne simonbyrne deleted the ksh/upstreamthrow branch January 28, 2017 21:33
"""
upstream(ref::GitReference) -> Nullable{GitReference}

Determine if the branch specified by `ref` has a specified upstream branch.
Copy link
Contributor

Choose a reason for hiding this comment

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

might read more nicely if two different words were used rather than saying specified twice in a row here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libgit2 The libgit2 library or the LibGit2 stdlib module
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants