Index

joshstock.in / 009440a

Source for serving and static templating/compiling of https://joshstock.in.

Latest Commit

{#}TimeHashSubjectAuthor#(+)(-)GPG?
9612 Dec 2020 20:23009440aUpdate lua-gitwebJosh Stockin12010G

Blob @ joshstock.in / lua-gitweb / git / git_commands.lua

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