Index

resty-gitweb / 1f62b32

A git web interface for Lua/OpenResty (you're on it right now!)

Latest Commit

{#}TimeHashSubjectAuthor#(+)(-)GPG?
315 Dec 2020 18:527890389Update copyright noticesJosh Stockin132G

Blob @ resty-gitweb / git / git_commands.lua

text/plain6150 bytesdownload raw
1-- resty-gitweb@git/git_commands.lua
2-- git commands and parser functions
3
4-- Copyright (c) 2020 Joshua 'joshuas3' Stockin
5-- <https://git.joshstock.in/resty-gitweb>
6-- This software is licensed under the MIT License.
7
8local utils = require("utils/utils")
9
10local _M = {}
11
12local git = function(repo_dir, command)
13 local formatted_command = string.format(
14 "git --git-dir=%s %s",
15 repo_dir, command
16 )
17 return utils.process(formatted_command)
18end
19
20_M.show_file = function(repo_dir, hash, filename)
21 hash = hash or "@"
22 filename = filename or ""
23 local output = git(repo_dir, "show "..hash..":"..filename)
24 return output
25end
26
27_M.get_head = function(repo_dir, head_name)
28 head_name = head_name or "HEAD"
29 local head = {}
30 local name = string.trim(git(repo_dir, "rev-parse --abbrev-ref "..head_name))
31 if name ~= "" then
32 local output = git(repo_dir, "show-ref --heads --tags "..name)
33 local a = string.split(string.trim(output), " ")
34 head.hash = a[1]
35 head.shorthash = string.sub(a[1], 1, 7)
36 head.full = a[2]
37 head.name = name
38 else -- no ref, default to hash
39 head.hash = head_name
40 head.shorthash = string.sub(head_name, 1, 7)
41 head.full = head_name
42 head.name = head_name
43 end
44 return head
45end
46
47_M.count = function(repo_dir, hash)
48 hash = hash or "@"
49 local output = git(repo_dir, "rev-list --count "..hash.." --")
50 return tonumber(string.trim(output))
51end
52
53_M.log = function(repo_dir, hash, file, number, skip, gpg)
54 hash = hash or "@"
55 file = file or ""
56 number = tostring(number or 25)
57 skip = tostring(skip or 0)
58 gpg = gpg or false
59 local output
60 if gpg then
61 output = git(repo_dir, "log --pretty=tformat:'%x00%x01%H%x00%cI%x00%cn%x00%ce%x00%s%x00%b%x00%G?%x00%GK%x00%GG%x00' --numstat -n "..number.." --skip "..skip.." "..hash.." -- "..file)
62 else
63 output = git(repo_dir, "log --pretty=tformat:'%x00%x01%H%x00%cI%x00%cn%x00%ce%x00%s%x00%b%x00' --numstat -n "..number.." --skip "..skip.." "..hash.." -- "..file)
64 end
65 local commits = {}
66 local a = string.split(output,"\0\1")
67 local f = false
68 for i,v in pairs(a) do
69 if f == true then
70 local commit = {}
71 local c = string.split(v, "\0")
72 commit.hash = c[1]
73 commit.shorthash = string.sub(c[1], 1,7)
74 commit.timestamp = c[2]
75 commit.author = c[3]
76 commit.email = c[4]
77 commit.subject = c[5]
78 commit.body = string.trim(c[6])
79 local diffs
80 if gpg then
81 commit.gpggood = c[7]
82 commit.gpgkey = c[8]
83 commit.gpgfull = string.trim(c[9])
84 diffs = string.trim(c[10])
85 else
86 diffs = string.trim(c[7])
87 end
88 commit.diff = {}
89 local b = string.split(diffs, "\n")
90 commit.diff.plus = 0
91 commit.diff.minus = 0
92 commit.diff.num = 0
93 commit.diff.files = {}
94 for i,v in pairs(b) do
95 local d = string.split(v,"\t")
96 local x = {}
97 x.plus = tonumber(d[1]) or 0
98 commit.diff.plus = commit.diff.plus + x.plus
99 x.minus = tonumber(d[2]) or 0
100 commit.diff.minus = commit.diff.minus + x.minus
101 commit.diff.files[d[3]] = x
102 commit.diff.num = commit.diff.num + 1
103 end
104 table.insert(commits, commit)
105 else
106 f = true
107 end
108 end
109 return commits
110end
111
112_M.commit = function(repo_dir, hash)
113 local commit = _M.log(repo_dir, hash, "", 1, 0, true)[1]
114 commit.count = _M.count(repo_dir, hash)
115 return commit
116end
117
118local heads = function(repo_dir)
119 local output = git(repo_dir, "show-ref --heads")
120 local a = string.split(output, "\n")
121 table.remove(a,#a)
122 local heads = {}
123 for i,v in pairs(a) do
124 local b = string.split(v, " ")
125 local head = {}
126 head.hash = b[1]
127 head.shorthash = string.sub(b[1], 1, 7)
128 head.full = b[2]
129 head.name = string.split(b[2], "/")[3]
130 table.insert(heads, head)
131 end
132 return heads
133end
134
135local tags = function(repo_dir)
136 local output = git(repo_dir, "show-ref --tags")
137 local a = string.split(output, "\n")
138 table.remove(a,#a)
139 local tags = {}
140 for i,v in pairs(a) do
141 local b = string.split(v, " ")
142 local tag = {}
143 tag.hash = b[1]
144 tag.shorthash = string.sub(b[1], 1, 7)
145 tag.full = b[2]
146 tag.name = string.split(b[2], "/")[3]
147 table.insert(tags, tag)
148 end
149 return tags
150end
151
152_M.list_refs = function(repo_dir)
153 local refs = {}
154 refs.heads = heads(repo_dir)
155 refs.tags = tags(repo_dir)
156 return refs
157end
158
159local list_dirs = function(repo_dir, hash, path)
160 hash = hash or "@"
161 path = path or ""
162 local output = git(repo_dir, "ls-tree -d --name-only "..hash.." -- "..path)
163 local dirs = string.split(output, "\n")
164 table.remove(dirs, #dirs) -- remove trailing \n
165 return dirs
166end
167
168local list_all = function(repo_dir, hash, path)
169 hash = hash or "@"
170 path = path or ""
171 local output = git(repo_dir, "ls-tree --name-only "..hash.." -- "..path)
172 local all = string.split(output, "\n")
173 table.remove(all, #all) -- remove trailing \n
174 return all
175end
176
177_M.list_tree = function(repo_dir, hash, path)
178 hash = hash or "@"
179 path = path or ""
180 local files = list_all(repo_dir, hash, path)
181 local dirs = list_dirs(repo_dir, hash, path)
182 local ret = {}
183 ret.dirs = {}
184 ret.files = {}
185 for i,v in pairs(files) do -- iterate over all objects, separate directories from files
186 local not_dir = true
187 for _,d in pairs(dirs) do -- check if object is directory
188 if v == d then
189 not_dir = false
190 break
191 end
192 end
193 if not_dir then
194 table.insert(ret.files, v)
195 else
196 table.insert(ret.dirs, v)
197 end
198 end
199 return ret
200end
201
202return _M
203