git3html

git clone https://orangeshoelaces.net/git/git3html.git

1d4967e82cc844544a831519fd63eb31b576fabd

Author: Vasilii Kolobkov on 01/14/2019

Committer: Vasilii Kolobkov on 01/14/2019

Show commit log

Stats

git3html | 113 +++++++-
1 file changed, 106 insertions(+), 7 deletions(-)

Patch

diff --git a/git3html b/git3html
index 95451ba..38cb341 100755
--- a/git3html
+++ b/git3html
@@ -69,6 +69,18 @@ tmrc() {
 	g rev-list -n 1 --all --format=tformat:%T | tail -n +2
 }
 
+# this and morecommits should use same filter options to maintain the
+# invariant: morecommits exits with positive status if pickcommits selects
+# proper subset of all commits
+pickcommits() {
+	g rev-list ${clim+-n $clim} --all --date-order "$@"
+}
+
+morecommits() {
+	[ -n "${clim:-}" ] &&
+	[ "$(g rev-list --skip="$clim" -n 1 --all | wc -l | cut -d ' ' -f1)" -gt 0 ]
+}
+
 defaultname() {
 	if [ "$(basename "$repodir")" = '.' ]; then
 		basename $(pwd)
@@ -115,7 +127,7 @@ footer() {
 }
 
 readme() (
-	header "${projname} readme" '.'
+	header "${projname} readme" .
 	root=$(tmrc)
 	echo '<pre>'
 	g ls-tree --name-only "$root" | grep '^README*' | while read -r readme; do
@@ -125,6 +137,94 @@ readme() (
 	footer
 )
 
+commit() (
+	id="$1"
+	g rev-list -n 1 --date=format:%x --format='%h%n%an%n%ae%n%ad%n%cn%n%ce%n%cd' "$id" | \
+	tail -n +2 | escape | {
+		IFS= read -r shortid
+		header "${projname} commit ${shortid}" ..
+		printf '<h2>%s<span class="id-suffix">%s</h2>\n' "$shortid" \
+			"$(echo "$id" | cut -c "$(expr ${#shortid} + 1)-")"
+		cat <<-END
+		<pre>
+		<code>
+		END
+		for v in an ae ad cn ce cd; do
+			IFS= read -r "$v"
+		done
+		printf 'Author:    <a href="mailto:%s">%s</a> on %s\n' "$ae" "$an" "$ad"
+		printf 'Committer: <a href="mailto:%s">%s</a> on %s\n' "$ce" "$cn" "$cd"
+		cat <<-END
+		</code>
+		</pre>
+		END
+	}
+	cat <<-END
+	<h3>Stats</h3>
+	<pre>
+	<code>
+	END
+	g diff-tree --stat --stat-graph-width=8 "$id" | tail -n +2 | escape | sed \
+		's/^[[:space:]]*//;
+		s#\(+*\)\(-*\)$#<span class="add">\1</span><span class="delete">\2</span>#'
+	cat <<-END
+	</code>
+	</pre>
+	<h3>Patch</h3>
+	<pre>
+	<code>
+	END
+	g diff-tree -p "$id" | escape | sed "\
+		$(for p in diff old new deleted copy rename similarity dissimilarity index; do
+			echo "/^$p/ { s,^,<span class=\"hunk-header\">,; s,$,</span>,; }"
+		done;)"
+	cat <<-END
+	</code>
+	</pre>
+	END
+	footer
+)
+
+log() (
+	outdir="$1"
+	cdir="${outdir%/}/commits"
+	if [ ! -d "$cdir" ]; then
+		mkdir "$cdir"
+	fi
+	exec >"${outdir%/}/log.html"
+
+	header "${projname} log" .
+	cat <<-END
+	<table>
+	<thead>
+	<tr>
+	<th>Subject</th>
+	<th>Date</th>
+	</tr>
+	</thead>
+	<tbody>
+	END
+	pickcommits --date=format:%x --format=tformat:%s%n%cd | while read prefix id; do
+		commit "$id" >"${cdir%/}/${id}.html"
+		IFS= read -r subj
+		IFS= read -r date
+		printf '<tr>\n<td><a href="commits/%s.html">%s</a></td>\n<td>%s</td>\n</tr>\n' \
+			"$id" "$(echo "$subj" | escape)" "$(echo "$date" | escape)"
+	done
+	if morecommits; then
+		cat <<-END
+		<tr>
+		<td>...</td>
+		</tr>
+		END
+	fi
+	cat <<-END
+	</tbody>
+	</table>
+	END
+	footer
+)
+
 dirent() {
 	printf "<li><pre><code>d <a href=\"%s\">%s</a></code></pre></li>\n" \
 		"$(echo "$2" | escape)" "$(echo "$1" | escape)"
@@ -220,11 +320,11 @@ files() (
 # ........ driver ........
 
 usage() {
-	echo "Usage: $0 [-p name] [-u url] [-d depth] repodir htmldir" >&2
+	echo "Usage: $0 [-p name] [-u url] [-c lim] repodir htmldir" >&2
 	exit 1
 }
 
-while getopts 'p:u:d:h' opt; do
+while getopts 'p:u:c:h' opt; do
 	case "$opt" in
 	p)
 		projname="$OPTARG"
@@ -232,8 +332,8 @@ while getopts 'p:u:d:h' opt; do
 	u)
 		cloneurl="$OPTARG"
 		;;
-	d)
-		depth="$OPTARG"
+	c)
+		clim="$OPTARG"
 		;;
 	*)
 		usage
@@ -249,12 +349,11 @@ fi
 repodir="$1"
 htmldir="$2"
 projname="${projname:-$(defaultname)}"
-depth="${depth:-0}"
 
 if [ ! -d "$htmldir" ]; then
 	mkdir -p "$htmldir"
 fi
 
 readme > "${htmldir%/}/readme.html"
-#log
+log "$htmldir"
 files "$(tmrc)" 'files' "$htmldir" '.' '' '/'