-
-
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
add GitShortHash type, remove some get methods #20104
Conversation
ccall((:git_oid_fromstrp, :libgit2), Cint, | ||
(Ptr{GitHash}, Cstring), oid_ptr, bstr) | ||
if len < OID_HEXSZ | ||
error("Input string is too short, use `GitShortHash` for partial hashes") |
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 make more sense as an ArgumentError
?
|
||
|
||
|
||
|
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.
Four newlines seems like a lot of vertical whitespace. Perhaps for consistency it should be 1-2?
@deprecate get{T<:GitObject}(::Type{T}, repo::GitRepo, oid::GitHash, oid_size::Int) T(repo, GitShortHash(oid, oid_size)) | ||
@deprecate revparse(repo::GitRepo, objname::AbstractString) GitObject(repo, objname) | ||
@deprecate object(repo::GitRepo, te::GitTreeEntry) GitObject(repo, te) | ||
@deprecate commit(ann::GitAnnotated) GitHash(ann) |
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.
were these previously exported from the LibGit2 module?
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.
No. Should I not bother deprecating them then?
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.
dunno who if anyone would be using these. the main concern is that @deprecate
exports by default, if you want a non exported deprecation then you have to manually call depwarn
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.
These are sometimes used externally (e.g. PkgDev calls LibGit2.get).
I've added an option to @deprecate
on whether to export or not.
9a0af6a
to
776e66d
Compare
776e66d
to
4a1e17a
Compare
else | ||
return nothing | ||
nothing |
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 this correspond to?
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 the resulting object is a commit, tag or tree. Arguably this is another function that could be removed altogether.
end | ||
err != 0 && return GitHash() | ||
oid_ptr = Ref{GitHash}() | ||
@check ccall((:git_oid_fromstrn, :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.
it had been calling fromstrp in this case, will they return the same thing if full length?
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 believe so
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.
Yes, fromstrp
is just the null-terminated version of fromstrn
. Since Julia strings store the length, we might as well use fromstrn
.
end | ||
|
||
Base.hex(id::GitHash) = join([hex(i,2) for i in id.val]) | ||
Base.hex(id::GitShortHash) = hex(id.hash)[1:id.len] |
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 looks like there are two concepts of length for hashes, raw size and hex size, that differ by a factor of 2?
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.
yes, exactly. id.len
is hex size.
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 looked like it was getting used as if it was raw size in a few places, though I may have misread
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's only used in a handful of functions: git_oid_ncmp
and git_object_lookup_prefix
val::NTuple{OID_RAWSZ, UInt8} | ||
GitHash(val::NTuple{OID_RAWSZ, UInt8}) = new(val) | ||
end | ||
GitHash() = GitHash(ntuple(i->zero(UInt8), OID_RAWSZ)) | ||
|
||
immutable GitShortHash <: AbstractGitHash | ||
hash::GitHash | ||
len::Csize_t |
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 be extra careful (and add lots of comments) that this gets used consistently as the right notion of length everywhere, hex or raw
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.
Good point.
4a1e17a
to
ed65d4d
Compare
return c == 0 ? cmp(id1.len, id2.len) : c | ||
end | ||
Base.cmp(id1::GitHash, id2::GitShortHash) = cmp(GitShortHash(id1, OID_RAWSZ), id2) | ||
Base.cmp(id1::GitShortHash, id2::GitHash) = cmp(id1, GitShortHash(id2, OID_RAWSZ)) |
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 these be using OID_HEXSZ then when converting a full GitHash to a GitShortHash?
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.
Ah, yes...
This is a shortened form of `GitHash`, which can be used to identify a git object when it | ||
is unique. | ||
|
||
Internally it is stored as two fields: a full-size `GitHash` (`hash`) and a length (`len`). Only the initial `len` hex digits of `hash` are 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.
line length
close(obj) | ||
return oid | ||
Return the specified git object from `repo` specified by `hash` or `spec`. | ||
- `hash` is a full (`GitHash`) or partial (`GitShortHash`) |
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.
either leave out the parens or add the word hash at the end
ed65d4d
to
74b585d
Compare
Base.cmp(id1::GitHash, id2::GitShortHash) = cmp(GitShortHash(id1, OID_RAWSZ), id2) | ||
Base.cmp(id1::GitShortHash, id2::GitHash) = cmp(id1, GitShortHash(id2, OID_RAWSZ)) | ||
Base.cmp(id1::GitHash, id2::GitShortHash) = cmp(GitShortHash(id1, OID_HEXSZ), id2) | ||
Base.cmp(id1::GitShortHash, id2::GitHash) = cmp(id1, GitShortHash(id2, OID_HEXSZ)) |
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.
guess a comparison that depended on the latter half of the full input would have given differing results here, but we didn't have any such cases?
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 this function was used (or tested for that matter).
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.
via equality only?
|
||
==(id1::GitHash, id2::GitHash) = cmp(id1, id2) == 0 | ||
Base.isless(id1::GitHash, id2::GitHash) = cmp(id1, id2) < 0 | ||
==(id1::AbstractGitHash, id2::AbstractGitHash) = cmp(id1, id2) == 0 |
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 this try to canonicalize short hashes and consider them equal to a full hash if they are unambiguous?
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.
The problem is that they can only be canonicalized in the context of a single repository. But GitHash
es exist independent of the repository.
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 good point. So maybe we shouldn't define this for short hashes, and only use repo-context-aware equality testing with them?
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 know...
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.
Perhaps we could define isequal
with a repo argument for any AbstractGitHash
then as Tony said only have ==
for GitHash
?
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.
Meh, I'm not really convinced it's a problem that different AbstractGitHash
es can refer identify the same object.
We should probably define ==
for GitObject
s as well: could be "are they from the same repo, and are their GitHash
es equal"?
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.
two references to the same object comparing as not equal because they had different partial hash lengths strikes me as unintuitive and not a useful notion of equality
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 guess it depends on whether you view a GitHash
by itself as a reference to an object? Or is it only a reference in the context of a specific repo, in which case you have a GitObject
?
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'm thinking that a GitHash type without a reference to an owning repository isn't all that meaningful on its own.
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.
okay, should we just revert this to ==(id1::GitHash, id2::GitHash) = cmp(id1, id2) == 0
?
@check ccall((:git_index_read_tree, :libgit2), Cint, | ||
(Ptr{Void}, Ptr{Void}), idx.ptr, tree.ptr) | ||
end | ||
function read_tree!(idx::GitIndex, hash::AbstractGitHash) |
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.
Can this be a one-line?
end | ||
return head_oid(repo) | ||
""" git reset [--soft | --mixed | --hard] <id> """ | ||
function reset!(repo::GitRepo, id::GitHash, mode::Cint = Consts.RESET_MIXED) |
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.
Again can this be a one-line?
c62ef8f
to
ec8e2f6
Compare
peel([T,] ref::GitReference) | ||
|
||
Recursively peel `ref` until an object of type `T` is obtained. If no `T` is provided, | ||
then it will be peeled until an object other than a `GitTag` is obtained. |
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.
maybe ref
in place of "it" would be more clear
(same for L181 of repository.jl)
I think this is ready to go. |
peel([T,] obj::GitObject) | ||
|
||
Recursively peel `obj` until an object of type `T` is obtained. If no `T` is provided, | ||
then it will be peeled until the type changes. |
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.
can we put obj
instead of "it" here, otherwise it's potentially ambiguous whether "it" refers to T
or obj
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.
done. I've also added docs for all the GitObject
types.
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.") |
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 this be println? along with the other prints in this function that have been adding \n
manually
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.
done.
@@ -73,15 +73,29 @@ function isattached(repo::GitRepo) | |||
ccall((:git_repository_head_detached, :libgit2), Cint, (Ptr{Void},), repo.ptr) != 1 | |||
end | |||
|
|||
""" | |||
@doc """ |
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.
Why is the @doc
necessary here?
@@ -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)) |
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 this is binary content, it could easily have embedded nuls or be invalid utf-8, 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.
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.
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.
have it return an array of bytes?
end | ||
|
||
function content(blob::GitBlob) | ||
s = String(rawcontent) |
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.
rawcontent(blob)
Can this be merged? |
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.
Looks good to me!
Another part of #19839.