Files
headquarter/openspec/changes/archive/2026-05-19-git-history-visualization/specs/spec.md
T
Fusion 6807f449b7 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 ✓
2026-05-19 13:43:49 +02:00

214 lines
4.7 KiB
Markdown

# Git History Visualization Specification
## Requirements
### Functional Requirements
1. **View Commit History**: Display all commits in a repository
2. **Graph Visualization**: Show commits as nodes with branch/merge lines
3. **List View**: Alternative linear view of commits
4. **Commit Details**: Click to view full commit info and diff
5. **Branch Display**: Show branch names on commits
6. **Tag Display**: Show tags on commits
7. **View Toggle**: Switch between graph and list views
### Non-Functional Requirements
1. **Performance**: Load first 100 commits in < 2 seconds
2. **Responsiveness**: Graph should render smoothly up to 500 commits
3. **Compatibility**: Work with bare repositories and mirror clones
4. **Read-only**: No write operations to repository
## API Specification
### GET /projects/{project_id}/repositories/{repo_id}/history
Retrieve commit history for a repository.
**Query Parameters:**
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| view | string | "graph" | "graph" or "list" |
| branch | string | null | Filter by branch name |
| limit | integer | 100 | Max commits to return |
| offset | integer | 0 | Skip first N commits |
**Response 200:**
```json
{
"commits": [
{
"hash": "full-sha-hash",
"short_hash": "abc1234",
"parents": ["parent-hash-1", "parent-hash-2"],
"author": "John Doe",
"email": "john@example.com",
"date": "2026-05-19",
"timestamp": 1716123456,
"message": "feat: add new feature",
"branches": ["main"],
"tags": []
}
],
"branches": ["main", "develop", "feature/x"],
"total_commits": 250,
"graph_data": {
"nodes": [
{
"hash": "abc1234",
"x": 0,
"y": 0,
"column": 0
}
],
"edges": [
{
"from_hash": "abc1234",
"to_hash": "def5678",
"type": "parent"
}
]
}
}
```
### GET /projects/{project_id}/repositories/{repo_id}/commits/{commit_hash}
Get detailed information about a specific commit.
**Response 200:**
```json
{
"hash": "full-sha-hash",
"short_hash": "abc1234",
"parents": ["parent-hash"],
"author": "John Doe",
"email": "john@example.com",
"date": "2026-05-19",
"timestamp": 1716123456,
"message": "feat: add new feature",
"body": "Detailed description here",
"stats": {
"files_changed": 3,
"insertions": 45,
"deletions": 12
},
"files": [
{
"path": "src/main.py",
"change_type": "modified",
"insertions": 20,
"deletions": 5,
"diff": "diff content here"
}
]
}
```
## Frontend Components
### GitHistoryPage
Main page component that orchestrates the view.
### GraphView
SVG-based commit graph visualization.
**Props:**
- `commits`: Commit[]
- `graphData`: GraphData
- `selectedCommit`: string | null
- `onCommitSelect`: (hash: string) => void
### ListView
Linear commit list.
**Props:**
- `commits`: Commit[]
- `selectedCommit`: string | null
- `onCommitSelect`: (hash: string) => void
### CommitDetails
Panel showing commit details and diff.
**Props:**
- `commit`: CommitDetail | null
### DiffViewer
Component to display git diff with syntax highlighting.
**Props:**
- `files`: FileChange[]
## Data Models
### Commit
```typescript
interface Commit {
hash: string;
short_hash: string;
parents: string[];
author: string;
email: string;
date: string;
timestamp: number;
message: string;
branches: string[];
tags: string[];
}
```
### CommitDetail
```typescript
interface CommitDetail extends Commit {
body: string;
stats: {
files_changed: number;
insertions: number;
deletions: number;
};
files: FileChange[];
}
```
### FileChange
```typescript
interface FileChange {
path: string;
change_type: "added" | "modified" | "deleted" | "renamed";
insertions: number;
deletions: number;
diff: string;
}
```
## URL Structure
```
/projects/:projectId/repositories/:repoId/history
```
## Error Codes
| Error Code | Description | User Message |
|------------|-------------|--------------|
| REPO_EMPTY | Repository has no commits | "This repository has no commits yet" |
| GIT_ERROR | Git command failed | "Failed to load repository history" |
| COMMIT_NOT_FOUND | Commit hash not found | "Commit not found" |
| INVALID_BRANCH | Branch doesn't exist | "Branch not found" |
## Testing Strategy
### Backend Tests
- Test git log parsing with various repo structures
- Test commit detail extraction
- Test error handling for empty repos
### Frontend Tests
- Test graph rendering with sample data
- Test list view rendering
- Test commit selection and details display
- Test view toggle
### Integration Tests
- End-to-end flow: load history → select commit → view details