1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
|
-- gall.object
--
-- Git Abstraction Layer for Lua -- Generic object interface
--
-- Copyright 2012 Daniel Silverstone <dsilvers@digital-scurf.org>
--
--
---
-- Generic object interface
--
-- @module gall.object
local ll = require "gall.ll"
local commit = require "gall.commit"
local tree = require "gall.tree"
local tag = require "gall.tag"
local repos = setmetatable({}, {__mode="k"})
local blobs = setmetatable({}, {__mode="k"})
local known_types = {
blob = true, commit = true, tree = true, tag = true,
}
local function _objectindex(obj, field)
local ok, ret
local blob = blobs[obj]
if field == "type" then
if blob then
ok, ret = 0, ll.git2.get_object_type(blob)
else
ok, ret = repos[obj]:gather("cat-file", "-t", obj.sha)
end
elseif field == "size" then
if blob then
ok, ret = 0, ll.git2.get_object_size(blob)
else
ok, ret = repos[obj]:gather("cat-file", "-s", obj.sha)
end
elseif field == "raw" then
if blob and obj.type ~= "tree" then
ok, ret = 0, ll.git2.get_object_raw(blob)
else
ok, ret = repos[obj]:rawgather("cat-file", (obj.type == "tag" and "tag" or "-p"), obj.sha)
end
elseif field == "content" then
assert(known_types[obj.type], "Unknown type: " .. obj.type)
if obj.type == "blob" then
ok, ret = 0, obj.raw
elseif obj.type == "commit" then
ok, ret = 0, commit.new(repos[obj], obj)
elseif obj.type == "tree" then
ok, ret = 0, tree.new(repos[obj], obj)
elseif obj.type == "tag" then
ok, ret = 0, tag.new(repos[obj], obj)
end
else
error("Unknown field <" .. tostring(field) .. ">")
end
assert(ok == 0, "Unable to retrieve " .. field)
if field == "size" then ret = tonumber(ret) end
rawset(obj, field, ret)
return ret
end
function _objecttostring(obj)
return "<GitObject(" .. tostring(obj.sha)..") in " .. tostring(repos[obj]) .. ">"
end
local objectmeta = {
__index = _objectindex,
__tostring = _objecttostring
}
---
-- Low level git object
--
-- @type object
---
-- The type of the object
--
-- @field type
---
-- The size of the object
--
-- @field size
---
-- The object's raw content
--
-- @field raw
---
-- The object's processed content.
--
-- * If the object is a commit, then this will be a @{commit} instance.
-- * If the object is a tree, then this will be a @{tree} instance.
-- * If the object is a tag, then this will be a @{tag} instance.
--
-- @field content
---
-- The object's OID (SHA1)
--
-- @field sha
--- @section end
---
-- Create a new raw object.
--
-- Create a new instance of @{object} referring to the given SHA1 OID.
--
-- @function new
-- @tparam repository repo The repository within which the object resides.
-- @tparam string sha The SHA1 OID of the object in the repository.
-- @treturn object The object instance encapsulating the given object.
local function _new(repo, sha)
local ret = setmetatable({sha=sha}, objectmeta)
repos[ret] = repo
if ll.git2 then
blobs[ret] = ll.git2.get_object(repo.git2.repo, sha)
end
return ret
end
---
-- Create a new raw object.
--
-- Create a new raw object and insert it into the given repository. This will
-- not only create the @{object} instance but also insert it into the
-- repository storage.
--
-- @function create
-- @tparam repository repo The repository within which the object resides.
-- @tparam string type The type of the object (e.g. blob or commit)
-- @tparam string content The content to insert as the object's content.
-- @treturn[1] object The object instance encapsulating the given object.
-- @treturn[2] nil Nil on error
-- @treturn[2] string The error message
local function _create(repo, type, content)
local why, sha =
repo:_run_with_input(content, ll.chomp,
"hash-object", "-t", type, "-w", "--stdin")
if why ~= 0 then
return nil, "hash-object returned " .. tostring(why)
end
return _new(repo, sha)
end
return {
new = _new,
create = _create,
}
|