login

<     >

2022-02-26 21:24:26 (UTC-03:00)

Marcel Rodrigues <marcelgmr@gmail.com>

add history browsing

diff --git a/app.lua b/app.lua
index a349fce..a000ed4 100644
--- a/app.lua
+++ b/app.lua
@@ -27,7 +27,15 @@ local routes = {
         local repo = groups[gname][rname]
         local bnames = repo:branches()
         local tnames = repo:tags()
-        return lud.template.render_file("view/repo.html", {gname=gname, rname=rname, bnames=bnames, tnames=tnames})
+        local env = {gname=gname, rname=rname, bnames=bnames, tnames=tnames}
+        return lud.template.render_file("view/repo.html", env)
+    end},
+    {"GET", "/group/([%w_-]+)/repo/([%w_-]+)/history/([%w_-]+)", function (req, gname, rname, first)
+        local repo = groups[gname][rname]
+        local commit = repo:commit(first)
+        local prev = repo:find_prev(commit:id(), 20)
+        local env = {gname=gname, rname=rname, bname=bname, commit=commit, prev=prev, first=first}
+        return lud.template.render_file("view/history.html", env)
     end},
 }
 

diff --git a/git.lua b/git.lua
index be31587..f22edb1 100644
--- a/git.lua
+++ b/git.lua
@@ -63,6 +63,7 @@ int git_revparse_single(git_object **out, git_repository *repo, const char *spec
 
 int git_commit_lookup(git_commit **commit, git_repository *repo, const git_oid *id);
 int git_commit_parent(git_commit **out, const git_commit *commit, unsigned int n);
+const git_oid * git_commit_id(const git_commit *commit);
 const char * git_commit_message(const git_commit *commit);
 const char * git_commit_summary(git_commit *commit);
 git_time_t git_commit_time(const git_commit *commit);
@@ -97,6 +98,13 @@ local function get_commit(commit)
     return setmetatable({commit=commit}, Commit)
 end
 
+function Commit:id(len)
+    len = len or 16
+    local oid = ffi.new("char ["..(len+1).."]")
+    C.git_oid_tostr(oid, len, C.git_commit_id(self.commit))
+    return ffi.string(oid)
+end
+
 function Commit:message()
     return ffi.string(C.git_commit_message(self.commit))
 end
@@ -158,6 +166,29 @@ function Repo:commit(rev)
     return get_commit(commit)
 end
 
+function Repo:find_prev(cid, dist)
+    for i, bname in ipairs(self:branches()) do
+        local cids = {}
+        local commit = self:commit(bname)
+        while commit do
+            local cur_cid = commit:id()
+            table.insert(cids, cur_cid)
+            if cur_cid == cid then
+                break
+            end
+            commit = commit:parent()
+        end
+        if cids[#cids] == cid then
+            if #cids > dist then
+                return self:commit(cids[#cids - dist - 1])
+            else
+                return nil
+            end
+        end
+    end
+    return nil
+end
+
 local function open(path)
     local self = setmetatable({}, Repo)
     local prepo = ffi.new("git_repository *[1]")

diff --git a/view/history.html b/view/history.html
new file mode 100644
index 0000000..911a798
--- /dev/null
+++ b/view/history.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>cogit - {{$gname}} - {{$rname}} - history</title>
+</head>
+<body>
+  <p>Commits:</p>
+  <ul>
+    % set i = 0
+    % while $commit and $i < 20 do
+    <li><a href="/group/{{$gname}}/repo/{{$rname}}/commit/{{$commit:id()}}">{{$commit:summary()}}</a></li>
+      % set commit = $commit:parent()
+      % set i = $i + 1
+    % end
+  </ul>
+  <br/>
+  % if $prev then
+  <a href="/group/{{$gname}}/repo/{{$rname}}/history/{{$prev:id()}}">&lt</a>
+  % else
+  &lt
+  % end
+  &nbsp;&nbsp;&nbsp;
+  % if $commit and $commit:parent() then
+  <a href="/group/{{$gname}}/repo/{{$rname}}/history/{{$commit:parent():id()}}">&gt</a>
+  % else
+  &gt
+  % end
+</body>
+</html>

diff --git a/view/repo.html b/view/repo.html
index d79355d..79726a2 100644
--- a/view/repo.html
+++ b/view/repo.html
@@ -8,7 +8,7 @@
   <p>Branches:</p>
   <ul>
     % for bname in $bnames do
-    <li><a href="/group/{{$gname}}/repo/{{$rname}}/branch/{{$bname}}">{{$bname}}</a></li>
+    <li><a href="/group/{{$gname}}/repo/{{$rname}}/history/{{$bname}}">{{$bname}}</a></li>
     % end
   </ul>
   % if #$tnames > 0 then