refactor: simplify worktree management by removing legacy API

- Remove legacy worktree API usage and related state
- Add Manage Branches button in the Git header for quick access
- Introduce worktree status utilities to derive root branch hints
This commit is contained in:
Bohdan Triapitsyn
2026-02-06 12:38:09 +02:00
parent 2f336a0716
commit 0503f51357
26 changed files with 504 additions and 1450 deletions
+3 -43
View File
@@ -2171,42 +2171,12 @@ export async function handleBridgeMessage(message: BridgeRequest, ctx?: BridgeCo
}
case 'api:git/worktrees': {
const { directory, method, path: worktreePath, branch, createBranch, force } = (payload || {}) as {
directory?: string;
method?: string;
path?: string;
branch?: string;
createBranch?: boolean;
force?: boolean;
};
const { directory } = (payload || {}) as { directory?: string };
if (!directory) {
return { id, type, success: false, error: 'Directory is required' };
}
const normalizedMethod = typeof method === 'string' ? method.toUpperCase() : 'GET';
if (normalizedMethod === 'GET') {
const worktrees = await gitService.listGitWorktrees(directory);
return { id, type, success: true, data: worktrees };
}
if (normalizedMethod === 'POST') {
if (!worktreePath || !branch) {
return { id, type, success: false, error: 'Path and branch are required' };
}
const result = await gitService.addGitWorktree(directory, worktreePath, branch, createBranch);
return { id, type, success: true, data: result };
}
if (normalizedMethod === 'DELETE') {
if (!worktreePath) {
return { id, type, success: false, error: 'Path is required' };
}
const result = await gitService.removeGitWorktree(directory, worktreePath, force);
return { id, type, success: true, data: result };
}
return { id, type, success: false, error: `Unsupported method: ${normalizedMethod}` };
const worktrees = await gitService.listGitWorktrees(directory);
return { id, type, success: true, data: worktrees };
}
case 'api:git/diff': {
@@ -2438,16 +2408,6 @@ export async function handleBridgeMessage(message: BridgeRequest, ctx?: BridgeCo
return { id, type, success: false, error: `Unsupported method: ${normalizedMethod}` };
}
case 'api:git/ignore-openchamber': {
// LEGACY_WORKTREES: only needed for <project>/.openchamber era. Safe to remove after legacy support dropped.
const { directory } = (payload || {}) as { directory?: string };
if (!directory) {
return { id, type, success: false, error: 'Directory is required' };
}
await gitService.ensureOpenChamberIgnored(directory);
return { id, type, success: true, data: { success: true } };
}
default:
return { id, type, success: false, error: `Unknown message type: ${type}` };
}
-71
View File
@@ -694,48 +694,6 @@ export async function getAvailableBranchesForWorktree(directory: string): Promis
return availableBranches;
}
/**
* Add a new worktree
*/
export async function addGitWorktree(
directory: string,
worktreePath: string,
branch: string,
createBranch = false
): Promise<{ success: boolean; path: string; branch: string }> {
const args = ['worktree', 'add'];
if (createBranch) {
args.push('-b', branch, worktreePath);
} else {
args.push(worktreePath, branch);
}
const result = await execGit(args, directory);
return {
success: result.exitCode === 0,
path: worktreePath,
branch,
};
}
/**
* Remove a worktree
*/
export async function removeGitWorktree(
directory: string,
worktreePath: string,
force = false
): Promise<{ success: boolean }> {
const args = ['worktree', 'remove'];
if (force) args.push('--force');
args.push(worktreePath);
const result = await execGit(args, directory);
return { success: result.exitCode === 0 };
}
// ============== Diff Operations ==============
/**
@@ -1361,32 +1319,3 @@ export async function setGitIdentity(
return { success: true };
}
// ============== Utility Operations ==============
/**
* Ensure .openchamber is in git exclude
*/
export async function ensureOpenChamberIgnored(directory: string): Promise<void> {
// LEGACY_WORKTREES: only needed for <project>/.openchamber era. Safe to remove after legacy support dropped.
const excludeFile = path.join(directory, '.git', 'info', 'exclude');
try {
const uri = vscode.Uri.file(excludeFile);
let content = '';
try {
const bytes = await vscode.workspace.fs.readFile(uri);
content = Buffer.from(bytes).toString('utf8');
} catch {
// File doesn't exist, we'll create it
}
if (!content.includes('.openchamber')) {
const newContent = content.trimEnd() + '\n.openchamber\n';
await vscode.workspace.fs.writeFile(uri, Buffer.from(newContent, 'utf8'));
}
} catch (error) {
console.warn('[GitService] Failed to update git exclude:', error);
}
}