# Gitocean Implementation Plan ## Product decisions - Build a Git repository hosting platform in Go. - Store bare Git repositories under `storage/repos/{owner}/{repo}.git`. - Use MySQL for metadata. - Support HTTP Smart Git only. SSH is out of scope for MVP. - Support CLI + API only. No web UI. - Registration is open, but registration happens through the CLI/API only. - Users register with email, username, and password. - Users can log in with either email + password or username + password. - Login returns a temporary auth token that expires after 7 days. - The CLI stores this token locally for API calls and can approve it into Git's credential helper for Git HTTP operations. - Repository names allow lowercase letters, numbers, `.`, `_`, and `-`. - Usernames allow lowercase letters, numbers, `_`, and `-`. - New repositories use `main` as the default branch. - Pull request numbers are per target repository. ## Permissions ### Repository visibility - `public`: anyone can clone/fetch. Only the owner can push/delete/manage. - `private`: only the owner can clone/fetch/push/delete/manage. ### Writes - MVP is owner-only. - There are no collaborators, organizations, teams, or fine-grained permissions yet. - Open collaboration is supported through pull requests against public repositories. ## Storage layout ```text storage/ repos/ alice/ demo.git/ bob/ project.git/ ``` Each repository directory is a bare Git repository. ## MySQL schema Core tables: - `users` - id - email - username - password_hash - created_at - `auth_tokens` - id - user_id - token_hash - expires_at - revoked_at - created_at - `repositories` - id - owner_user_id - name - visibility: `public` or `private` - forked_from_repository_id nullable - created_at - updated_at - `pull_requests` - id - target_repository_id - number - author_user_id - source_repository_id - source_branch - target_branch - title - description - status: `open`, `closed`, or `merged` - closed_at nullable - merged_at nullable - created_at - updated_at ## API ### Auth ```http POST /api/register POST /api/login POST /api/logout GET /api/me ``` ### Repositories ```http POST /api/repos GET /api/repos/search?q=demo&scope=all GET /api/repos/search?q=demo&scope=mine GET /api/repos/{owner}/{repo} DELETE /api/repos/{owner}/{repo}?force=false POST /api/repos/{owner}/{repo}/fork ``` ### Pull requests ```http POST /api/repos/{owner}/{repo}/pulls GET /api/repos/{owner}/{repo}/pulls GET /api/repos/{owner}/{repo}/pulls/{number} POST /api/repos/{owner}/{repo}/pulls/{number}/close POST /api/repos/{owner}/{repo}/pulls/{number}/merge ``` ### Git HTTP ```http /{owner}/{repo}.git/info/refs /{owner}/{repo}.git/git-upload-pack /{owner}/{repo}.git/git-receive-pack ``` ## CLI commands ```bash gitocean server --addr :8080 --dsn 'user:pass@tcp(127.0.0.1:3306)/gitocean?parseTime=true' --storage storage gitocean register gitocean login gitocean logout gitocean whoami gitocean repo create NAME --public gitocean repo create NAME --private gitocean repo delete OWNER/NAME [--force] gitocean repo search QUERY --all gitocean repo search QUERY --mine gitocean repo fork OWNER/NAME [--name NEW_NAME] gitocean clone OWNER/NAME gitocean pr create --from OWNER/REPO:BRANCH --to OWNER/REPO:BRANCH --title TITLE --description DESC gitocean pr create --repo OWNER/REPO --from BRANCH --to BRANCH --title TITLE --description DESC gitocean pr list OWNER/REPO gitocean pr view OWNER/REPO NUMBER gitocean pr close OWNER/REPO NUMBER gitocean pr merge OWNER/REPO NUMBER ``` ## Pull request rules ### Same-repository PRs - Source and target repository are the same. - Only the repository owner can create same-repo PRs. - Source and target branches must both exist. ### Cross-repository PRs - Source repository branch points to target repository branch. - Source repository must be owned by the PR author. - Target repository must be public, unless the author is also the target owner. - Source and target branches must both exist. - Only the target repository owner can close or merge the PR. ## Merge behavior MVP merge mode is a normal merge commit: 1. Clone target repo into a temporary worktree. 2. Checkout target branch. 3. Add/fetch source repo branch. 4. Run `git merge --no-ff FETCH_HEAD`. 5. Push the result back to the target branch. 6. Mark PR as merged. If conflicts occur, return an error and keep the PR open. ## Implementation milestones 1. Project scaffold and build setup. 2. MySQL migrations. 3. User registration, login, logout, and token auth. 4. Repository create, delete, detail, search. 5. HTTP Smart Git integration using `git http-backend`. 6. CLI auth and repository commands. 7. Fork support. 8. Pull request create/list/view/close. 9. Pull request merge. 10. Tests, hardening, and UX polish.