Files
headquarter/openspec/changes/archive/2026-05-19-git-control/design.md
T
Fusion 0bc0d99c21 feat: add project settings page with tabbed layout
- Create SettingsTabLayout component with sidebar navigation
- Create ProjectSettingsPage with General settings tab
- Create RepositoriesSettingsTab for repo management
- Add Members placeholder tab
- Update router with settings routes
- Add CSS styles for settings layout
- Navigate to /projects/:id/settings from workspace header
2026-05-19 15:26:57 +02:00

7.3 KiB

Git Control - Design

Architecture

Repository Workspace
├─ Toolbar
│  ├─ [Fetch] [Pull] [Push]
│  ├─ [Branch: main ▼] [+ New Branch]
│  └─ [Commit] [Merge ▼]
├─ Sidebar
│  ├─ Repo Selector
│  ├─ Branch Selector (with management)
│  └─ File Tree (with status icons)
│     ├─ 📄 main.py ✏️ (modified)
│     ├─ 📁 src/
│     └─ 📄 README.md ✨ (new)
└─ Main Content
   ├─ File Viewer (with edit/save)
   └─ Commit Panel (when files modified)
      ├─ Changed files list
      ├─ Commit message input
      └─ [Commit to main] button

Git Operations

Branch Operations

Create Branch:

POST /projects/{id}/repositories/{id}/branches
{
  "name": "feature/new-thing",
  "base_branch": "main"
}

Delete Branch:

DELETE /projects/{id}/repositories/{id}/branches/{name}

Checkout Branch:

POST /projects/{id}/repositories/{id}/checkout
{
  "branch": "feature/new-thing"
}

Working Directory Status

Get Status:

GET /projects/{id}/repositories/{id}/status

Response:

{
  "branch": "main",
  "modified": ["src/main.py", "README.md"],
  "added": ["new-file.txt"],
  "deleted": ["old-file.txt"],
  "untracked": ["temp.log"]
}

Commit Operations

Commit Changes:

POST /projects/{id}/repositories/{id}/commits
{
  "message": "Update greeting",
  "author_name": "User",
  "author_email": "user@example.com",
  "files": ["src/main.py", "README.md"]
}

Remote Operations

Fetch:

POST /projects/{id}/repositories/{id}/fetch

Pull:

POST /projects/{id}/repositories/{id}/pull
{
  "branch": "main",
  "strategy": "merge"
}

Push:

POST /projects/{id}/repositories/{id}/push
{
  "branch": "main"
}

Merge:

POST /projects/{id}/repositories/{id}/merge
{
  "source_branch": "feature/new-thing",
  "target_branch": "main",
  "commit_message": "Merge feature into main"
}

Backend Implementation

Git Command Utilities

Extend src/utils/git_files.py with:

  • get_status(repo_path) - working directory status
  • create_branch(repo_path, name, base) - create new branch
  • delete_branch(repo_path, name) - delete branch
  • checkout_branch(repo_path, name) - switch branch
  • commit_changes(repo_path, files, message, author) - commit files
  • fetch(repo_path) - fetch from remote
  • pull(repo_path, branch) - pull updates
  • push(repo_path, branch) - push changes
  • merge(repo_path, source, target, message) - merge branches

Error Handling

All git operations can fail:

  • Merge conflicts: Return conflict details, require resolution
  • Auth failures: Remote requires authentication
  • Dirty working tree: Can't checkout with uncommitted changes
  • Branch exists: Can't create duplicate branch
  • Nothing to commit: Working tree clean

Security

  • All operations check repository ownership
  • Push/pull requires valid remote URL
  • Commits use authenticated user's identity

Frontend Implementation

Workspace Toolbar

Add git action bar above file viewer:

┌──────────────────────────────────────────────────────┐
│ [Fetch] [Pull] [Push]  │  Branch: [main ▼] [+ New] │
│                        │  [Commit ▼] [Merge ▼]      │
└──────────────────────────────────────────────────────┘

Branch Management

Branch Selector Dropdown:

  • List all branches with current branch highlighted
  • Create new branch option (opens dialog)
  • Delete branch option (with confirmation)

New Branch Dialog:

┌──────────────────────────────┐
│ Create New Branch            │
├──────────────────────────────┤
│ Name: [feature/________]     │
│ Base: [main ▼]               │
│                              │
│ [Create] [Cancel]            │
└──────────────────────────────┘

Working Directory Status

Status Indicators in File Tree:

  • ✏️ Modified file
  • New file
  • 🗑️ Deleted file
  • Untracked file

Commit Panel (appears when files modified):

┌──────────────────────────────┐
│ Changes (3)                  │
├──────────────────────────────┤
│ ✏️ src/main.py               │
│ ✨ new-file.txt              │
│ 🗑️ old-file.txt             │
├──────────────────────────────┤
│ Commit message:              │
│ [____________________]       │
│                              │
│ [Commit to main]             │
└──────────────────────────────┘

Merge Dialog

┌──────────────────────────────┐
│ Merge Branch                 │
├──────────────────────────────┤
│ Source: [feature/xyz ▼]      │
│ Target: main                 │
│                              │
│ Commit message:              │
│ [Merge feature/xyz into main]│
│                              │
│ [Merge] [Cancel]             │
└──────────────────────────────┘

Implementation Order

  1. Backend git utilities - Status, branch, commit, remote operations
  2. Backend API endpoints - All git operation endpoints
  3. Frontend toolbar - Git action buttons
  4. Frontend branch management - Create/delete/checkout
  5. Frontend status display - Modified file indicators
  6. Frontend commit panel - Commit UI
  7. Frontend merge dialog - Merge UI
  8. Integration - Wire everything together
  9. Tests - Backend + frontend tests

State Management

URL State

/projects/:projectId?repo=:repoId&branch=:branch&path=:path

React State

interface GitState {
  currentBranch: string;
  branches: Branch[];
  status: {
    modified: string[];
    added: string[];
    deleted: string[];
    untracked: string[];
  };
  isLoading: boolean;
  lastOperation: string | null;
}

Error Handling

User-Facing Errors

  • "Cannot checkout: uncommitted changes" - Show commit panel
  • "Merge conflict" - Show conflict resolution UI
  • "Push rejected: non-fast-forward" - Suggest pull first
  • "Authentication failed" - Show SSH key settings
  • "Nothing to commit" - Working tree clean

Conflict Resolution (Future)

For now, show error and abort. Later can add:

  • Diff view of conflicts
  • Manual resolution editor
  • Accept ours/theirs buttons

Performance Considerations

  • Status updates: Poll every 5 seconds when viewing workspace
  • Fetch on load: Auto-fetch when opening workspace (optional)
  • Lazy operations: Don't fetch until user clicks fetch/pull
  • Progress indicators: Show for long operations (clone, push, merge)