-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Conversation
@@ -169,10 +169,8 @@ function lookup_branch(repo::GitRepo, | |||
err = ccall((:git_branch_lookup, :libgit2), Cint, |
There was a problem hiding this comment.
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(...)
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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
024b003
to
e80782a
Compare
@@ -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) |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yeah probably
e80782a
to
4865f02
Compare
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 |
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. |
A try-catch shouldn't be the only way of asking if something exists. |
Agreed, but then we should have separate functions, at least until we've figured out a standard Julia idiom for this. |
4865f02
to
1bfd093
Compare
try | ||
branch_ref = lookup_branch(repo, branch_name) | ||
catch err | ||
if !isa(err, LibGit2.GitError) && err.code != LibGit2.ENOTFOUND |
There was a problem hiding this comment.
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?
1bfd093
to
2d196e1
Compare
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) |
There was a problem hiding this comment.
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
?
2d196e1
to
b46c391
Compare
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)) |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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)) |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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!
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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
0af7d4e
to
d0d2306
Compare
end | ||
|
||
# checkout selected branch | ||
with(LibGit2.peel(LibGit2.GitTree, ref)) do btree | ||
with(LibGit2.peel(LibGit2.GitTree, get(ref))) do btree |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Base.get
There was a problem hiding this comment.
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)) |
There was a problem hiding this comment.
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)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Base.get
CI passed and I don't think we need |
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 |
Ah right. In that case, LGTM. |
""" | ||
upstream(ref::GitReference) -> Nullable{GitReference} | ||
|
||
Determine if the branch specified by `ref` has a specified upstream branch. |
There was a problem hiding this comment.
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
No description provided.