| Mode | Name | Last commit | Updated | Size |
|---|---|---|---|---|
| .gitignore | Initial commit: foxygit, a read-only git web frontend | 1 month ago | 315 B | |
| README.md | Add accounts, API keys, and a web admin panel | 3 weeks ago | 5.68 KB | |
| assets | Add accounts, API keys, and a web admin panel | 3 weeks ago | ||
| deploy.sh | Initial commit: foxygit, a read-only git web frontend | 1 month ago | 4.22 KB | |
| inc | Add accounts, API keys, and a web admin panel | 3 weeks ago | ||
| index.php | Add accounts, API keys, and a web admin panel | 3 weeks ago | 16.66 KB | |
| install.sh | Initial commit: foxygit, a read-only git web frontend | 1 month ago | 1.46 KB | |
| retire-stagit.sh | Initial commit: foxygit, a read-only git web frontend | 1 month ago | 2.42 KB | |
| server | Add accounts, API keys, and a web admin panel | 3 weeks ago | ||
| themes | Initial commit: foxygit, a read-only git web frontend | 1 month ago | ||
| views | Add accounts, API keys, and a web admin panel | 3 weeks ago |
foxygit
A mostly-read-only git web frontend, in the spirit of stagit and cgit — but a single PHP application instead of a static-site generator or a C CGI program. No database, no framework, no build step. It shells out to the git binary and renders what comes back; accounts and API keys live in one flat JSON file, not a database.
git push/pull itself is not handled here — that's SSH or authenticated HTTPS against your bare repos (see server/). The web app is the "shop window" (browse repos), plus login, API key management, and a repo admin panel.
Features
- Browse repos: file tree, commit log (grouped by day), branches/tags, colorized commit diffs.
- README/LICENSE auto-detected from the repo root and rendered (a small, dependency-free
markdown → HTML converter — headings, lists, code, links, bold/italic).
- Atom feeds for commits and tags.
- Raw file download with correct
Content-Typesniffing. - Anonymous, unauthenticated
git cloneover HTTPS (seeserver/setup-anon-clone.sh); push worksover SSH for people with a key, or over HTTPS with an API key (see Accounts below) — the same split GitHub/GitLab use for public repos.
- Log in, create/revoke your own API keys, and (as an admin) create/delete repos and add other
accounts — all from the browser, no shell access needed.
- Themeable: colors live entirely in small CSS custom-property files under
themes/; thestructural CSS in
assets/base.cssnever hardcodes a color. Ships with a dark/light pair in its own style plus a GitHub Primer–inspired dark/light pair. A sun/moon toggle switches within a theme's family; a dropdown in the footer switches families. - Careful about the things a "just shell out to git" app can get wrong: leading-dash arguments
that could be read as flags, path traversal, unicode filenames, binary blobs, oversized diffs, and command/argument injection in general.
Accounts, API keys, and admin
Visiting the site with no accounts yet shows a one-time "set up an admin account" screen. Once logged in:
- Account (
?a=account) — anyone can create and revoke their own API keys. An API key isa personal-access-token-style credential: use it as the password when
git pushasks for one over HTTPS (any username works, same convention as GitHub). Any valid key can push to any repo — the same trust level SSH keyholders already have; there's no per-repo ACL. - Admin (
?a=admin, admin accounts only) — create and delete repos from the browser (deleterequires retyping the repo name to confirm, same guard as the SSH
deletecommand), and create additional accounts (with or without admin rights) — the HTTPS-login equivalent ofadd-key.sh.
Enabling the HTTPS-push side of this (beyond anonymous clone) needs one more server-side setup step: sudo bash server/setup-http-push.sh — see that script and server/git-http-backend-auth for how it works (a small CGI wrapper in front of git-http-backend that checks push requests' Basic Auth password against the stored API keys; reads stay anonymous, unchanged).
Architecture
index.php router only — resolves the request, asks inc/ for data, hands it to views/
inc/
config.php site-specific values (gitignored — see config.example.php)
functions.php all git/data logic; never prints HTML
auth.php accounts, API keys, sessions — one JSON file (AUTH_STORE), no database
render.php the one bridge between index.php and views/
views/
partials/ header (incl. the login/account/admin nav), footer, tabs, subnav
*.php one file per page (tree, log, commit, ..., login, account, admin)
assets/ structural CSS (base.css) + the one bit of JS (clone-to-clipboard)
themes/ *.css files, each just a set of CSS custom properties
server/ git hosting over SSH: user setup, key management, self-serve
`create`/`describe`/`delete`; the anonymous-HTTPS-clone route
(setup-anon-clone.sh); and the authenticated-HTTPS-push route
(setup-http-push.sh, git-http-backend-auth, verify-api-key.php) —
independent of the web frontend except for sharing inc/auth.php
inc/functions.php never emits HTML; views/*.php never talks to git. index.php is the only place that knows both sides exist.
Deploy
cp inc/config.example.php inc/config.phpand fill in your domain and paths.sudo bash install.sh— sets up git hosting over SSH (dedicated user, bare-repo storage,self-serve repo creation/description/deletion) and the web frontend (a php-fpm pool running as that user, since the bare repos aren't readable by the default
www-datapool, plus the Caddy block). Both halves are idempotent and can be run standalone too —server/setup-server.shfor just the git side,deploy.shfor just the web frontend.- Optional:
sudo bash server/setup-anon-clone.shfor unauthenticated HTTPS clone. - Optional:
sudo bash server/setup-http-push.sh(needs step 3 first) so people can push overHTTPS with an API key instead of only SSH — see "Accounts, API keys, and admin" above.
- Add collaborators' SSH keys with
sudo bash server/add-key.sh, or have them log in on the siteand create their own API key instead (once an admin has created their account).
Everything assumes Debian + Caddy + php-fpm; adjust the paths in inc/config.php and the server/ scripts for a different setup.
Requirements
PHP 8+ with exec() and proc_open() enabled (on by default), and the git binary on PATH. That's the whole dependency list.