From 341e7309ad06f52e84e5d1fa43cdc6e9b1755f53 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sat, 23 Aug 2014 20:06:52 +0100 Subject: Migration to new libgit2 complete, test suite passes --- Makefile | 7 +++-- lib/gall/ll/git2.c | 53 +++++++++++++++++++++++++++++++++++-- lib/gall/object.lua | 9 +++---- lib/gall/repository.lua | 61 ++++++++++++++++++------------------------- lib/gall/tree.lua | 14 +++++----- test/test-gall.repository.lua | 2 +- 6 files changed, 91 insertions(+), 55 deletions(-) diff --git a/Makefile b/Makefile index 0afd01b..e844f02 100644 --- a/Makefile +++ b/Makefile @@ -14,10 +14,9 @@ INCS := -I/usr/include/lua$(LUA_VER) -Ilibgit2/build/gall-install/include OPT := -O0 -g PIC := -fPIC WARN := -Wall -Werror -DEFS := -D'LUA_INTERP_NAME="$(LUA_INTERP_NAME)"' \ - -D'LUA_INTERP_PATH="$(LUA_INTERP_PATH)"' +DEFS := CFLAGS := $(INCS) $(OPT) $(WARN) $(DEFS) $(PIC) $(CFLAGS) -LIBGIT2_LDEPS ?= -lssl -lrt +LIBGIT2_LDEPS ?= -lssl -lssh2 -lrt LFLAGS := -O1 -g -Llibgit2/build/gall-install/lib -lgit2 $(LIBGIT2_LDEPS) $(LFLAGS) MOD_FILES := $(patsubst %,%.lua,$(subst .,/,$(MODULES))) @@ -56,7 +55,7 @@ libgit2/build/gall-install-stamp: clean: $(RM) luacov.report.out luacov.report.git2.out luacov.stats.out - $(RM) -r libgit2/build luagit2/build lib/gall/ll + $(RM) -r libgit2/build luagit2/build lib/gall/ll/git2.so distclean: clean find . -name "*~" -delete diff --git a/lib/gall/ll/git2.c b/lib/gall/ll/git2.c index 4eecb91..27e2450 100644 --- a/lib/gall/ll/git2.c +++ b/lib/gall/ll/git2.c @@ -97,7 +97,7 @@ static int L_lookup_symbolic_ref(lua_State *L) return 1; } -static int format_oid(lua_State *L, git_oid *oid) +static int format_oid(lua_State *L, const git_oid *oid) { char oidstr[40]; git_oid_fmt(oidstr, oid); @@ -145,6 +145,21 @@ static int L_merge_base(lua_State *L) return push_git2_error(L); } +static int L_set_symbolic_ref(lua_State *L) +{ + git_repository *repo = to_repo(L, 1); + git_reference *ref; + if (git_reference_symbolic_create(&ref, repo, + luaL_checkstring(L, 2), + luaL_checkstring(L, 3), + 1, NULL, NULL) != 0) { + return push_git2_error(L); + } + git_reference_free(ref); + lua_pushboolean(L, 1); + return 1; +} + static int L_gc_odb_object(lua_State *L) { git_odb_object **obj = lua_touserdata(L, 1); @@ -229,7 +244,39 @@ static int L_get_object_raw(lua_State *L) return 1; } -int luaopen_git2(lua_State *L) +static int L_get_tree_table(lua_State *L) +{ + git_repository *repo = to_repo(L, 1); + git_oid oid; + git_tree *tree; + size_t ent; + if (parse_oid(L, 2, &oid) != 0) + return 2; + if (git_tree_lookup(&tree, repo, &oid) != 0) + return push_git2_error(L); + lua_newtable(L); + for (ent = 0; ent < git_tree_entrycount(tree); ++ent) { + const git_tree_entry *tree_ent = + git_tree_entry_byindex(tree, ent); + lua_pushnumber(L, ent+1); + lua_newtable(L); + lua_pushliteral(L, "name"); + lua_pushstring(L, git_tree_entry_name(tree_ent)); + lua_settable(L, -3); + lua_pushliteral(L, "sha"); + format_oid(L, git_tree_entry_id(tree_ent)); + lua_settable(L, -3); + lua_pushliteral(L, "perms"); + lua_pushnumber(L, git_tree_entry_filemode_raw(tree_ent)); + lua_settable(L, -3); + lua_settable(L, -3); + } + + git_tree_free(tree); + return 1; +} + +int luaopen_gall_ll_git2(lua_State *L) { lua_newtable(L); lua_pushliteral(L, "LIBGIT2_VERSION"); @@ -260,9 +307,11 @@ int luaopen_git2(lua_State *L) } while (0) BASIC_FUNC(lookup_symbolic_ref); BASIC_FUNC(lookup_sha_from_ref); + BASIC_FUNC(set_symbolic_ref); BASIC_FUNC(merge_base); BASIC_FUNC(get_object_size); BASIC_FUNC(get_object_type); BASIC_FUNC(get_object_raw); + BASIC_FUNC(get_tree_table); return 1; } diff --git a/lib/gall/object.lua b/lib/gall/object.lua index bedc6f1..f59fb39 100644 --- a/lib/gall/object.lua +++ b/lib/gall/object.lua @@ -23,19 +23,19 @@ local function _objectindex(obj, field) local blob = blobs[obj] if field == "type" then if blob then - ok, ret = 0, blob:type() + 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, blob:size() + 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, blob:data() + 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 @@ -76,8 +76,7 @@ local function _new(repo, sha) local ret = setmetatable({sha=sha}, objectmeta) repos[ret] = repo if ll.git2 then - local oid = ll.git2.OID.hex(sha) - blobs[ret] = repo.git2.odb:read(oid) + blobs[ret] = ll.git2.get_object(repo.git2.repo, sha) end return ret end diff --git a/lib/gall/repository.lua b/lib/gall/repository.lua index 70381cb..38ed398 100644 --- a/lib/gall/repository.lua +++ b/lib/gall/repository.lua @@ -84,14 +84,7 @@ end if ll.git2 then function repomethod:get_ref(ref) - local rref = ll.git2.Reference.lookup(self.git2.repo, ref) - if not rref then - return nil - end - if rref:type() ~= ll.git2.REF_OID then - return nil - end - return tostring(rref:oid()) + return ll.git2.lookup_sha_from_ref(self.git2.repo, ref) end end @@ -153,15 +146,9 @@ function repomethod:normalise(sha) else local fullsha if ll.git2 then - local refobj = ll.git2.Reference.lookup(self.git2.repo, sha) + local refobj = ll.git2.lookup_sha_from_ref(self.git2.repo, sha) if refobj then - if refobj:type() == ll.git2.REF_SYMBOLIC then - refobj = ll.git2.Reference.lookup(self.git2.repo, - refobj:target()) - end - if refobj:type() == ll.git2.REF_OID then - fullsha = tostring(refobj:oid()) - end + fullsha = refobj end end if not fullsha then @@ -228,16 +215,16 @@ if ll.git2 then commitish_2 = commitish_2.content.object end end) - local oid_1 = ll.git2.OID.hex(commitish_1.sha) - local oid_2 = ll.git2.OID.hex(commitish_2.sha) - local oid_base, err = ll.git2.merge.base(self.git2.repo, oid_1, oid_2) + local oid_base, err = ll.git2.merge_base(self.git2.repo, + commitish_1.sha, + commitish_2.sha) if not oid_base then if tostring(err) == "ENOTFOUND" then return true end return nil, err end - return tostring(oid_base), err + return oid_base, err end end @@ -282,17 +269,18 @@ end if ll.git2 then function repomethod:symbolic_ref(name, toref) - local symref = ll.git2.Reference.lookup(self.git2.repo, name) - if not symref then - return nil, "No such ref: " .. tostring(toref) - end - if symref:type() ~= ll.git2.REF_SYMBOLIC then - return false - end if toref then - symref:set_target(toref) + -- Set the ref... + local ok, err = ll.git2.set_symbolic_ref(self.git2.repo, name, toref) + if not ok then + return nil, err + end end - return true, symref:target() + local symref, err = ll.git2.lookup_symbolic_ref(self.git2.repo, name) + if not symref then + return nil, "No such ref: " .. tostring(toref) .. " (" .. err .. ")" + end + return true, symref end end @@ -305,6 +293,8 @@ function repomethod:config(confname, value) end end +--[[ +-- TODO: Add config support to git2.c and convert this if ll.git2 then local old_config = repomethod.config function repomethod:config(confname, value) @@ -325,6 +315,7 @@ if ll.git2 then end end end +]] local repomt = { __index = repomethod, @@ -350,14 +341,12 @@ local function _new(path) local symref if ll.git2 then - local git2, msg = ll.git2.Repository(repopath) + local git2, msg = ll.git2.open_repo(repopath) if not git2 then return nil, "Unable to find Git repository at " .. path end - local odb = git2:odb() - retrepo.git2 = { repo = git2, odb = odb } - symref = ll.git2.Reference.lookup(git2, "HEAD") - symref = symref:target() + retrepo.git2 = { repo = git2 } + symref = ll.git2.lookup_symbolic_ref(git2, "HEAD") else ok, symref = ll.symbolic_ref { "-q", "HEAD", stderr=true, repo=repopath } if ok ~= 0 then @@ -370,6 +359,8 @@ local function _new(path) retrepo.work = workpath retrepo.HEAD = symref +--[[ +-- This seems redundant if ll.git2 then local git2, msg = ll.git2.Repository(retrepo.path) if not git2 then @@ -378,7 +369,7 @@ local function _new(path) local odb = git2:odb() retrepo.git2 = { repo = git2, odb = odb } end - +--]] return setmetatable(retrepo, repomt) end diff --git a/lib/gall/tree.lua b/lib/gall/tree.lua index 14d75ba..a44b333 100644 --- a/lib/gall/tree.lua +++ b/lib/gall/tree.lua @@ -107,14 +107,12 @@ if ll.git2 then end if not parsed[tree] then - local repo = repos[tree] - local oid = ll.git2.OID.hex(objs[tree].sha) - local treeobj = ll.git2.Tree.lookup(repo.git2.repo, oid) - for i = 0, treeobj:entrycount() - 1 do - local entry = treeobj:entry_byindex(i) - local perm = string.format('0x%08X', entry:filemode()) - local sha = tostring(entry:id()) - local name = entry:name() + local treetab = ll.git2.get_tree_table(repos[tree].git2.repo, + objs[tree].sha) + for _, tab in ipairs(treetab) do + local perm = string.format('0x%08X', tab.perms) + local sha = tab.sha + local name = tab.name local obj = repos[tree]:get(sha) local type = obj.type local t = { diff --git a/test/test-gall.repository.lua b/test/test-gall.repository.lua index f945864..87a22f8 100644 --- a/test/test-gall.repository.lua +++ b/test/test-gall.repository.lua @@ -260,7 +260,7 @@ end function suite.symbolic_ref_not_symbolic() local repo = test_repo() local ok, ref = repo:symbolic_ref "refs/heads/master" - assert(ok == false) + assert(not ok) end function suite.symbolic_ref_bad_name() -- cgit v1.2.1