1 | -- git_commands.lua |
2 | -- Index of git commands used for the git status site |
3 |
|
4 | -- Copyright (c) 2020 Joshua 'joshuas3' Stockin |
5 | -- <https://github.com/JoshuaS3/joshstock.in> |
6 | -- <https://joshstock.in> |
7 |
|
8 |
|
9 | local utils = require("utils") |
10 |
|
11 |
|
12 | _M = {} |
13 |
|
14 |
|
15 | local COMMANDS = { |
16 | get_number = "rev-list --count %s --", |
17 | get_commit = "log %s --pretty=format:'%%aI ## %%H ## %%an ## %%ae ## %%s ## %%b' -n 1 --", |
18 | get_branches = "branch --list --format='%(refname:lstrip=2)'", |
19 | list_commits = "log %s --pretty=format:'%%aI ## %%H ## %%an ## %%ae ## %%s' -n %d --skip=%d --", |
20 | get_diff = "show --pretty='' --numstat %s" |
21 | } |
22 |
|
23 |
|
24 | local execute = function(repo_dir, command) |
25 | local formatted_command = string.format( |
26 | "git --git-dir=%s/.git --work-tree=%s %s", |
27 | repo_dir, repo_dir, command |
28 | ) |
29 | local output |
30 | local status, err = pcall(function() |
31 | local process = io.popen(formatted_command, "r") |
32 | assert(process, "Error opening git process") |
33 | output = process:read("*all") |
34 | process:close() |
35 | end) |
36 | if status then |
37 | return output |
38 | else |
39 | return string.format("Error in git call: %s", err or "") |
40 | end |
41 | end |
42 |
|
43 |
|
44 | local format_commit = function(commit_string, repo_dir, branch) |
45 | local raw_out = string.split(commit_string, " ## ") |
46 | local commit = {} |
47 | commit.date = raw_out[1] |
48 | commit.hash = raw_out[2] |
49 | commit.author = raw_out[3] |
50 | commit.email = raw_out[4] |
51 | commit.subject = raw_out[5] |
52 | commit.body = raw_out[6] |
53 | return commit |
54 | end |
55 |
|
56 |
|
57 | _M.get_number = function(repo_dir, commit_hash) |
58 | commit_hash = commit_hash or "HEAD" |
59 | local command = string.format(COMMANDS.get_number, commit_hash) |
60 | local raw_out = execute(repo_dir, command) |
61 | return tonumber(raw_out) |
62 | end |
63 |
|
64 |
|
65 | _M.get_commit = function(repo_dir, branch) |
66 | branch = branch or "HEAD" |
67 | local command = string.format(COMMANDS.get_commit, branch) |
68 | local raw_out = execute(repo_dir, command) |
69 | local commit = format_commit(raw_out) |
70 | commit.branch = branch |
71 | commit.number = _M.get_number(repo_dir, branch) |
72 | return commit |
73 | end |
74 |
|
75 |
|
76 | _M.get_diff = function(repo_dir, branch) |
77 | branch = branch or "HEAD" |
78 | local command = string.format(COMMANDS.get_diff, branch) |
79 | local raw_out = string.trim(execute(repo_dir, command)) |
80 | local diffs = {} |
81 | diffs.delta = 0 |
82 | diffs.max = 0 |
83 | diffs.files = {} |
84 | local files = string.split(raw_out, "\n") |
85 | for _, file in pairs(files) do |
86 | local diff = {} |
87 | local stats = string.split(file, "\t") |
88 | diff.plus = stats[1] |
89 | diff.minus = stats[2] |
90 | diff.file = stats[3] |
91 | table.insert(diffs.files, diff) |
92 | local total = diff.plus + diff.minus |
93 | local delta = diff.plus - diff.minus |
94 | if diffs.max < total then |
95 | diffs.max = total |
96 | end |
97 | diffs.delta = diffs.delta + delta |
98 | end |
99 | return diffs |
100 | end |
101 |
|
102 |
|
103 | _M.get_branches = function(repo_dir) |
104 | local raw_out = execute(repo_dir, COMMANDS.get_branches) |
105 | local trimmed = string.trim(raw_out) |
106 | return string.split(trimmed, "\n") |
107 | end |
108 |
|
109 |
|
110 | _M.list_commits_by_page = function(repo_dir, branch, page_num, commits_per_page) |
111 | branch = branch or "HEAD" |
112 | page_num = page_num or 1 |
113 | commits_per_page = commits_per_page or 32 |
114 | local skip = commits_per_page * (page_num - 1) |
115 | local command = string.format(COMMANDS.list_commits, branch, commits_per_page, skip) |
116 | local raw_out = string.trim(execute(repo_dir, command)) |
117 | local commits = {} |
118 | for _, line in pairs(string.split(raw_out, "\n")) do |
119 | local commit = format_commit(line) |
120 | commit.branch = branch |
121 | commit.number = _M.get_number(repo_dir, commit.hash) |
122 | table.insert(commits, commit) |
123 | end |
124 | return commits |
125 | end |
126 |
|
127 |
|
128 | return _M |
129 |
|