inital commit
This commit is contained in:
@@ -0,0 +1,9 @@
|
|||||||
|
# build outputs
|
||||||
|
/gitocean
|
||||||
|
/bin/
|
||||||
|
|
||||||
|
# runtime storage
|
||||||
|
/storage/
|
||||||
|
|
||||||
|
# local env
|
||||||
|
.env
|
||||||
+521
@@ -0,0 +1,521 @@
|
|||||||
|
# Gitocean Phase 2 Plan: Usability
|
||||||
|
|
||||||
|
Phase 2 focuses on making Gitocean feel usable as a day-to-day personal Git hosting environment. This phase is not about GitLab enterprise parity, CI/CD, or a web UI. It is about setup, common workflows, repository inspection, pull request ergonomics, and maintenance.
|
||||||
|
|
||||||
|
## Goals
|
||||||
|
|
||||||
|
- Make first-time setup simple.
|
||||||
|
- Make CLI output readable by humans by default.
|
||||||
|
- Support the common workflow of publishing an existing local repository.
|
||||||
|
- Provide enough CLI inspection tools to compensate for no web UI.
|
||||||
|
- Improve pull request workflows with diff and checkout commands.
|
||||||
|
- Add simple repository metadata and settings.
|
||||||
|
- Add lightweight collaboration support.
|
||||||
|
- Add comments, token management, and basic admin/backup tooling.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Config + `gitocean init`
|
||||||
|
|
||||||
|
### Add server config file
|
||||||
|
|
||||||
|
Create a persistent server config file, likely:
|
||||||
|
|
||||||
|
```text
|
||||||
|
storage/config.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"addr": ":8080",
|
||||||
|
"public_url": "http://localhost:8080",
|
||||||
|
"storage": "storage",
|
||||||
|
"mysql_dsn": "root:pass@tcp(127.0.0.1:3306)/gitocean?parseTime=true"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add command
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gitocean init
|
||||||
|
```
|
||||||
|
|
||||||
|
It should:
|
||||||
|
|
||||||
|
1. Prompt for server listen address.
|
||||||
|
2. Prompt for public URL.
|
||||||
|
3. Prompt for storage directory.
|
||||||
|
4. Prompt for MySQL DSN or individual MySQL fields.
|
||||||
|
5. Create the database if missing.
|
||||||
|
6. Run migrations.
|
||||||
|
7. Create storage directories.
|
||||||
|
8. Optionally create the first user account.
|
||||||
|
9. Write config file.
|
||||||
|
10. Print next-step instructions.
|
||||||
|
|
||||||
|
### Update server command
|
||||||
|
|
||||||
|
Allow:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gitocean server
|
||||||
|
```
|
||||||
|
|
||||||
|
without requiring `--dsn` if config exists.
|
||||||
|
|
||||||
|
Still allow overrides:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gitocean server --config storage/config.json
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gitocean server --dsn '...' --addr :8080 --storage storage
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Friendly CLI output
|
||||||
|
|
||||||
|
Most commands currently print JSON. Phase 2 should make human-friendly output the default.
|
||||||
|
|
||||||
|
### Add global or per-command JSON output
|
||||||
|
|
||||||
|
Support:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gitocean repo search test --json
|
||||||
|
```
|
||||||
|
|
||||||
|
or eventually a global flag:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gitocean --json repo search test
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
Repo creation should print:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Created public repository owen/test
|
||||||
|
|
||||||
|
Clone:
|
||||||
|
git clone http://localhost:8080/owen/test.git
|
||||||
|
|
||||||
|
Add existing repo:
|
||||||
|
git remote add origin http://localhost:8080/owen/test.git
|
||||||
|
git branch -M main
|
||||||
|
git push -u origin main
|
||||||
|
```
|
||||||
|
|
||||||
|
Search should print a table:
|
||||||
|
|
||||||
|
```text
|
||||||
|
REPOSITORY VISIBILITY DESCRIPTION UPDATED
|
||||||
|
owen/test public Test repository 2m ago
|
||||||
|
alice/demo public Demo project 3h ago
|
||||||
|
```
|
||||||
|
|
||||||
|
PR list should print:
|
||||||
|
|
||||||
|
```text
|
||||||
|
#1 open Add config support bob:feature-config -> main
|
||||||
|
#2 merged Fix clone auth alice:fix-auth -> main
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. `repo publish`
|
||||||
|
|
||||||
|
Add a command for publishing an existing local Git repository.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gitocean repo publish NAME --public
|
||||||
|
gitocean repo publish NAME --private
|
||||||
|
```
|
||||||
|
|
||||||
|
Optional flags:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gitocean repo publish NAME --public --remote origin
|
||||||
|
gitocean repo publish NAME --public --branch main
|
||||||
|
gitocean repo publish NAME --public --description "My project"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Behavior
|
||||||
|
|
||||||
|
From inside a local Git repository:
|
||||||
|
|
||||||
|
1. Verify current directory is a Git repository.
|
||||||
|
2. Create remote repository through API.
|
||||||
|
3. Add remote if missing.
|
||||||
|
4. Set or rename current branch to `main` by default.
|
||||||
|
5. Push current branch.
|
||||||
|
6. Set upstream.
|
||||||
|
7. Print success and clone URL.
|
||||||
|
|
||||||
|
Equivalent workflow:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gitocean repo create test --public
|
||||||
|
git remote add origin http://localhost:8080/owen/test.git
|
||||||
|
git branch -M main
|
||||||
|
git push -u origin main
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. `repo view`, branches, tags
|
||||||
|
|
||||||
|
Since there is no web UI, add basic repository inspection commands.
|
||||||
|
|
||||||
|
### Repo view
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gitocean repo view OWNER/REPO
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```text
|
||||||
|
owen/test
|
||||||
|
Visibility: public
|
||||||
|
Default branch: main
|
||||||
|
Description: My test project
|
||||||
|
|
||||||
|
Clone:
|
||||||
|
git clone http://localhost:8080/owen/test.git
|
||||||
|
|
||||||
|
Open PRs: 2
|
||||||
|
Branches: 4
|
||||||
|
Tags: 1
|
||||||
|
```
|
||||||
|
|
||||||
|
### Branch listing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gitocean repo branches OWNER/REPO
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```text
|
||||||
|
BRANCH COMMIT UPDATED MESSAGE
|
||||||
|
main 8f31abc 2 hours ago Initial commit
|
||||||
|
feature-x 1ab22df 1 day ago Add feature
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tag listing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gitocean repo tags OWNER/REPO
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```text
|
||||||
|
TAG COMMIT DATE MESSAGE
|
||||||
|
v0.1.0 8f31abc 2026-06-08 First release
|
||||||
|
```
|
||||||
|
|
||||||
|
### API additions
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /api/repos/{owner}/{repo}/branches
|
||||||
|
GET /api/repos/{owner}/{repo}/tags
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. PR diff + PR checkout
|
||||||
|
|
||||||
|
Pull requests are difficult to use without seeing and checking out changes.
|
||||||
|
|
||||||
|
### PR diff
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gitocean pr diff OWNER/REPO NUMBER
|
||||||
|
```
|
||||||
|
|
||||||
|
Server should generate a diff between:
|
||||||
|
|
||||||
|
```text
|
||||||
|
source_repo:source_branch
|
||||||
|
```
|
||||||
|
|
||||||
|
and:
|
||||||
|
|
||||||
|
```text
|
||||||
|
target_repo:target_branch
|
||||||
|
```
|
||||||
|
|
||||||
|
API:
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /api/repos/{owner}/{repo}/pulls/{number}/diff
|
||||||
|
```
|
||||||
|
|
||||||
|
Return `text/plain` patch/diff output.
|
||||||
|
|
||||||
|
### PR checkout
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gitocean pr checkout OWNER/REPO NUMBER
|
||||||
|
```
|
||||||
|
|
||||||
|
From inside a local Git repo, it should:
|
||||||
|
|
||||||
|
1. Fetch PR source branch from source repository URL.
|
||||||
|
2. Create or update a local branch such as `pr-1`.
|
||||||
|
3. Check out that branch.
|
||||||
|
|
||||||
|
Equivalent:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git fetch http://localhost:8080/bob/test.git fix:pr-1
|
||||||
|
git checkout pr-1
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Repo description/default branch/visibility update
|
||||||
|
|
||||||
|
Add basic repository settings.
|
||||||
|
|
||||||
|
### Schema additions
|
||||||
|
|
||||||
|
Add columns to `repositories`:
|
||||||
|
|
||||||
|
- `description TEXT NOT NULL DEFAULT ''`
|
||||||
|
- `default_branch VARCHAR(200) NOT NULL DEFAULT 'main'`
|
||||||
|
- `archived BOOLEAN NOT NULL DEFAULT false`
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gitocean repo set OWNER/REPO --description "My project"
|
||||||
|
gitocean repo set OWNER/REPO --visibility private
|
||||||
|
gitocean repo set OWNER/REPO --visibility public
|
||||||
|
gitocean repo set OWNER/REPO --default-branch main
|
||||||
|
gitocean repo archive OWNER/REPO
|
||||||
|
gitocean repo unarchive OWNER/REPO
|
||||||
|
```
|
||||||
|
|
||||||
|
### API additions
|
||||||
|
|
||||||
|
```http
|
||||||
|
PATCH /api/repos/{owner}/{repo}
|
||||||
|
```
|
||||||
|
|
||||||
|
Owner-only.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Collaborators
|
||||||
|
|
||||||
|
Owner-only permissions are too limiting for personal collaboration. Add simple collaborators.
|
||||||
|
|
||||||
|
### Roles
|
||||||
|
|
||||||
|
- `read`: can clone/fetch private repositories.
|
||||||
|
- `write`: can clone/fetch/push.
|
||||||
|
|
||||||
|
Owner remains the only user who can:
|
||||||
|
|
||||||
|
- delete repository
|
||||||
|
- update settings
|
||||||
|
- manage collaborators
|
||||||
|
- merge/close PRs, unless explicitly changed later
|
||||||
|
|
||||||
|
### Schema
|
||||||
|
|
||||||
|
Add table:
|
||||||
|
|
||||||
|
```text
|
||||||
|
repository_collaborators
|
||||||
|
id
|
||||||
|
repository_id
|
||||||
|
user_id
|
||||||
|
role: read/write
|
||||||
|
created_at
|
||||||
|
```
|
||||||
|
|
||||||
|
Unique key:
|
||||||
|
|
||||||
|
```text
|
||||||
|
(repository_id, user_id)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gitocean repo collaborators OWNER/REPO
|
||||||
|
gitocean repo collaborator add OWNER/REPO USER --role read
|
||||||
|
gitocean repo collaborator add OWNER/REPO USER --role write
|
||||||
|
gitocean repo collaborator remove OWNER/REPO USER
|
||||||
|
```
|
||||||
|
|
||||||
|
### API additions
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /api/repos/{owner}/{repo}/collaborators
|
||||||
|
POST /api/repos/{owner}/{repo}/collaborators
|
||||||
|
DELETE /api/repos/{owner}/{repo}/collaborators/{username}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. PR comments
|
||||||
|
|
||||||
|
Add simple general comments on pull requests. Line comments can wait.
|
||||||
|
|
||||||
|
### Schema
|
||||||
|
|
||||||
|
Add table:
|
||||||
|
|
||||||
|
```text
|
||||||
|
pull_request_comments
|
||||||
|
id
|
||||||
|
pull_request_id
|
||||||
|
author_user_id
|
||||||
|
body
|
||||||
|
created_at
|
||||||
|
updated_at
|
||||||
|
```
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gitocean pr comment OWNER/REPO NUMBER "Looks good"
|
||||||
|
gitocean pr comments OWNER/REPO NUMBER
|
||||||
|
```
|
||||||
|
|
||||||
|
Optional editor support later:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gitocean pr comment OWNER/REPO NUMBER --editor
|
||||||
|
```
|
||||||
|
|
||||||
|
### API additions
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /api/repos/{owner}/{repo}/pulls/{number}/comments
|
||||||
|
POST /api/repos/{owner}/{repo}/pulls/{number}/comments
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. Token management
|
||||||
|
|
||||||
|
Tokens expire after 7 days, but users need visibility and revocation.
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gitocean token list
|
||||||
|
gitocean token revoke TOKEN_ID
|
||||||
|
gitocean token prune
|
||||||
|
```
|
||||||
|
|
||||||
|
### Behavior
|
||||||
|
|
||||||
|
- `token list`: show active tokens for current user.
|
||||||
|
- `token revoke`: revoke one token.
|
||||||
|
- `token prune`: remove expired/revoked tokens from database. Owner/admin-only if global, current-user only otherwise.
|
||||||
|
|
||||||
|
### API additions
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /api/tokens
|
||||||
|
DELETE /api/tokens/{id}
|
||||||
|
POST /api/tokens/prune
|
||||||
|
```
|
||||||
|
|
||||||
|
### CLI expired-session UX
|
||||||
|
|
||||||
|
When API returns unauthorized, show:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Your session may have expired. Run:
|
||||||
|
gitocean login
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. Backup/admin commands
|
||||||
|
|
||||||
|
Personal servers need reliable maintenance tooling.
|
||||||
|
|
||||||
|
### Admin commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gitocean admin users list
|
||||||
|
gitocean admin users delete USER
|
||||||
|
gitocean admin repos list
|
||||||
|
gitocean admin storage check
|
||||||
|
gitocean admin tokens prune
|
||||||
|
```
|
||||||
|
|
||||||
|
For MVP, admin can be:
|
||||||
|
|
||||||
|
- the first registered user, or
|
||||||
|
- a boolean `is_admin` column on `users`.
|
||||||
|
|
||||||
|
### Backup commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gitocean backup create backup.tar.gz
|
||||||
|
gitocean backup restore backup.tar.gz
|
||||||
|
```
|
||||||
|
|
||||||
|
Backup should include:
|
||||||
|
|
||||||
|
- server config
|
||||||
|
- `storage/repos/`
|
||||||
|
- MySQL dump of metadata
|
||||||
|
|
||||||
|
Possible implementation:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mysqldump ... > metadata.sql
|
||||||
|
tar -czf backup.tar.gz storage/config.json storage/repos metadata.sql
|
||||||
|
```
|
||||||
|
|
||||||
|
Restore should:
|
||||||
|
|
||||||
|
1. Stop or warn about running server.
|
||||||
|
2. Restore config.
|
||||||
|
3. Restore repositories.
|
||||||
|
4. Restore database from SQL dump.
|
||||||
|
5. Run migrations after restore.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Recommended implementation order
|
||||||
|
|
||||||
|
1. Config file support and `gitocean init`.
|
||||||
|
2. Friendly CLI output with `--json` escape hatch.
|
||||||
|
3. `repo publish`.
|
||||||
|
4. Repository metadata fields and `repo view`.
|
||||||
|
5. Branch/tag listing.
|
||||||
|
6. PR diff.
|
||||||
|
7. PR checkout.
|
||||||
|
8. Collaborators.
|
||||||
|
9. PR comments.
|
||||||
|
10. Token management.
|
||||||
|
11. Backup/admin commands.
|
||||||
|
|
||||||
|
## Success criteria
|
||||||
|
|
||||||
|
Phase 2 is successful when a user can comfortably:
|
||||||
|
|
||||||
|
1. Initialize the server without memorizing flags.
|
||||||
|
2. Register/login from CLI.
|
||||||
|
3. Publish an existing local Git repository with one command.
|
||||||
|
4. Clone, push, search, and inspect repositories.
|
||||||
|
5. Open, inspect, checkout, and merge PRs.
|
||||||
|
6. Share private repositories with specific users.
|
||||||
|
7. Revoke tokens and back up the server.
|
||||||
@@ -0,0 +1,194 @@
|
|||||||
|
# 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.
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,10 @@
|
|||||||
|
module gitocean
|
||||||
|
|
||||||
|
go 1.23
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/go-sql-driver/mysql v1.9.0
|
||||||
|
golang.org/x/crypto v0.31.0
|
||||||
|
)
|
||||||
|
|
||||||
|
require filippo.io/edwards25519 v1.1.0 // indirect
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||||
|
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||||
|
github.com/go-sql-driver/mysql v1.9.0 h1:Y0zIbQXhQKmQgTp44Y1dp3wTXcn804QoTptLZT1vtvo=
|
||||||
|
github.com/go-sql-driver/mysql v1.9.0/go.mod h1:pDetrLJeA3oMujJuvXc8RJoasr589B6A9fwzD3QMrqw=
|
||||||
|
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
|
||||||
|
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||||
Submodule
+1
Submodule test added at b00f141889
Reference in New Issue
Block a user