Kandev Docs

Git Operations

Understand how Kandev manages repositories, worktrees, branches, and review surfaces.

This document describes the architecture for Git operations (Pull, Push, Rebase, Merge, and Abort) 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

OperationDirectionDescription
PullRemote → WorktreeFetch and merge changes from remote for the worktree's branch
PushWorktree → RemotePush local commits to remote
RebaseBase → WorktreeRebase worktree branch onto base branch (rewrites history)
MergeBase → WorktreeMerge base branch into worktree branch (creates merge commit)
Abort-Abort an in-progress merge or rebase

Architecture

Request Flow

flowchart TD
    A["Frontend UI (Git Actions Dropdown)"] --> B["WebSocket Client"]
    B -->|"worktree.pull/push/rebase/merge/abort"| 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/{operation}"| 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:

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

MethodPathDescription
POST/api/v1/git/pullPull from remote
POST/api/v1/git/pushPush to remote
POST/api/v1/git/rebaseRebase onto base branch
POST/api/v1/git/mergeMerge base branch in
POST/api/v1/git/abortAbort merge/rebase

Request/Response Format

Pull Request:

{ "rebase": false }

Push Request:

{ "force": false, "set_upstream": true }

Rebase/Merge Request:

{ "base_branch": "main" }

Abort Request:

{ "operation": "merge" }

Every request also accepts an optional repo subpath for multi-repository task workspaces. Omit it for a single-repository workspace.

Response (all operations):

{
  "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

const { pull, push, rebase, merge, abort, isLoading, error } = useGitOperations(sessionId);

// In component
<Button onClick={() => pull()} disabled={isLoading}>Pull</Button>
<Button onClick={() => rebase("main")} disabled={isLoading}>Rebase</Button>
<Button onClick={() => merge("main")} disabled={isLoading}>Merge</Button>
<Button onClick={() => abort("rebase")} disabled={isLoading}>Abort rebase</Button>

rebase and merge require the base branch as their first argument. In a multi-repository workspace, pass the repository subpath as the optional second argument, for example rebase("main", "kandev").

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
  • hooks/use-git-operations.ts - WebSocket action functions and React hook

On this page