feat: add repository workspace as default project view
- Create git file utilities (list_tree, get_file_content, list_branches, commit_file) - Add file browsing API endpoints (list, content, branches, update) - Create RepoWorkspace page with sidebar + main content layout - Add FileTree component with directory navigation - Add FileViewer component for viewing file contents - Update project list to link to workspace - Add workspace CSS styles - Update router with workspace route Quality gates: ruff ✓, mypy ✓, typecheck ✓, build ✓
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
# Git History Visualization - Design
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
User → Frontend → Backend API → Git CLI → Repository
|
||||
↓
|
||||
Commit Data
|
||||
↓
|
||||
Frontend Rendering
|
||||
```
|
||||
|
||||
## Backend Design
|
||||
|
||||
### Git History Extraction
|
||||
|
||||
Use `git log --graph` with custom format to get structured data:
|
||||
|
||||
```bash
|
||||
git log --all --graph --format="%H|%P|%an|%ae|%at|%s" --date=short
|
||||
```
|
||||
|
||||
This gives us:
|
||||
- Commit hash
|
||||
- Parent hashes
|
||||
- Author name
|
||||
- Author email
|
||||
- Author timestamp
|
||||
- Subject line
|
||||
|
||||
### API Endpoints
|
||||
|
||||
#### GET /projects/{project_id}/repositories/{repo_id}/history
|
||||
|
||||
**Query Parameters:**
|
||||
- `view`: "graph" or "list" (default: "graph")
|
||||
- `branch`: specific branch to filter (optional)
|
||||
- `limit`: max commits to return (default: 100)
|
||||
|
||||
**Response (Graph View):**
|
||||
```json
|
||||
{
|
||||
"commits": [
|
||||
{
|
||||
"hash": "abc123...",
|
||||
"short_hash": "abc123",
|
||||
"parents": ["def456...", "ghi789..."],
|
||||
"author": "John Doe",
|
||||
"email": "john@example.com",
|
||||
"date": "2026-05-19",
|
||||
"timestamp": 1716123456,
|
||||
"message": "feat: add new feature",
|
||||
"branches": ["main", "feature-branch"],
|
||||
"tags": ["v1.0.0"]
|
||||
}
|
||||
],
|
||||
"branches": ["main", "develop", "feature-branch"],
|
||||
"graph_data": {
|
||||
"columns": 3,
|
||||
"rows": [
|
||||
{
|
||||
"commit_hash": "abc123...",
|
||||
"column": 0,
|
||||
"connections": [
|
||||
{"from_column": 0, "to_column": 1, "type": "merge"}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### GET /projects/{project_id}/repositories/{repo_id}/commits/{commit_hash}
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"hash": "abc123...",
|
||||
"short_hash": "abc123",
|
||||
"parents": ["def456..."],
|
||||
"author": "John Doe",
|
||||
"email": "john@example.com",
|
||||
"date": "2026-05-19",
|
||||
"timestamp": 1716123456,
|
||||
"message": "feat: add new feature\n\nDetailed description here",
|
||||
"stats": {
|
||||
"files_changed": 3,
|
||||
"insertions": 45,
|
||||
"deletions": 12
|
||||
},
|
||||
"diff": "diff --git a/file.txt b/file.txt\n..."
|
||||
}
|
||||
```
|
||||
|
||||
## Frontend Design
|
||||
|
||||
### Page Layout
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ Repository Name > History [Graph] [List] │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ ┌──────────────────┐ ┌──────────────────────────────┐ │
|
||||
│ │ │ │ │ │
|
||||
│ │ Graph/List │ │ Commit Details │ │
|
||||
│ │ View │ │ (message, author, │ │
|
||||
│ │ │ │ diff) │ │
|
||||
│ │ │ │ │ │
|
||||
│ └──────────────────┘ └──────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Graph View
|
||||
|
||||
- SVG-based rendering
|
||||
- Commits shown as circles
|
||||
- Lines connect commits (straight or curved)
|
||||
- Branch labels shown inline
|
||||
- Color coding for different branches
|
||||
- Click to select commit
|
||||
|
||||
### List View
|
||||
|
||||
- Linear list of commits
|
||||
- Each row: hash, message, author, date
|
||||
- Expandable for details
|
||||
- Click to select commit
|
||||
|
||||
### Commit Details Panel
|
||||
|
||||
- Header: Commit message, author, date
|
||||
- Stats: Files changed, insertions, deletions
|
||||
- Diff view: Syntax highlighted changes
|
||||
|
||||
## Data Flow
|
||||
|
||||
1. User navigates to repository history page
|
||||
2. Frontend fetches history data from backend
|
||||
3. Backend executes git commands on bare repo
|
||||
4. Backend parses output into structured JSON
|
||||
5. Frontend renders graph or list based on user preference
|
||||
6. User clicks commit → Frontend fetches commit details
|
||||
7. Backend executes `git show` for specific commit
|
||||
8. Frontend displays details panel with diff
|
||||
|
||||
## Error Handling
|
||||
|
||||
- **Empty repository**: Show "No commits yet" message
|
||||
- **Git command failure**: Show error with retry button
|
||||
- **Large repositories**: Implement pagination/lazy loading
|
||||
- **Binary files in diff**: Show "Binary file changed" instead of diff
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
- **Pagination**: Load commits in batches (100 at a time)
|
||||
- **Lazy loading**: Load diff only when commit is selected
|
||||
- **Caching**: Cache history data for 30 seconds
|
||||
- **Graph complexity**: Limit graph to first 500 commits for performance
|
||||
Reference in New Issue
Block a user