ref: f8a5ea28c2a510823598940a1e375e2337c8c6e2
dir: /gitonline.rc/
#!/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 }