# 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
