# GitGram
A self-hosted git repository hosting platform written entirely in PHP, designed to run on shared hosting accounts with no database, no shell execution, and no external dependencies beyond a standard PHP installation.
## Features
- **Pure PHP git implementation** — read/write git objects, pack files, and refs without `exec()`, `shell_exec()`, or `proc_open()`
- **Smart HTTP protocol** — full git clone, push, and pull over HTTP using the native git wire protocol
- **OS/2 Warp 3.0 UI** — teal desktop, beveled windows, title bar controls (minimize, maximize, ×)
- **User accounts** — registration with math captcha, invite-only mode, profile pages with 128×128 avatars
- **Repository management** — create, browse, upload files, manage access per repo
- **Gitolite-inspired access control** — R / RW / RW+ permissions for users, groups (`@group`), and `@all`
- **Repository forking** — fork any public repo into your own account with full history
- **File browser** — tree view, syntax-highlighted blob view, raw file download, ZIP archive download
- **Commit log** — paginated history, individual commit view
- **Admin panel** — user management, repo management, invite codes, site settings
- **Setup utility** — `setup.php` for initial account creation without admin access
- **No database required** — all data stored as JSON files
## Requirements
- PHP 8.1+
- Apache with `mod_rewrite` (or Nginx with equivalent rewrite rules)
- PHP extensions: `zlib`, `json`, `session`, `gd` (for avatars), `zip` (for ZIP download)
- Write access to `data/`, `repos/`, and `avatars/` directories
## Installation
1. Upload all files to your web root (or a subdirectory)
2. Set directory permissions:
```
chmod 755 data/ repos/ avatars/
```
3. Edit `config.php` and set your admin password hash:
```
php -r "echo password_hash('yourpassword', PASSWORD_DEFAULT);"
```
Paste the result into `ADMIN_HASH`.
4. Visit `setup.php` to create your first user account
5. Lock `setup.php` from within its own interface once accounts are created
6. Visit `/admin` to manage users, repositories, and site settings
## Configuration (`config.php`)
| Constant | Default | Description |
|---|---|---|
| `SITE_TITLE` | `GitGram` | Site name shown in the UI |
| `SITE_URL` | *(auto)* | Override base URL, e.g. `https://git.example.com` |
| `REPO_PATH` | `./repos` | Where bare git repositories are stored |
| `DATA_PATH` | `./data` | Where JSON data files are stored |
| `GIT_BIN` | `git` | Path to git binary (used if shell is available) |
| `ADMIN_HASH` | *(placeholder)* | bcrypt hash of the admin panel password |
| `AVATAR_PATH` | `./avatars` | Where user avatar images are stored |
| `COMMIT_PREVIEW` | `10` | Number of commits shown on the repo home page |
## Directory Structure
```
gitgram/
├── index.php Main application (router, pages, helpers)
├── admin.php Admin panel
├── gitlib.php Pure PHP git object store + smart HTTP protocol
├── setup.php Initial account setup utility
├── config.php Site configuration
├── .htaccess URL rewriting + directory protection
├── data/
│ ├── users.json User accounts and groups
│ ├── repos.json Repository metadata and access rules
│ ├── settings.json Site settings
│ ├── invites.json Invite codes
│ └── .htaccess Blocks direct web access
├── repos/
│ ├── .htaccess Blocks direct web access
│ └── *.git/ Bare git repositories
└── avatars/
└── *.jpg User avatar images (128×128 JPEG)
```
## Access Control
Access rules are stored in `data/repos.json` per repository:
```json
{
"myrepo": {
"owner": "alice",
"access": {
"@all": "R",
"@devs": "RW",
"bob": "RW+",
"mallory": "-"
}
}
}
```
Permission levels:
- `-` — explicitly denied
- `R` — read (clone, browse)
- `RW` — read + push (no force push)
- `RW+` — read + push + force push + delete refs
Subjects: a username, `@groupname` (defined in `users.json`), or `@all` (everyone including anonymous).
## Using Git with GitGram
```bash
# Clone a repository
git clone http://yoursite.com/reponame.git
# Push to a repository (credentials required)
git remote add origin http://yoursite.com/reponame.git
git push origin main
# Cache credentials
git config credential.helper store
```
## Shared Hosting Notes
GitGram is built specifically for shared hosts where shell execution is disabled:
- `exec()`, `shell_exec()`, and `proc_open()` are all optional — `gitlib.php` handles all git operations in pure PHP when they are unavailable
- No database is used — everything is stored in flat JSON files and the git object store
- All file writes use atomic temp-file + rename to prevent corruption
## License
MIT License — see source files for details.