diff options
author | Daniel Silverstone <dsilvers@digital-scurf.org> | 2012-09-08 23:03:45 +0100 |
---|---|---|
committer | Daniel Silverstone <dsilvers@digital-scurf.org> | 2012-09-08 23:04:43 +0100 |
commit | 42ea9108d73e0d1fb415892879c10dd37235c6b7 (patch) | |
tree | a4f18fa6aa926991f5abbcfa44edfe24fecd4345 /lib | |
parent | d068d64d01dbfad2162ce5c31474d868f418e32c (diff) | |
download | gitano-42ea9108d73e0d1fb415892879c10dd37235c6b7.tar.gz |
GITANO: Migrate from gitano.git to gall
Diffstat (limited to 'lib')
-rw-r--r-- | lib/gitano.lua | 2 | ||||
-rw-r--r-- | lib/gitano/actions.lua | 4 | ||||
-rw-r--r-- | lib/gitano/config.lua | 8 | ||||
-rw-r--r-- | lib/gitano/git.lua | 28 | ||||
-rw-r--r-- | lib/gitano/git/commit.lua | 165 | ||||
-rw-r--r-- | lib/gitano/git/ll.lua | 98 | ||||
-rw-r--r-- | lib/gitano/git/object.lua | 78 | ||||
-rw-r--r-- | lib/gitano/git/repository.lua | 279 | ||||
-rw-r--r-- | lib/gitano/git/tag.lua | 97 | ||||
-rw-r--r-- | lib/gitano/git/tree.lua | 209 | ||||
-rw-r--r-- | lib/gitano/lace.lua | 6 | ||||
-rw-r--r-- | lib/gitano/repository.lua | 28 |
12 files changed, 23 insertions, 979 deletions
diff --git a/lib/gitano.lua b/lib/gitano.lua index b2f8244..ad3cd7c 100644 --- a/lib/gitano.lua +++ b/lib/gitano.lua @@ -6,7 +6,6 @@ -- local util = require 'gitano.util' -local git = require 'gitano.git' local config = require 'gitano.config' local repository = require 'gitano.repository' local log = require 'gitano.log' @@ -18,7 +17,6 @@ local supple = require 'gitano.supple' return { util = util, - git = git, config = config, repository = repository, log = log, diff --git a/lib/gitano/actions.lua b/lib/gitano/actions.lua index c19a97c..b0aec5c 100644 --- a/lib/gitano/actions.lua +++ b/lib/gitano/actions.lua @@ -6,7 +6,7 @@ local util = require "gitano.util" local log = require "gitano.log" -local git = require "gitano.git" +local gall = require "gall" local config = require "gitano.config" local sio = require 'luxio.simple' local supple = require 'gitano.supple' @@ -171,7 +171,7 @@ local function cia_branch_update_gen(project, branch, repo, if parent then parent = parent.content.tree.content else - parent = repo.git:get(git.tree.empty_sha).content + parent = repo.git:get(gall.tree.empty_sha).content end local treedelta = parent:diff_to(mytree) local filelist = {} diff --git a/lib/gitano/config.lua b/lib/gitano/config.lua index a56427b..865e222 100644 --- a/lib/gitano/config.lua +++ b/lib/gitano/config.lua @@ -8,7 +8,7 @@ -- Copyright 2012 Daniel Silverstone <dsilvers@digital-scurf.org> -- -local git = require 'gitano.git' +local gall = require 'gall' local log = require 'gitano.log' local lace = require 'gitano.lace' local sio = require 'luxio.simple' @@ -48,7 +48,7 @@ end local function parse_admin_config(commit) local gittree = commit.content.tree - local flat_tree = git.tree.flatten(gittree.content) + local flat_tree = gall.tree.flatten(gittree.content) local function is_blob(thingy) return thingy and thingy.type and thingy.type == "blob" @@ -399,7 +399,7 @@ local function commit_config_changes(conf, desc, username) newtree[gtab.meta.prefix .. g .. ".conf"] = conf.repo.git:get(obj) end - local tree, msg = git.tree.create(conf.repo.git, newtree) + local tree, msg = gall.tree.create(conf.repo.git, newtree) if not tree then return nil, msg end @@ -410,7 +410,7 @@ local function commit_config_changes(conf, desc, username) }) or admin_name local commit, msg = - git.commit.create(conf.repo.git, { + gall.commit.create(conf.repo.git, { author = person, committer = person, message = desc or "Updated", diff --git a/lib/gitano/git.lua b/lib/gitano/git.lua deleted file mode 100644 index f77e0bd..0000000 --- a/lib/gitano/git.lua +++ /dev/null @@ -1,28 +0,0 @@ --- gitano.git --- --- Core Git functionality for Gitano --- --- Copyright 2012 Daniel Silverstone <dsilvers@digital-scurf.org> --- --- - -local ll = require "gitano.git.ll" -local object = require "gitano.git.object" -local commit = require "gitano.git.commit" -local tree = require "gitano.git.tree" -local repo = require "gitano.git.repository" -local tag = require "gitano.git.tag" - - -return { - open = repo.new, - - -- Sub modules - repository = repo, - object = object, - commit = commit, - tree = tree, - tag = tag, - -- Finally LL - ll = ll -}
\ No newline at end of file diff --git a/lib/gitano/git/commit.lua b/lib/gitano/git/commit.lua deleted file mode 100644 index ebee865..0000000 --- a/lib/gitano/git/commit.lua +++ /dev/null @@ -1,165 +0,0 @@ --- gitano.git.commit --- --- Core Git functionality for Gitano --- --- Copyright 2012 Daniel Silverstone <dsilvers@digital-scurf.org> --- --- - -local ll = require "gitano.git.ll" - -local objs = setmetatable({}, {__mode="k"}) -local repos = setmetatable({}, {__mode="k"}) -local parsed = setmetatable({}, {__mode="k"}) - -local _new - -local function parse_person(pers) - local real, email, when, tz = pers:match("^(.-) <([^>]+)> ([0-9]+) ([+-][0-9]+)$") - return { - realname = real, - email = email, - unixtime = when, - timezone = tz - } -end - -local function parse_parents(repo, ps) - local ret = {} - for _, psha in ipairs(ps) do - ret[_] = repo:get(psha) - end - return ret -end - -local function commitindex(commit, field) - if not parsed[commit] then - local raw = objs[commit].raw - local headers, body, signature = {}, "" - local state = "headers" - - for l in raw:gmatch("([^\n]*)\n") do - if state == "headers" then - local first, second = l:match("^([^ ]+) (.+)$") - if first then - if headers[first] then - headers[first][#headers[first]+1] = second - else - headers[first] = { second } - end - else - state = "message" - end - elseif state == "message" then - if l == PGP_SIG_START then - signature = l .. "\n" - state = "signature" - else - body = body .. l .. "\n" - end - else - signature = signature .. l .. "\n" - end - end - - -- there's always one tree - rawset(commit, "tree", repos[commit]:get(headers.tree[1])) - -- Always one author - rawset(commit, "author", parse_person(headers.author[1])) - -- Always one committer - rawset(commit, "committer", parse_person(headers.committer[1])) - -- Zero or more parents - headers.parent = headers.parent or {} - rawset(commit, "parents", parse_parents(repos[commit], headers.parent)) - -- A message - rawset(commit, "message", body) - -- And an optional signature - rawset(commit, "signature", signature) - -- Promote the SHA - rawset(commit, "sha", objs[commit].sha) - - -- Signal we are parsed - parsed[commit] = true - end - - return rawget(commit, field) -end - -local function committostring(commit) - return "<GitCommit(" .. tostring(objs[commit].sha) .. ") in " .. tostring(repos[commit]) .. ">" -end - -local commitmeta = { - __index = commitindex, - __tostring = committostring -} - -function _new(repo, obj) - local ret = setmetatable({}, commitmeta) - objs[ret] = obj - repos[ret] = repo - return ret -end - -function _create(repo, data) - if not data.tree then - return nil, "No tree?" - end - if not data.author then - return nil, "No author?" - end - if not data.committer then - return nil, "No committer?" - end - if not data.author.realname then - return nil, "No author name?" - end - if not data.author.email then - return nil, "No author email?" - end - if not data.committer.realname then - return nil, "No committer name?" - end - if not data.committer.email then - return nil, "No committer email?" - end - if not data.message then - return nil, "No message?" - end - if not data.parents then - data.parents = {} - end - - -- Construct the commandline and environment - local env = { - GIT_AUTHOR_NAME = data.author.realname, - GIT_AUTHOR_EMAIL = data.author.email, - GIT_COMMITTER_NAME = data.committer.realname, - GIT_COMMITTER_EMAIL = data.committer.email, - } - local cmd = { - "commit-tree", data.tree.sha - } - for i, v in ipairs(data.parents) do - cmd[#cmd+1] = "-p" - cmd[#cmd+1] = v.sha - end - - if not data.message:match("\n$") then - data.message = data.message .. "\n" - end - - local why, sha = repo:_run_with_input_and_env(env, data.message, - ll.chomp, unpack(cmd)) - - if why ~= 0 then - return nil, "commit-tree returned " .. tostring(why) - end - - return repo:get(sha) -end - -return { - create = _create, - new = _new -} diff --git a/lib/gitano/git/ll.lua b/lib/gitano/git/ll.lua deleted file mode 100644 index 4f2d025..0000000 --- a/lib/gitano/git/ll.lua +++ /dev/null @@ -1,98 +0,0 @@ --- gitano.git.ll --- --- Low level git interface routines for Gitano --- --- Copyright 2012 Daniel Silverstone <dsilvers@digital-scurf.org> --- --- - -local sp = require "luxio.subprocess" -local util = require "gitano.util" - -local assert = assert - -local git_exe = "git" - -local function _rungit(t) - assert(t.repo, "No repository?") - - local proc_args = { - env = {}, - git_exe, unpack(t) - } - - for k, v in pairs(t.env or {}) do - proc_args.env[k] = v - end - - proc_args.env.GIT_DIR = t.repo - - if t.stdin then - proc_args.stdin = t.stdin - end - - if t.stdout then - proc_args.stdout = sp.PIPE - end - - if t.stderr then - proc_args.stderr = sp.PIPE - end - - local proc = sp.spawn_simple(proc_args) - local stdout, stderr - - if t.stdout then - stdout = proc.stdout:read("*a") - proc.stdout:close() - if type(t.stdout) == "function" then - stdout = t.stdout(stdout) - end - end - - if t.stderr then - stderr = proc.stderr:read("*a") - proc.stderr:close() - if type(t.stderr) == "function" then - stderr = t.stderr(stderr) - end - end - - local how, why = proc:wait() - - assert(how == "exit", "Not cleanly exited") - - return why, stdout, stderr -end - -local function _setgit(e) - git_exe = e -end - -local function _chomp(s) - local rest = s:match("^(.*)\n$") - return rest or s -end - -local mod_ret = { - rungit = _rungit, - setgit = _setgit, - chomp = _chomp -} - -local simple_cmds = { - "cat-file", "symbolic-ref", "show-ref", - "hash-object", "ls-tree", "init", "merge-base", "rev-list", "config" -} - -for _, s in pairs(simple_cmds) do - local ss = s:gsub("%-", "_") - mod_ret[ss] = function(_t) - local t = util.deep_copy(_t) - table.insert(t, 1, s) - t.stdout = _chomp - return _rungit(t) - end -end - -return mod_ret diff --git a/lib/gitano/git/object.lua b/lib/gitano/git/object.lua deleted file mode 100644 index 0778bdc..0000000 --- a/lib/gitano/git/object.lua +++ /dev/null @@ -1,78 +0,0 @@ --- gitano.git.object --- --- Core Git functionality for Gitano --- --- Copyright 2012 Daniel Silverstone <dsilvers@digital-scurf.org> --- --- - -local ll = require "gitano.git.ll" -local commit = require "gitano.git.commit" -local tree = require "gitano.git.tree" -local tag = require "gitano.git.tag" - -local repos = setmetatable({}, {__mode="k"}) - -local function _objectindex(obj, field) - local ok, ret - if field == "type" then - ok, ret = repos[obj]:gather("cat-file", "-t", obj.sha) - elseif field == "size" then - ok, ret = repos[obj]:gather("cat-file", "-s", obj.sha) - elseif field == "raw" then - ok, ret = repos[obj]:rawgather("cat-file", (obj.type == "tag" and "tag" or "-p"), obj.sha) - elseif field == "content" then - 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) - else - error("Unknown type <" .. obj.type .. "> for content parse") - 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 -} - -local function _new(repo, sha) - local ret = setmetatable({sha=sha}, objectmeta) - repos[ret] = repo - return ret -end - -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, -} diff --git a/lib/gitano/git/repository.lua b/lib/gitano/git/repository.lua deleted file mode 100644 index 258b907..0000000 --- a/lib/gitano/git/repository.lua +++ /dev/null @@ -1,279 +0,0 @@ --- gitano.git --- --- Core 'Repository' functionality for Gitano --- --- Copyright 2012 Daniel Silverstone <dsilvers@digital-scurf.org> --- --- - -local ll = require "gitano.git.ll" -local object = require "gitano.git.object" - -local chomp = ll.chomp - -local repomethod = {} - -local pattern = { - fullsha = string.rep("[0-9a-f]", 40), - shortsha = string.rep("[0-9a-f]", 7), - ref = "refs/.+" -} - -for k, v in pairs(pattern) do - pattern[k] = ("^%s$"):format(v) -end - -local function _repotostring(repo) - return "<GitRepository(" .. repo.path .. ")>" -end - -function repomethod:_run_with_input_and_env(env, input, want_output, ...) - local t = {...} - t.repo = self.path - if want_output then - t.stdout = want_output - end - if input then - t.stdin = input - end - -- We never want to see the stderr dumped to the client, so we eat it. - t.stderr = true - if env then - t.env = env - end - return ll.rungit(t) -end - -function repomethod:_run_with_input(input, want_output, ...) - return self:_run_with_input_and_env(nil, input, want_output, ...) -end - -function repomethod:_run(want_output, ...) - return self:_run_with_input(nil, want_output, ...) -end - -function repomethod:gather(...) - return self:_run(chomp, ...) -end - -function repomethod:rawgather(...) - return self:_run(true, ...) -end - -function repomethod:force_empty_tree() - self:_run(true, "hash-object", "-t", "tree", "-w", "/dev/null") -end - -function repomethod:hash_object(type, content, inject) - local args = { - "hash-object", "-t", type, "--stdin", - } - if inject then - args[#args+1] = "-w" - end - local ok, sha = self:_run_with_input(content, chomp, unpack(args)) - return (ok == 0) and sha or nil -end - -function repomethod:get_ref(ref) - local ok, sha = self:_run(chomp, "show-ref", "--verify", "-s", ref) - return (ok == 0) and sha or nil -end - -function repomethod:update_ref(ref, new_ref, reason, old_ref) - if new_ref and not old_ref then - old_ref = string.rep("0", 40) - end - if not reason then - reason = "Gitano internal operations" - end - - local cmd = { "update-ref", "-m", reason } - - if not new_ref then - cmd[#cmd+1] = "-d" - end - - cmd[#cmd+1] = ref - - if new_ref then - cmd[#cmd+1] = new_ref - end - if old_ref then - cmd[#cmd+1] = old_ref - end - - local why = self:_run(false, unpack(cmd)) - if why ~= 0 then - return nil, "update-ref returned " .. tostring(why) - end - return true -end - -function repomethod:update_server_info() - local why = self:_run(false, "update-server-info") - if why ~= 0 then - return nil, "update-server-info returned " .. tostring(why) - end - return true -end - -function repomethod:all_refs() - local ok, refs = self:_run(chomp, "show-ref") - if ok ~= 0 then return nil, refs end - local reft = {} - for sha, ref in refs:gmatch("([0-9a-f]+) (refs/[^\n]+)") do - reft[ref] = sha - end - return reft -end - -function repomethod:normalise(sha) - -- Purpose is to take a 'shaish' object and normalise it - if sha:match(pattern.fullsha) then - return sha - elseif sha:match(pattern.ref) then - local ref, err = self:get_ref(sha) - return ref, err - else - local ok, out = self:_run_with_input(sha, chomp, "cat-file", "--batch-check") - if not ok then - error(out) - end - sha = out:match("^("..string.rep("[0-9a-f]", 40)..")") - return sha - end - return nil, "Unable to normalise " .. tostring(sha) -end - -function repomethod:get(_sha) - local sha, err = self:normalise(_sha) - if not sha then - return nil, err - end - local ret = self.objmemo[sha] - if not ret then - ret = object.new(self, sha) - self.objmemo[sha] = ret - end - return ret -end - -function repomethod:merge_base(sha_1, sha_2, get_all) - local args = { sha_1, sha_2 } - if get_all then - args = { "-a", sha_1, sha_2 } - end - args.repo = self.path - local ok, out = ll.merge_base(args) - if not ok then - return nil, out - end - local ret = {} - for sha in out:gmatch("([a-f0-9]+)") do - ret[#ret+1] = sha - end - if #ret == 0 then - return true - end - return unpack(ret) -end - -function repomethod:rev_list(oldhead, newhead, firstonly) - local args = { newhead, "^" .. oldhead } - if firstonly then - table.insert(args, 1, "--first-parent") - end - args.repo = self.path - local ok, out = ll.rev_list(args) - if not ok then - return nil, out - end - local ret = {} - for sha in out:gmatch("([a-f0-9]+)") do - ret[#ret+1] = sha - end - if #ret == 0 then - return true - end - return ret -end - -function repomethod:symbolic_ref(name, toref) - if not toref then - return ll.symbolic_ref { "-q", name, - stderr=true, repo=self.path } - else - return ll.symbolic_ref { "-q", name, toref, - stderr=true, repo=self.path } - end - return false, "argh" -end - -function repomethod:config(confname, value) - -- Trivial interface to key/value in config - if not value then - return self:gather("config", confname) - else - self:gather("config", "--replace-all", confname, value) - end -end - -local repomt = { - __index = repomethod, - __tostring = _repotostring -} - -local function _new(path) - -- return a new git repository object - -- with the git_dir set for the provided path - -- and, if we had to add /.git then the GIT_WORK_DIR set - -- appropriately too - - local retrepo = {objmemo=setmetatable({}, {__mode="v"})} - - local repopath = path - local workpath = nil - - local ok, symref = ll.symbolic_ref { "-q", "HEAD", stderr=true, repo=repopath } - if ok ~= 0 then - repopath = path .. "/.git" - workpath = path - ok, symref = ll.symbolic_ref { "-q", "HEAD", stderr=true, repo=repopath } - end - - if ok ~= 0 then - return nil, "Unable to find Git repository at " .. path - end - - retrepo.path = repopath - retrepo.work = workpath - retrepo.HEAD = symref - - return setmetatable(retrepo, repomt) -end - -local function _create(path, full) - -- Cause a bare repository to be created (or a non-bare if full is true) - local args = { - stderr = true, - repo = path, - "-q" - } - if not full then - args[#args+1] = "--bare" - end - ok, msg = ll.init(args) - - if ok ~= 0 then - return nil, "Unable to create Git repository at " .. path - end - - -- Otherwise, return the shiny new repo - return _new(path) -end - -return { - create = _create, - new = _new -} diff --git a/lib/gitano/git/tag.lua b/lib/gitano/git/tag.lua deleted file mode 100644 index 4c07691..0000000 --- a/lib/gitano/git/tag.lua +++ /dev/null @@ -1,97 +0,0 @@ --- gitano.git.tag --- --- Core Git functionality for Gitano --- --- Copyright 2012 Daniel Silverstone <dsilvers@digital-scurf.org> --- --- - -local ll = require "gitano.git.ll" - -local objs = setmetatable({}, {__mode="k"}) -local repos = setmetatable({}, {__mode="k"}) -local parsed = setmetatable({}, {__mode="k"}) - -local _new - -local function parse_person(pers) - local real, email, when, tz = pers:match("^(.-) <([^>]+)> ([0-9]+) ([+-][0-9]+)$") - return { - realname = real, - email = email, - unixtime = when, - timezone = tz - } -end - -local function tagindex(tag, field) - if not parsed[tag] then - local raw = objs[tag].raw - local headers, body, signature = {}, "" - local state = "headers" - - for l in raw:gmatch("([^\n]*)\n") do - if state == "headers" then - local first, second = l:match("^([^ ]+) (.+)$") - if first then - if headers[first] then - headers[first][#headers[first]+1] = second - else - headers[first] = { second } - end - else - state = "message" - end - elseif state == "message" then - if l == PGP_SIG_START then - signature = l .. "\n" - state = "signature" - else - body = body .. l .. "\n" - end - else - signature = signature .. l .. "\n" - end - end - - -- there's always one object - rawset(tag, "object", repos[tag]:get(headers.object[1])) - -- Always one type - rawset(tag, "type", headers.type[1]) - -- Always one tag name - rawset(tag, "tag", headers.tag[1]) - -- Always one tagger - rawset(tag, "tagger", parse_person(headers.tag[1])) - -- A message - rawset(tag, "message", body) - -- And an optional signature - rawset(tag, "signature", signature) - -- Promote the SHA - rawset(tag, "sha", objs[tag].sha) - - -- Signal we are parsed - parsed[tag] = true - end - - return rawget(tag, field) -end - -local function tagtostring(tag) - return "<GitTag(" .. tostring(objs[tag].sha) .. ") in " .. tostring(repos[tag]) .. ">" -end - -local tagmeta = { - __index = tagindex, - __tostring = tagtostring -} - -function _new(repo, obj) - local ret = setmetatable({}, tagmeta) - objs[ret] = obj - repos[ret] = repo - return ret -end - -return { - new = _new -} diff --git a/lib/gitano/git/tree.lua b/lib/gitano/git/tree.lua deleted file mode 100644 index 99b0237..0000000 --- a/lib/gitano/git/tree.lua +++ /dev/null @@ -1,209 +0,0 @@ --- gitano.git.tree --- --- Core Git functionality for Gitano --- --- Copyright 2012 Daniel Silverstone <dsilvers@digital-scurf.org> --- --- - -local ll = require "gitano.git.ll" - -local PARSED = {} - -local objs = setmetatable({}, {__mode="k"}) -local repos = setmetatable({}, {__mode="k"}) -local parsed = setmetatable({}, {__mode="k"}) - -local tree_method = {} - -local shapattern = ("[a-f0-9]"):rep(40) -local shacapture = "(" .. shapattern .. ")" -local modepattern = ("[0-7]"):rep(6) -local modecapture = "(" .. modepattern .. ")" --- startmode, endmode, startsha, endsha, action, optional score, filename(s) -local treediffline = table.concat { - ":", modecapture, " ", modecapture, " ", shacapture, " ", shacapture, " ", - "(.)", "([0-9]*)", "\t", "([^\n]+)", "\n" -} - -local mode_to_kind_map = { - ["000000"] = "missing", - ["160000"] = "submodule", - ["100644"] = "blob", - ["100755"] = "xblob", - ["120000"] = "symlink", -} - -local function unescape_filename(fn) - local zfn = fn:gsub("\\\\", "\0") - zfn = zfn:gsub("\\n", "\n") - zfn = zfn:gsub("\\t", "\t") - return (zfn:gsub("%z", "\\")) -end - -function tree_method:diff_to(other) - -- Generate a diff from self to other - local repo = repos[self] - local ok, streediff = repo:rawgather("diff-tree", "-r", "-M", "-C", - objs[self].sha, objs[other].sha) - if ok ~= 0 then - return nil, streediff - end - local treediff = {} - for startmode, endmode, startsha, endsha, action, score, filenames in - streediff:gmatch(treediffline) do - local diffentry = { - startmode = startmode, - endmode = endmode, - startkind = mode_to_kind_map[startmode] or "UNKNOWN", - endkind = mode_to_kind_map[endmode] or "UNKNOWN", - startsha = startsha, - endsha = endsha, - action = action, - score = (score ~= "") and score or nil, - } - if action == "C" or action == "R" then - local src, dst = filenames:match("([^\t]+)\t(.+)") - diffentry.src_name = unescape_filename(src) - diffentry.filename = unescape_filename(dst) - diffentry.dst_name = diffentry.filename - else - diffentry.filename = unescape_filename(filenames) - end - treediff[#treediff+1] = diffentry - treediff[diffentry.filename] = diffentry - end - return treediff -end - -local function treeindex(tree, field) - if tree_method[field] then - return tree_method[field] - end - - if not parsed[tree] then - local raw = objs[tree].raw - for l in raw:gmatch("([^\n]+)\n") do - local perm, type, sha, name = l:match("^([0-9]+) ([^ ]+) ([0-9a-f]+)\t(.+)$") - local t = { - permissions = perm, - name = name, - type = type, - obj = repos[tree]:get(sha) - } - rawset(tree, name, t) - end - parsed[tree] = true - end - - return rawget(tree, field) -end - -local function treetostring(tree) - return "<GitTree(" .. tostring(objs[tree].sha) .. ") in " .. tostring(repos[tree]) .. ">" -end - -local treemeta = { - __index = treeindex, - __tostring = treetostring, -} - -local function _new(repo, obj) - local ret = setmetatable({}, treemeta) - objs[ret] = obj - repos[ret] = repo - return ret -end - -local function _realise(t) - if not parsed[t] then - local ignored = t[parsed] - end - return t -end - -local function _flatten(t) - local ret = {} - local function _inner_flatten(pfx, tt) - _realise(tt) - for k, v in pairs(tt) do - local leaf = pfx .. k - if v.type == "tree" then - _inner_flatten(leaf .. "/", v.obj.content) - else - ret[leaf] = v - end - end - end - _inner_flatten("", t) - return ret -end - -local function _create(repo, flat_tree) - local function __store(tree, element, content) - local prefix, suffix = element:match("^([^/]+)/(.+)$") - if not prefix then - tree[element] = content - else - tree[prefix] = tree[prefix] or { [""] = true } - __store(tree[prefix], suffix, content) - end - end - local t = {[""] = true} - for k, v in pairs(flat_tree) do - __store(t, k, v) - end - - -- t is now a 'tree' so we need to turn any tables into trees recursively - - local function __treeify(t) - -- Step one, ensure any trees inside t are treeified - for k, v in pairs(t) do - if k ~= "" and rawget(v, "") then - local _v, reason = __treeify(v) - if not _v then - return nil, reason - end - t[k] = _v - end - end - -- Next, construct a mktree input - local tree_ent = "" - local mode = { - tree = "040000", - blob = "100644", - } - for k, v in pairs(t) do - if k ~= "" then - local ok, obj = pcall(function() return v.obj end) - if ok then - v = obj - end - if not mode[v.type] then - return nil, "Unknown type " .. v.type - end - tree_ent = tree_ent .. - ("%s %s %s\t%s\0"):format(mode[v.type], v.type, v.sha, k) - end - end - - local why, sha = repo:_run_with_input(tree_ent, ll.chomp, - "mktree", "-z") - if why ~= 0 then - return nil, "mktree returned " .. tostring(why) - end - return repo:get(sha) - end - - return __treeify(t) -end - -return { - realise = _realise, - flatten = _flatten, - new = _new, - create = _create, - - -- Magic SHA1 for empty tree - empty_sha = "4b825dc642cb6eb9a060e54bf8d69288fbee4904" -} diff --git a/lib/gitano/lace.lua b/lib/gitano/lace.lua index c98e42b..517c476 100644 --- a/lib/gitano/lace.lua +++ b/lib/gitano/lace.lua @@ -6,7 +6,7 @@ local lace = require 'lace' local util = require 'gitano.util' -local git = require 'gitano.git' +local gall = require 'gall' local log = require 'gitano.log' local function _loader(ctx, _name) @@ -15,7 +15,7 @@ local function _loader(ctx, _name) if not global_name then -- Project load if ctx.project and not ctx.project_tree then - ctx.project_tree = git.tree.flatten(ctx.project.content.tree.content) + ctx.project_tree = gall.tree.flatten(ctx.project.content.tree.content) end if ctx.project_tree then tree = ctx.project_tree @@ -24,7 +24,7 @@ local function _loader(ctx, _name) else -- Global load if not ctx.global_tree then - ctx.global_tree = git.tree.flatten(ctx.global.content.tree.content) + ctx.global_tree = gall.tree.flatten(ctx.global.content.tree.content) end tree = ctx.global_tree sha = ctx.global.sha diff --git a/lib/gitano/repository.lua b/lib/gitano/repository.lua index cf4fd09..9e6460c 100644 --- a/lib/gitano/repository.lua +++ b/lib/gitano/repository.lua @@ -5,7 +5,7 @@ -- Copyright 2012 Daniel Silverstone <dsilvers@digital-scurf.org> -- -local git = require 'gitano.git' +local gall = require 'gall' local luxio = require 'luxio' local sio = require 'luxio.simple' local sp = require 'luxio.subprocess' @@ -38,7 +38,7 @@ local repo_method = {} function repo_method:load_from_admin_ref(filename) local admincommit = self.git:get(adminrefname) local admintree = admincommit.content.tree.content - local flat_tree = git.tree.flatten(admintree) + local flat_tree = gall.tree.flatten(admintree) local entry = flat_tree[filename] if not entry then return nil, "Not found: " .. admincommit.sha .. "::" .. filename @@ -56,7 +56,7 @@ function repo_method:uses_hook(hookname) end local admincommit = self.git:get(adminrefname) local admintree = admincommit.content.tree.content - local flat_tree = git.tree.flatten(admintree) + local flat_tree = gall.tree.flatten(admintree) local entry = flat_tree["hooks/" .. hookname .. ".lua"] if not entry then return false @@ -81,11 +81,11 @@ function repo_method:run_checks() if not self.git:get_ref(adminrefname) then -- Admin branch is missing, create one. -- First, the blob for the rules - local rules, msg = git.object.create(self.git, "blob", base_rules) + local rules, msg = gall.object.create(self.git, "blob", base_rules) if not rules then return nil, msg end - local conf, msg = git.object.create(self.git, "blob", base_config) + local conf, msg = gall.object.create(self.git, "blob", base_config) if not conf then return nil, msg end @@ -94,13 +94,13 @@ function repo_method:run_checks() ["rules/main.lace"] = rules, ["project.conf"] = conf, } - local tree, msg = git.tree.create(self.git, flat_tree) + local tree, msg = gall.tree.create(self.git, flat_tree) if not tree then return nil, msg end -- Now a commit of the blob, using the gitano admin identity local commit, msg = - git.commit.create(self.git, { + gall.commit.create(self.git, { author = admin_name, committer = admin_name, message = "Initial admin tree", @@ -304,7 +304,7 @@ end function repo_method:validate_admin_sha(sha) local commit = self.git:get(sha) - local tree = git.tree.flatten(commit.content.tree.content) + local tree = gall.tree.flatten(commit.content.tree.content) local function is_blob(thingy) return thingy and thingy.type and thingy.type == "blob" @@ -393,7 +393,7 @@ function repo_method:realise() return false, "Cannot prepare path leading to repository." end - local r, msg = git.repository.create(self:fs_path()) + local r, msg = gall.repository.create(self:fs_path()) if not r then return false, msg end @@ -511,17 +511,17 @@ end function repo_method:save_admin(reason, username) local cursha = self.git:get_ref(adminrefname) local curcommit = self.git:get(cursha) - local flat_tree = git.tree.flatten(curcommit.content.tree.content) + local flat_tree = gall.tree.flatten(curcommit.content.tree.content) local new_conf_content = self.project_config:serialise() - local conf_blob, msg = git.object.create(self.git, "blob", new_conf_content) + local conf_blob, msg = gall.object.create(self.git, "blob", new_conf_content) if not conf_blob then return nil, msg end flat_tree["project.conf"] = conf_blob - local tree, msg = git.tree.create(self.git, flat_tree) + local tree, msg = gall.tree.create(self.git, flat_tree) if not tree then return nil, msg end @@ -531,7 +531,7 @@ function repo_method:save_admin(reason, username) }) or admin_name -- Now a commit of the blob, using the gitano admin identity local commit, msg = - git.commit.create(self.git, { + gall.commit.create(self.git, { author = person, committer = person, message = reason or "Updated admin tree", @@ -640,7 +640,7 @@ local function find_repository(config, reponame) -- Let's get hold of a git repo for this - local r, msg = git.repository.new(repo:fs_path()) + local r, msg = gall.repository.new(repo:fs_path()) if not r then return nil, msg end |