feat: add commit panel and file status indicators to repo workspace
- Add CommitPanel component for viewing changed files and committing - Show file status indicators (M/A/D/?) in file tree - Integrate git status with workspace for real-time updates - Add CSS styles for commit panel and status badges Part of git-control change implementation.
This commit is contained in:
@@ -0,0 +1,273 @@
|
||||
# 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:
|
||||
```json
|
||||
{
|
||||
"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
|
||||
```typescript
|
||||
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)
|
||||
Reference in New Issue
Block a user