Skip to content

Commit f944d30

Browse files
authored
Add method to compute GitShortHash of a GitObject. (JuliaLang#20871)
1 parent 7affd0c commit f944d30

File tree

3 files changed

+74
-6
lines changed

3 files changed

+74
-6
lines changed

base/libgit2/oid.jl

+60
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,23 @@ function GitHash(ptr::Ptr{UInt8})
99
return oid_ptr[]
1010
end
1111

12+
"""
13+
GitHash(id::Vector{UInt8})
14+
15+
Construct a `GitHash` from a vector of $OID_RAWSZ bytes.
16+
"""
1217
function GitHash(id::Array{UInt8,1})
1318
if length(id) != OID_RAWSZ
1419
throw(ArgumentError("invalid raw buffer size"))
1520
end
1621
return GitHash(pointer(id))
1722
end
1823

24+
"""
25+
GitHash(id::AbstractString)
26+
27+
Construct a `GitHash` from a string of $OID_HEXSZ hexadecimal digits.
28+
"""
1929
function GitHash(id::AbstractString)
2030
bstr = String(id)
2131
len = sizeof(bstr)
@@ -27,6 +37,19 @@ function GitHash(id::AbstractString)
2737
(Ptr{GitHash}, Ptr{UInt8}, Csize_t), oid_ptr, bstr, len)
2838
return oid_ptr[]
2939
end
40+
41+
function GitShortHash(buf::Buffer)
42+
oid_ptr = Ref{GitHash}()
43+
@check ccall((:git_oid_fromstrn, :libgit2), Cint,
44+
(Ptr{GitHash}, Ptr{UInt8}, Csize_t), oid_ptr, buf.ptr, buf.size)
45+
GitShortHash(oid_ptr[], buf.size)
46+
end
47+
48+
"""
49+
GitShortHash(id::AbstractString)
50+
51+
Construct a `GitShortHash` from a string of at most $OID_HEXSZ hexadecimal digits.
52+
"""
3053
function GitShortHash(id::AbstractString)
3154
bstr = String(id)
3255
len = sizeof(bstr)
@@ -44,6 +67,15 @@ macro githash_str(id)
4467
GitHash(id)
4568
end
4669
end
70+
71+
72+
"""
73+
GitHash(ref::GitReference)
74+
75+
Get the identifier (`GitHash`) of the object referred to by the direct reference
76+
`ref`. Note: this does not work for symbolic references; in such cases use
77+
`GitHash(repo::GitRepo, ref_name::AbstractString)` instead.
78+
"""
4779
function GitHash(ref::GitReference)
4880
isempty(ref) && return GitHash()
4981
reftype(ref) != Consts.REF_OID && return GitHash()
@@ -52,6 +84,13 @@ function GitHash(ref::GitReference)
5284
return GitHash(oid_ptr)
5385
end
5486

87+
88+
"""
89+
GitHash(repo::GitRepo, ref_name::AbstractString)
90+
91+
Get the identifier (`GitHash`) of the object referred to by reference specified by
92+
`ref_name`.
93+
"""
5594
function GitHash(repo::GitRepo, ref_name::AbstractString)
5695
isempty(repo) && return GitHash()
5796
oid_ptr = Ref(GitHash())
@@ -61,10 +100,31 @@ function GitHash(repo::GitRepo, ref_name::AbstractString)
61100
return oid_ptr[]
62101
end
63102

103+
"""
104+
GitHash(obj::GitObject)
105+
106+
Get the identifier (`GitHash`) of `obj`.
107+
"""
64108
function GitHash(obj::GitObject)
65109
GitHash(ccall((:git_object_id, :libgit2), Ptr{UInt8}, (Ptr{Void},), obj.ptr))
66110
end
67111

112+
"""
113+
GitShortHash(obj::GitObject)
114+
115+
Get a shortened identifier (`GitShortHash`) of `obj`. The minimum length (in characters)
116+
is determined by the `core.abbrev` config option, and will be of sufficient length to
117+
unambiuously identify the object in the repository.
118+
"""
119+
function GitShortHash(obj::GitObject)
120+
buf_ref = Ref(Buffer())
121+
@check ccall((:git_object_short_id, :libgit2), Cint,
122+
(Ptr{Buffer},Ptr{Void}), buf_ref, obj.ptr)
123+
sid = GitShortHash(buf_ref[])
124+
free(buf_ref)
125+
return sid
126+
end
127+
68128
Base.hex(id::GitHash) = join([hex(i,2) for i in id.val])
69129
Base.hex(id::GitShortHash) = hex(id.hash)[1:id.len]
70130

base/libgit2/types.jl

+4-6
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,11 @@ end
2222
GitHash() = GitHash(ntuple(i->zero(UInt8), OID_RAWSZ))
2323

2424
"""
25-
GitShortHash
25+
GitShortHash(hash::GitHash, len::Integer)
2626
27-
This is a shortened form of `GitHash`, which can be used to identify a git object when it
28-
is unique.
29-
30-
Internally it is stored as two fields: a full-size `GitHash` (`hash`) and a length
31-
(`len`). Only the initial `len` hex digits of `hash` are used.
27+
A shortened git object identifier, which can be used to identify a git object when it is
28+
unique, consisting of the initial `len` hexadecimal digits of `hash` (the remaining digits
29+
are ignored).
3230
"""
3331
struct GitShortHash <: AbstractGitHash
3432
hash::GitHash # underlying hash: unused digits are ignored

test/libgit2.jl

+10
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,16 @@ mktempdir() do dir
473473
@test !(short_oid1 < commit_oid1)
474474
short_str = sprint(show, short_oid1)
475475
@test short_str == "GitShortHash(\"$(string(short_oid1))\")"
476+
short_oid2 = LibGit2.GitShortHash(cmt)
477+
@test startswith(hex(commit_oid1), hex(short_oid2))
478+
479+
cmt2 = LibGit2.GitCommit(repo, short_oid2)
480+
try
481+
@test commit_oid1 == LibGit2.GitHash(cmt2)
482+
finally
483+
close(cmt2)
484+
end
485+
476486
auth = LibGit2.author(cmt)
477487
@test isa(auth, LibGit2.Signature)
478488
@test auth.name == test_sig.name

0 commit comments

Comments
 (0)