145 lines
4.1 KiB
Markdown
145 lines
4.1 KiB
Markdown
# Git Operations for Worktrees
|
|
|
|
This document describes the architecture for Git operations (Pull, Push, Rebase, Merge) on worktrees in Kandev.
|
|
|
|
## Overview
|
|
|
|
Git operations are executed **in agentctl**, not in the backend. This ensures consistent behavior whether running locally or in Docker/remote environments. The backend acts as a proxy, forwarding requests from the frontend WebSocket to agentctl's HTTP API.
|
|
|
|
## Supported Operations
|
|
|
|
| Operation | Direction | Description |
|
|
|-----------|-----------|-------------|
|
|
| **Pull** | Remote → Worktree | Fetch and merge changes from remote for the worktree's branch |
|
|
| **Push** | Worktree → Remote | Push local commits to remote |
|
|
| **Rebase** | Base → Worktree | Rebase worktree branch onto base branch (rewrites history) |
|
|
| **Merge** | Base → Worktree | Merge base branch into worktree branch (creates merge commit) |
|
|
| **Abort** | - | Abort an in-progress merge or rebase |
|
|
|
|
## Architecture
|
|
|
|
### Request Flow
|
|
|
|
```mermaid
|
|
flowchart TD
|
|
A["Frontend UI (Git Actions Dropdown)"] --> B["WebSocket Client"]
|
|
B -->|"worktree.pull/push/rebase/merge"| C["Backend WebSocket Gateway"]
|
|
C --> D["Git Handlers"]
|
|
D -->|"GetExecutionBySessionID"| E["Lifecycle Manager"]
|
|
E --> F["AgentExecution"]
|
|
F --> G["agentctl.Client"]
|
|
G -->|"HTTP POST /api/v1/git/op"| H["agentctl HTTP API"]
|
|
H --> I["Git Command Execution"]
|
|
I -->|"exec.Command git"| J["Worktree Directory"]
|
|
J --> K["HTTP Response"]
|
|
K --> L["Backend Handler"]
|
|
L --> M["WebSocket Response"]
|
|
M --> N["Frontend"]
|
|
```
|
|
|
|
### Notification Flow (Git Status Updates)
|
|
|
|
After any git operation, the workspace state changes. Updates flow through the event bus:
|
|
|
|
```mermaid
|
|
flowchart TD
|
|
A["agentctl WorkspaceTracker"] -->|"git_status message"| B["Backend StreamManager"]
|
|
B -->|"OnGitStatus callback"| C["EventPublisher.PublishGitStatus"]
|
|
C --> D["Event Bus"]
|
|
D --> E["TaskNotificationBridge"]
|
|
E --> F["Hub.BroadcastToSession"]
|
|
F --> G["Frontend WebSocket"]
|
|
G --> H["Zustand Store update"]
|
|
```
|
|
|
|
## agentctl API
|
|
|
|
### Endpoints
|
|
|
|
| Method | Path | Description |
|
|
|--------|------|-------------|
|
|
| POST | `/api/v1/git/pull` | Pull from remote |
|
|
| POST | `/api/v1/git/push` | Push to remote |
|
|
| POST | `/api/v1/git/rebase` | Rebase onto base branch |
|
|
| POST | `/api/v1/git/merge` | Merge base branch in |
|
|
| POST | `/api/v1/git/abort` | Abort merge/rebase |
|
|
|
|
### Request/Response Format
|
|
|
|
**Pull Request:**
|
|
```json
|
|
{ "rebase": false }
|
|
```
|
|
|
|
**Push Request:**
|
|
```json
|
|
{ "force": false, "set_upstream": true }
|
|
```
|
|
|
|
**Rebase/Merge Request:**
|
|
```json
|
|
{ "base_branch": "main" }
|
|
```
|
|
|
|
**Abort Request:**
|
|
```json
|
|
{ "operation": "merge" }
|
|
```
|
|
|
|
**Response (all operations):**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"operation": "pull",
|
|
"output": "Already up to date.",
|
|
"error": null,
|
|
"conflict_files": []
|
|
}
|
|
```
|
|
|
|
## Locking
|
|
|
|
A per-instance mutex in agentctl prevents concurrent git operations on the same worktree. If an operation is already running, new requests return HTTP 409 Conflict.
|
|
|
|
## Conflict Handling
|
|
|
|
- **Rebase conflicts**: Automatically aborted (`git rebase --abort`), conflict files returned
|
|
- **Merge conflicts**: Left in place for user/agent resolution, conflict files returned
|
|
- **Abort endpoint**: Allows manual abort of conflicted merge/rebase
|
|
|
|
## Frontend Integration
|
|
|
|
### WebSocket Actions
|
|
|
|
- `worktree.pull` - Pull from remote
|
|
- `worktree.push` - Push to remote
|
|
- `worktree.rebase` - Rebase onto base
|
|
- `worktree.merge` - Merge base branch
|
|
- `worktree.abort` - Abort operation
|
|
|
|
### Hook Usage
|
|
|
|
```typescript
|
|
const { pull, push, rebase, merge, isLoading, error } = useGitOperations(sessionId);
|
|
|
|
// In component
|
|
<Button onClick={() => pull()} disabled={isLoading}>Pull</Button>
|
|
```
|
|
|
|
## Files
|
|
|
|
### agentctl
|
|
- `server/api/git.go` - HTTP handlers
|
|
- `server/process/git.go` - Git command execution
|
|
- `client/git.go` - Client methods
|
|
|
|
### Backend
|
|
- `internal/agent/handlers/git_handlers.go` - WebSocket handlers
|
|
- `pkg/websocket/actions.go` - Action constants
|
|
|
|
### Frontend
|
|
- `lib/types/backend.ts` - TypeScript types
|
|
- `lib/ws/actions/git.ts` - WebSocket action functions
|
|
- `lib/hooks/useGitOperations.ts` - React hook
|
|
|