Files
Codewalkers/apps/server/git/branch-manager.ts
Lukas May 28521e1c20 chore: merge main into cw/small-change-flow
Integrates main branch changes (headquarters dashboard, task retry count,
agent prompt persistence, remote sync improvements) with the initiative's
errand agent feature. Both features coexist in the merged result.

Key resolutions:
- Schema: take main's errands table (nullable projectId, no conflictFiles,
  with errandsRelations); migrate to 0035_faulty_human_fly
- Router: keep both errandProcedures and headquartersProcedures
- Errand prompt: take main's simpler version (no question-asking flow)
- Manager: take main's status check (running|idle only, no waiting_for_input)
- Tests: update to match removed conflictFiles field and undefined vs null
2026-03-06 16:48:12 +01:00

98 lines
3.3 KiB
TypeScript

/**
* BranchManager Port Interface
*
* Manages branch-level git operations (create, merge, diff, delete)
* across project clones. Works directly on branches without requiring
* a worktree to be checked out.
*/
import type { MergeResult, MergeabilityResult, BranchCommit } from './types.js';
export interface BranchManager {
/**
* Ensure a branch exists. Creates it from baseBranch if it doesn't.
* Idempotent — no-op if the branch already exists.
*/
ensureBranch(repoPath: string, branch: string, baseBranch: string): Promise<void>;
/**
* Merge sourceBranch into targetBranch.
* Uses an ephemeral worktree for merge safety.
* Returns conflict info if merge fails.
*/
mergeBranch(repoPath: string, sourceBranch: string, targetBranch: string): Promise<MergeResult>;
/**
* Get the raw unified diff between two branches.
* Uses three-dot diff (baseBranch...headBranch) to show changes
* introduced by headBranch since it diverged from baseBranch.
*/
diffBranches(repoPath: string, baseBranch: string, headBranch: string): Promise<string>;
/**
* Delete a branch. No-op if the branch doesn't exist.
*/
deleteBranch(repoPath: string, branch: string): Promise<void>;
/**
* Check if a branch exists in the repository.
*/
branchExists(repoPath: string, branch: string): Promise<boolean>;
/**
* Check if a branch exists as a remote tracking branch (origin/<branch>).
* Useful for validating branch names against what the remote has,
* since local branches may not include all remote branches.
*/
remoteBranchExists(repoPath: string, branch: string): Promise<boolean>;
/**
* List commits that headBranch has but baseBranch doesn't.
* Used for commit-level navigation in code review.
*/
listCommits(repoPath: string, baseBranch: string, headBranch: string): Promise<BranchCommit[]>;
/**
* Get the raw unified diff for a single commit.
*/
diffCommit(repoPath: string, commitHash: string): Promise<string>;
/**
* Get the merge base (common ancestor) of two branches.
* Returns the commit hash of the merge base.
*/
getMergeBase(repoPath: string, branch1: string, branch2: string): Promise<string>;
/**
* Push a branch to a remote.
* Defaults to 'origin' if no remote specified.
*/
pushBranch(repoPath: string, branch: string, remote?: string): Promise<void>;
/**
* Dry-run merge check — determines if sourceBranch can be cleanly merged
* into targetBranch without actually performing the merge.
* Uses `git merge-tree --write-tree` (git 2.38+).
*/
checkMergeability(repoPath: string, sourceBranch: string, targetBranch: string): Promise<MergeabilityResult>;
/**
* Fetch all refs from a remote.
* Defaults to 'origin' if no remote specified.
*/
fetchRemote(repoPath: string, remote?: string): Promise<void>;
/**
* Fast-forward a local branch to match its remote-tracking counterpart.
* No-op if already up to date. Throws if fast-forward is not possible
* (i.e. the branches have diverged).
*/
fastForwardBranch(repoPath: string, branch: string, remote?: string): Promise<void>;
/**
* Force-update a branch ref to point at a specific commit.
* Used to roll back a merge when a subsequent push fails.
*/
updateRef(repoPath: string, branch: string, commitHash: string): Promise<void>;
}