When merge_and_push failed at the push step, the local defaultBranch ref was left pointing at the merge commit. This made the three-dot diff (defaultBranch...initiativeBranch) return empty because main already contained all changes — causing the review tab to show "no changes." Now mergeBranch returns the previous ref, and approveInitiative restores it on push failure. Also repaired the corrupted clone state.
98 lines
3.3 KiB
TypeScript
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>;
|
|
}
|