vextoly/gitman
Fork of patx/gitman.
An ultra small Git host, free on gitman.io or self-hosted by you :)
$ git clone https://gitman.io/git/vextoly/gitman
GitMan
GitMan is a small Bottle app for hosting public Git repositories with local user accounts. It includes repository browsing, README rendering, issues, forks, comments, pull requests, stars, Pages-style static sites, and Git over HTTP for clone, fetch, and push.
Getting Started
Create a Virtual Environment, Install dependencies and run the app:
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
python app.py
Then open http://127.0.0.1:8080, sign up, and create a repository. Instructions will be provided on how to commit to the newly created repo.
How the App Works
GitMan keeps application metadata in SQLite and keeps Git data in bare repositories on disk. By default, the database is created at ./data/gitman.sqlite3 and repositories are stored under ./data/repos/<owner>/<repo>.
All repositories are public for web browsing, clone, and fetch. Pushes go through Git over HTTP at /git/<owner>/<repo> and require HTTP Basic Auth with a GitMan account that owns the repository or has been added as a contributor.
Creating a repository initializes an empty bare Git repo with HEAD pointing at main. The repository page shows clone instructions until the first push lands, then renders a README preview when it finds README.md, README.rst, README.txt, or README.
Empty repositories can also be populated from a full Git bundle in repository settings. From the existing repository, run git bundle create repo.bundle --all, then upload repo.bundle before any commits have been pushed to the GitMan repository.
The web UI reads directly from Git for source browsing, raw file downloads, commit history, branches, tags, archives, diffs, and README content. Markdown README files are rendered to sanitized HTML before display, and repository descriptions plus issue, pull request, and commit comments support sanitized links.
Issues, comments, stars, contributors, forks, and pull request records are stored in SQLite. Forking creates a bare clone of the source repository. Pull requests compare a source ref against a target branch, and maintainers can close or merge them from the browser.
Pages-style static hosting is driven by the Git repository contents. A user site repository named <username>.<GITMAN_PAGES_DOMAIN> is served from its repository root at https://<username>.<GITMAN_PAGES_DOMAIN>/; project Pages can be enabled in repository settings and are served from that repository's docs/ directory. Any published Pages repository can advertise a custom domain with a DNS TXT verification record: user sites use a root CNAME file, and project sites use docs/CNAME. A custom domain on the user site also serves that user's enabled project Pages at https://<custom-domain>/<repo>/.
Notifications
The bell beside the account and new repository icons opens your personal notifications feed. It includes activity on issues you created or commented on, plus activity (including commits, issues, and pull requests) in repositories you own or have starred. Your own actions are excluded. Commit authors matching your username or display name are treated as your own commits. The feed loads older entries as you scroll.
Type @ in issue/PR titles, descriptions, or comment fields to search accounts
by username or display name. Pick a suggestion with the mouse or with the arrow
keys and Enter/Tab; Escape dismisses the menu.
Use @username in issue and pull request titles/descriptions or in issue, pull
request, and commit comments to mention another account. Existing handles link
to profiles, and the mentioned account sees the event in their feed even without
starring the repository or participating in the thread. Mentions are case-insensitive;
code, escaped handles, email addresses, and Markdown links do not trigger them.
Repeated mentions and overlapping subscriptions yield one event. Mention matching
also applies to existing discussions. Unstarring a repository
removes that source unless you follow its issues, own its pull request target, or
are mentioned in the event.
Issue close/reopen and pull request close history is recorded from this version onward.
Commit activity scans up to GITMAN_ACTIVITY_REPO_SCAN_LIMIT owned or starred repositories,
prioritizing the most recently updated repositories.
Configuration
SECRET_KEY: Bottle signed-cookie secretGITMAN_DB: SQLite database path, default./data/gitman.sqlite3GITMAN_REPO_ROOT: Git repository root, default./data/reposGITMAN_DEBUG: set to1for debug mode and reloaderGITMAN_GIT_BINARY: Git executable name or full path, defaultgitGITMAN_PAGES_DOMAIN: wildcard Pages domain, defaultgitman.ioGITMAN_MAX_FORM_BYTES: maximum browser form body size, default65536GITMAN_MAX_IMPORT_BYTES: maximum Git bundle import upload size, default2147483648GITMAN_IMPORT_TIMEOUT_SECONDS: maximum Git bundle verify/fetch time, default3600GITMAN_GUNICORN_TIMEOUT_SECONDS: Gunicorn worker timeout, defaultGITMAN_IMPORT_TIMEOUT_SECONDS + 300GITMAN_MAX_RENDER_BYTES: maximum file preview size, default262144GITMAN_MAX_GIT_RESPONSE_BYTES: maximum Git HTTP backend response size, default268435456GITMAN_REPO_SEARCH_CANDIDATE_LIMIT: maximum repositories loaded for fuzzy search scoring, default1000GITMAN_ACTIVITY_REPO_SCAN_LIMIT: maximum repositories scanned for commit activity, default100GITMAN_RATE_LIMIT_ENABLED: set to0to disable login, signup, and Git push auth rate limitingGITMAN_AUTH_RATE_LIMIT_PRUNE_BATCH_SIZE: maximum expired rate-limit rows deleted during one cleanup, default1000PORT: HTTP port, default8080
Rate-limit counters are stored in the configured SQLite database, so failed-attempt tracking is shared across worker processes.
When GITMAN_DEBUG is off, SECRET_KEY must be set to a non-default value before startup.
Repositories and their Git data live on local disk, so keep the database and repo root on persistent storage. The app uses SQLite WAL mode and shells out to Git, so the process user needs read/write access to both paths and access to the configured Git executable. It is recommended to run behind nginx/gunicorn.
License
GitMan is licensed under the BSD 3-Clause License. See LICENSE.
Account passwords and resource limits
Sign-in sessions persist for 14 days, with a fixed expiry checked by the server. Existing signed sessions upgrade on their next visit.
Edit profile includes a Change password dialog. Changes require the current password, validate confirmation, and invalidate other browser sessions. Git HTTPS uses the new password immediately. Existing sessions survive upgrading until their account changes its password. Password changes use CSRF protection and failed-attempt throttling. Passwords are never included in rendered forms or logs.
Repositories default to a 256 MiB storage cap (GITMAN_MAX_REPO_BYTES). Push hooks
check existing and quarantined objects before accepting references; imports and
forks check size before publishing. Incoming packs and streamed uploads are bounded.
For a shared VPS, deploy/70-resource-limits.conf provides a systemd drop-in:
75% of one CPU, 768 MiB memory throttling, 1 GiB hard memory limit, no swap, and
128 tasks. The limits cover the service and its Git subprocesses. At the hard
memory limit GitMan may restart; mail should run in a separate service. These are
process resource limits, not an aggregate disk quota. The repository cap does not
limit the number of repositories. Adjust these settings for your workload.