ref: f8a5ea28c2a510823598940a1e375e2337c8c6e2
author: glenda <glenda@9front.local>
date: Sun Nov 29 07:35:57 EST 2020
Initial import
--- /dev/null
+++ b/gitonline.rc
@@ -1,0 +1,288 @@
+#!/bin/rc
+
+nl='
+'
+
+rfork ne
+ramfs -m /tmp
+
+cd $REPO_DIR
+
+fn resolveref {
+ if(~ $gitref HEAD)
+ echo $gitref
+ if not if(test -d /mnt/git/branch/$gitref/tree)
+ echo branch/$gitref
+ if not if(test -d /mnt/git/object/$gitref/tree)
+ echo object/$gitref
+ if not {
+ status='bad ref'
+ }
+}
+
+fn htcat {
+ sed '
+ s/&/\&/g;
+ s/</\</g;
+ s/>/\>/g;
+ s/"/\"/g;
+ s/''/\'/g
+ ' $*
+}
+
+fn redirect {
+ echo 'Status: 301 Moved Permanently'
+ echo 'Location: '$1
+}
+
+fn html_emit_start {
+ echo 'Content-type: text/html'
+ echo
+
+ echo '
+ <!DOCTYPE html>
+ <html>
+ <head>
+ <title>Git repo browser</title>
+ <meta charset="UTF-8">
+ <style>
+ body {
+ background-color: #ffffea;
+ }
+ th {
+ text-align: left;
+ }
+ code > pre.code {
+ border: 1px solid black;
+ background-color: #eaffff;
+ }
+ </style>
+ </head>'
+}
+
+fn html_emit_end {
+ echo '
+ </body>
+ </html>'
+}
+
+fn repo_index {
+ html_emit_start
+ echo '<h1> Git repo browser </h1>'
+ dirs=`{walk -d -n1}
+ echo '
+ <table style="width: 100%">
+ <tr>
+ <th>Name</th>
+ <th>Description</th>
+ <th>Last change</th>
+ </tr>'
+ for (d in $dirs) {
+ cd $REPO_DIR
+ if (test -d $d/.git) {
+ cd $d
+ git/fs
+ echo '
+ <tr>
+ <td><a href="/'$d'">'$d'</a></td>
+ <td>'
+ htcat .git/description
+ echo '
+ </td>
+ <td>'
+ htcat /mnt/git/HEAD/msg | sed 1q
+ echo '
+ </td>
+ </tr>'
+ }
+ }
+ echo '</table>'
+ html_emit_end
+}
+
+fn repo_view {
+ html_emit_start
+ reponame=`{basename $1}
+ echo '
+ <h1>'$reponame'</h1>
+ <a href="'$reponame'/shortlog">'Shortlog'</a>
+ <a href="'$reponame'/browse">'browse'</a>'
+ html_emit_end
+
+}
+
+fn repo_browse {
+ html_emit_start
+ cd $repo
+ git/fs
+
+ ref=`{resolveref $gitref}
+ if (! ref=`{resolveref $gitref}) {
+ `{resolveref $gitref}
+ echo '<b>'$status'</b>'
+ html_emit_end
+ exit
+ }
+
+ echo '<h2> Browsing '$repo' at commit '$gitref': '$filepath'</h2>'
+ gitpath=/mnt/git/$ref/tree$filepath
+ if (test -d $gitpath) {
+ cd $gitpath
+ files=`$nl{ls -F | sed 's/\*//g'}
+ echo '<pre>'
+ for (f in $files) {
+ echo '<a href="'$f'">'$f'</a>'
+ }
+ echo '</pre>'
+ }
+ if not if (test -f $gitpath) {
+ echo '<code><pre class="code">'
+ htcat $gitpath
+ echo '</pre></code>'
+ }
+ if not {
+ echo 'Sorry, could not find '$gitpath
+ }
+ html_emit_end
+}
+
+fn repo_shortlog {
+ html_emit_start
+ cd $repo
+ git/fs
+ if (! ref=`{resolveref $gitref}) {
+ `{resolveref $gitref}
+ echo '<b>'$status'</b>'
+ html_emit_end
+ exit
+ }
+
+ echo '
+ <b>Showing the last 100 commits</b>
+ <table>
+ <tr>
+ <th>Date</th>
+ <th>Author</th>
+ <th>Short message</th>
+ <th>Commit hash</th>
+ </tr>'
+ commithash=`{cat /mnt/git/$ref/hash | sed 1q}
+ count=()
+ while (! ~ $#commithash 0 && ! ~ $#count 100) {
+ count=($count 1)
+ message=`{htcat /mnt/git/object/$commithash/msg | sed 1q}
+ date=`{date -i `{mtime /mnt/git/object/$commithash/msg | awk '{print $1}'}}
+ author=`"{htcat /mnt/git/object/$commithash/author | awk '{print $1}'}
+ echo '
+ <tr>
+ <td>'$date'</td>
+ <td>'$author'</td>
+ <td>'$"message'</td>
+ <td><a href="/'$repo'/showcommit/'$commithash'">'$commithash'</a></td>
+ </tr>'
+ commithash=`{cat /mnt/git/object/$commithash/parent | sed 1q}
+ }
+ echo '</table>'
+ html_emit_end
+}
+
+fn show_commit {
+ html_emit_start
+ cd $repo
+ git/fs
+ gitref=$commithash
+ if (! ref=`{resolveref $gitref}) {
+ `{resolveref $gitref}
+ echo '<b>'$status'</b>'
+ html_emit_end
+ exit
+ }
+ oldcommit=`{cat /mnt/git/$ref/parent}
+ author=`''{htcat /mnt/git/$ref/author}
+ date=`''{date `{mtime /mnt/git/$ref/msg | awk '{print $1}'}}
+ msg=`''{htcat /mnt/git/$ref/msg}
+ echo '
+ <table>
+ <tr><td><b>Commit:</b></td><td>'$commithash' (<a href="/'$repo'/browse/'$commithash'/">browse</a>)</td></tr>'
+ if(~ $#oldcommit 0) {
+ echo '<tr><td><b>Parent:</b></td><td>No parent</td></tr>'
+ }
+ if not {
+ echo '<tr><td><b>Parent:</b></td><td><a href="/'$repo'/showcommit/'$oldcommit'">'$oldcommit'</a></td></tr>'
+ }
+ echo '<tr><td><b>Author:</b></td><td>'$author'</td></tr>
+ <tr><td><b>Date:</b></td><td>'$date'</td></tr>
+ <tr><td><b>Message:</b></td><td><pre>'$msg'</pre></td></tr>
+ <tr><td></td></tr>
+ </table>'
+ diff=`''{git/export $commithash |
+ sed 's,^--- ([^ ]*).*,--- \1,g' |
+ sed 's,^\+\+\+ ([^ ]*).*,+++ \1,g' |
+ awk '
+BEGIN {
+ started=0
+}
+/^---/ {
+ started = 1
+}
+/^+++/ {
+
+}
+{
+ if (started) {
+ print $0
+ }
+}
+' | htcat |
+ sed -e 's,^--- a/(.*),</pre></code><br>\n--- <a href="/'$repo'/browse/'$oldcommit'/\1">\1</a>,g' \
+ -e 's,^\+\+\+ b/(.*),+++ <a href="/'$repo'/browse/'$commithash'/\1">\1</a><code><pre class="code">,g' \
+ -e 's,^--- (/dev/null),</pre></code><br>\n--- \1,g' \
+ -e 's,^\+\+\+ (/dev/null),+++ \1<code><pre class="code">,g' |
+ ssam 's,^--- (.*)\n\+\+\+ (.*)$,\1 => \2,g'
+}
+ echo '<pre><code><pre>'$diff'</pre></code></pre>'
+ html_emit_end
+}
+
+if (~ $location */browse) {
+ redirect $location/HEAD/
+}
+if not if (~ $location */browse/) {
+ redirect $locationHEAD
+}
+if not if (~ $location */shortlog) {
+ redirect $location/HEAD/
+}
+if not if (~ $location */shortlog/) {
+ redirect $locationHEAD
+}
+
+if (~ $location /) {
+ repo_index
+}
+if not if (~ $location */showcommit/*) {
+ parts=`{echo $location | sed 's,/(.*)/showcommit/([^/]*),\1 \2,'}
+ repo=$parts(1)
+ commithash=$parts(2)
+ show_commit
+}
+if not if (~ $location */browse/*/* ) {
+ parts=`{echo $location | sed 's,/(.*)/browse/([^/]*)(.*),\1 \2 \3,'}
+ repo=$parts(1)
+ gitref=$parts(2)
+ filepath=$parts(3)
+ repo_browse
+}
+if not if (~ $location */shortlog/*/* ) {
+ parts=`{echo $location | sed 's,/(.*)/shortlog/([^/]*)(.*),\1 \2 \3,'}
+ repo=$parts(1)
+ gitref=$parts(2)
+ filepath=$parts(3)
+ repo_shortlog
+}
+if not if (test -d $REPO_DIR$location/.git) {
+ repo_view $location
+}
+if not {
+ echo no match
+}