git.lucas.co / gitsite
the static git browser that builds this site
git clone https://git.lucas.co/gitsite.git

commit93ce3e9078cac54952e4d6f19ab452ef71731cbd
parent3a49ee2316
authorLucas Galante <[email protected]>
date2026-08-11 11:16
Switch lineup to website + cce projects; handle empty repos

generate.py no longer crashes on repos with no commits (clear-typeface):
log/files/index fall back gracefully and the log page notes the repo
is empty.

Co-Authored-By: Claude Fable 5 <[email protected]>

 generate.py | 18 +++++++++++++++---
 repos.conf  | 34 ++++++++++++++++++++++++++++------
 2 files changed, 43 insertions(+), 9 deletions(-)

diff --git a/generate.py b/generate.py
index dc328fd..07480a0 100755
--- a/generate.py
+++ b/generate.py
@@ -153,6 +153,8 @@ def gen_log(repo, mirror, repo_dir, commits):
                  f'<td><a href="commit/{h}.html">{esc(subject)}</a></td>'
                  f'<td>{esc(author)}</td></tr>\n')
     body += '</table>\n'
+    if not commits:
+        body += '<div class="notice">no commits yet</div>\n'
     write_page(repo_dir / "index.html", repo["name"], body, rel(repo_dir, OUT))
 
 
@@ -160,7 +162,11 @@ def gen_files(repo, mirror, repo_dir):
     body = repo_header(repo, repo_dir, repo_dir, "Files")
     body += '<table class="list">\n<tr><td>Mode</td><td>Name</td><td>Size</td></tr>\n'
     entries = []
-    for line in git(mirror, "ls-tree", "-r", "-l", "HEAD").splitlines():
+    try:
+        tree = git(mirror, "ls-tree", "-r", "-l", "HEAD").splitlines()
+    except RuntimeError:  # empty repository
+        tree = []
+    for line in tree:
         info, path = line.split("\t", 1)
         mode, otype, _h, size = info.split()
         entries.append((mode, otype, size, path))
@@ -243,7 +249,10 @@ def gen_index(repos):
     body += '<table class="list">\n<tr><td>Name</td><td>Description</td><td>Last commit</td></tr>\n'
     for repo in repos:
         mirror = MIRRORS / f'{repo["name"]}.git'
-        last = git(mirror, "log", "-1", "--format=%as", "HEAD").strip()
+        try:
+            last = git(mirror, "log", "-1", "--format=%as", "HEAD").strip()
+        except RuntimeError:  # empty repository
+            last = "-"
         body += (f'<tr><td><a href="{quote(repo["name"])}/index.html">{esc(repo["name"])}</a></td>'
                  f'<td>{esc(repo["desc"])}</td><td>{last}</td></tr>\n')
     body += '</table>\n'
@@ -266,7 +275,10 @@ def main():
             sys.exit(f"missing mirror {mirror}; run build.sh")
         repo_dir = OUT / repo["name"]
         commits = []
-        log = git(mirror, "log", "--format=%H%x1f%as%x1f%an%x1f%s", "HEAD")
+        try:
+            log = git(mirror, "log", "--format=%H%x1f%as%x1f%an%x1f%s", "HEAD")
+        except RuntimeError:  # empty repository
+            log = ""
         for line in log.splitlines():
             h, at, author, subject = line.split("\x1f")
             commits.append((h, at, author, subject))
diff --git a/repos.conf b/repos.conf
index d1df3d2..0e9687d 100644
--- a/repos.conf
+++ b/repos.conf
@@ -2,9 +2,31 @@
 # mode: "clone" = browsable + clonable via dumb http, "browse" = browsable only
 # no spaces around the | separators
 website|/home/lsgalante/Dropbox/src/website|source for lucas.co|browse
-Myna|/home/lsgalante/Dropbox/src/Myna||clone
-hou-control|/home/lsgalante/Dropbox/src/hou-control||clone
-go_mono|/home/lsgalante/Dropbox/src/go_mono||clone
-fontpreview|/home/lsgalante/Dropbox/src/fontpreview||clone
-font-new-heterodox-mono|/home/lsgalante/Dropbox/src/font-new-heterodox-mono||clone
-gitsite|/home/lsgalante/Dropbox/src/gitsite|generator for git.lucas.co|clone
+cce-authenticator|/home/lsgalante/Dropbox/cce/cce-authenticator||clone
+cce-browser|/home/lsgalante/Dropbox/cce/cce-browser||clone
+cce-cloud|/home/lsgalante/Dropbox/cce/cce-cloud||clone
+cce-color-editor|/home/lsgalante/Dropbox/cce/cce-color-editor||clone
+cce-compositor|/home/lsgalante/Dropbox/cce/cce-compositor||clone
+cce-data-editor|/home/lsgalante/Dropbox/cce/cce-data-editor||clone
+cce-designer|/home/lsgalante/Dropbox/cce/cce-designer||clone
+cce-display-manager|/home/lsgalante/Dropbox/cce/cce-display-manager||clone
+cce-email|/home/lsgalante/Dropbox/cce/cce-email||clone
+cce-files|/home/lsgalante/Dropbox/cce/cce-files||clone
+cce-fonts|/home/lsgalante/Dropbox/cce/cce-fonts||browse
+cce-graph|/home/lsgalante/Dropbox/cce/cce-graph||clone
+cce-icons|/home/lsgalante/Dropbox/cce/cce-icons||clone
+cce-layout-interface|/home/lsgalante/Dropbox/cce/cce-layout-interface||clone
+cce-map|/home/lsgalante/Dropbox/cce/cce-map||clone
+cce-notifier|/home/lsgalante/Dropbox/cce/cce-notifier||clone
+cce-preview|/home/lsgalante/Dropbox/cce/cce-preview||clone
+cce-remote|/home/lsgalante/Dropbox/cce/cce-remote||clone
+cce-screenaver|/home/lsgalante/Dropbox/cce/cce-screenaver||clone
+cce-secrets|/home/lsgalante/Dropbox/cce/cce-secrets||clone
+cce-status-interface|/home/lsgalante/Dropbox/cce/cce-status-interface||clone
+cce-system-interface|/home/lsgalante/Dropbox/cce/cce-system-interface||clone
+cce-terminal|/home/lsgalante/Dropbox/cce/cce-terminal||clone
+cce-test-interface|/home/lsgalante/Dropbox/cce/cce-test-interface||browse
+cce-text-editor|/home/lsgalante/Dropbox/cce/cce-text-editor||clone
+cce-ui|/home/lsgalante/Dropbox/cce/cce-ui||clone
+cce-window-manager|/home/lsgalante/Dropbox/cce/cce-window-manager||clone
+clear-typeface|/home/lsgalante/Dropbox/cce/clear-typeface||clone