Warning
This project is still in active development and should not be used in production environments.
A custom Git Smart HTTP(S) server written in Go, designed for everyone with built-in authentication, observability, and operational features.
Mostly, we started this project, because relaying on git-http-backend as the main Git server, may be not a great idea.
We suggest to deploy from Docker, as it uses Git and may messed up your config.
# Build
docker build -t workgit:latest .
# Run
docker run -d \
-p 8080:8080 \
-v /path/to/repos:/var/lib/workgit/repos \
-v /path/to/config.yaml:/etc/workgit/config.yaml \
workgit:latestOr build from source:
git clone https://github.com/lluaguard/workgit
cd workgit
go build -o workgit ./cmd/workgit- Create a configuration file
config.yaml:
server:
addr: ":8080"
storage:
root: "./repos"
defaultBranch: "main"
auth:
anonymousRead: true
tokens:
- "your-secret-token"
log:
level: "info"
format: "json"- Start the server:
workgit serve --config config.yaml- Create a repository:
workgit repo create myproject.git- Use with Git:
# Clone (anonymous read if enabled)
git clone http://localhost:8080/myproject.git
# Push (requires authentication)
git remote add origin http://user:your-secret-token@localhost:8080/myproject.git
git push -u origin mainserver:
addr: ":8080" # Listen address
tls:
enabled: true
cert: "/path/to/cert.pem"
key: "/path/to/key.pem"storage:
root: "/var/lib/workgit/repos" # Repository root directory
autoInit: false # Auto-create repos on first access
defaultBranch: "main" # Default branch for new repos
allowUnknownRepos: false # Allow access to non-existent reposauth:
anonymousRead: false # Allow unauthenticated read access
tokens:
- "token1"
- "token2"
mtls:
caFile: "/path/to/ca.pem"
allowedSubjects:
- "CN=client1"
- "CN=client2"limits:
maxRequestMB: 100 # Maximum request body size in MB
rateLimit:
rps: 100 # Requests per second per IP
burst: 200 # Burst capacity# Start server
workgit serve --config config.yaml
# Override config with flags
workgit serve --addr :9000 --root /data/repos --anonymous-read# Create repository
workgit repo create myrepo.git --default-branch main
# List repositories
workgit repo list
# Delete repository
workgit repo delete myrepo.git
# JSON output
workgit repo list --jsonWorkGit supports multiple authentication methods:
git clone http://localhost:8080/repo.git
# When prompted:
# Username: <anything>
# Password: <your-token>
# Or in URL:
git clone http://user:token@localhost:8080/repo.gitConfigure client certificates and CA:
auth:
mtls:
caFile: "/etc/workgit/ca.pem"
allowedSubjects:
- "CN=ci-server"Then use git with client certificates:
git config --global http.sslCert /path/to/client.crt
git config --global http.sslKey /path/to/client.key
git clone https://git.example.com/repo.gitPrometheus metrics available at /metrics:
workgit_http_requests_total- HTTP request count by method/path/statusworkgit_http_request_duration_seconds- Request latency histogramworkgit_git_operations_total- Git operations by service/operation/statusworkgit_git_operation_duration_seconds- Git operation latencyworkgit_active_connections- Current active connections
GET /health/live- Liveness probe (always returns 200 if server is up)GET /health/ready- Readiness probe (checks storage access)
Structured logs with request tracing:
{
"time": "2025-01-15T10:30:00Z",
"level": "info",
"msg": "request",
"request_id": "1234567890",
"method": "POST",
"path": "/repo.git/git-receive-pack",
"status": 200,
"duration_ms": 1234,
"remote": "10.0.1.5:54321"
}apiVersion: apps/v1
kind: Deployment
metadata:
name: workgit
spec:
replicas: 3
selector:
matchLabels:
app: workgit
template:
metadata:
labels:
app: workgit
spec:
containers:
- name: workgit
image: workgit:latest
ports:
- containerPort: 8080
volumeMounts:
- name: repos
mountPath: /var/lib/workgit/repos
- name: config
mountPath: /etc/workgit
livenessProbe:
httpGet:
path: /health/live
port: 8080
readinessProbe:
httpGet:
path: /health/ready
port: 8080
volumes:
- name: repos
persistentVolumeClaim:
claimName: workgit-repos
- name: config
configMap:
name: workgit-configRun unit tests:
go test ./...Run tests with coverage:
go test -cover ./...Run integration tests with real Git:
# Requires git binary in PATH
go test -tags=integration ./internal/git/...Run fuzz tests:
go test -fuzz=FuzzPktLine ./internal/gitAll configuration can be overridden via environment variables:
WORKGIT_CONFIG- Config file pathWORKGIT_ADDR- Server addressWORKGIT_STORAGE_ROOT- Repository rootWORKGIT_TLS_CERT- TLS certificate fileWORKGIT_TLS_KEY- TLS key fileWORKGIT_ANONYMOUS_READ- Allow anonymous read (true/false)WORKGIT_AUTO_INIT- Auto-initialize repos (true/false)
WorkGit defaults to SHA-1 but supports SHA-256 repositories. To use SHA-256:
# Create SHA-256 repository
git init --object-format=sha256 --bare /path/to/repo.git
# WorkGit will automatically detect and advertise object-format=sha256Note: Ensure all clients support SHA-256 (Git 2.29+).
Contributions are welcome! Please:
- Run tests:
go test ./... - Run linters:
go vet ./...andstaticcheck ./... - Format code:
gofmt -s -w . - Update documentation for new features
GPLv3 License - see LICENSE file for details.
- Issues: https://github.com/lluaguard/workgit/issues
- Documentation: https://github.com/lluaguard/workgit/wiki