1- import { exec } from "child_process" ;
2- import { promisify } from "util" ;
31import * as fs from "fs" ;
42import * as path from "path" ;
53import type { Config } from "./config" ;
6-
7- const execAsync = promisify ( exec ) ;
4+ import { execAsync } from "./utils/disposableExec" ;
85
96export interface WorktreeResult {
107 success : boolean ;
@@ -17,9 +14,10 @@ export interface CreateWorktreeOptions {
1714}
1815
1916export async function listLocalBranches ( projectPath : string ) : Promise < string [ ] > {
20- const { stdout } = await execAsync (
17+ using proc = execAsync (
2118 `git -C "${ projectPath } " for-each-ref --format="%(refname:short)" refs/heads`
2219 ) ;
20+ const { stdout } = await proc . result ;
2321 return stdout
2422 . split ( "\n" )
2523 . map ( ( line ) => line . trim ( ) )
@@ -29,7 +27,8 @@ export async function listLocalBranches(projectPath: string): Promise<string[]>
2927
3028async function getCurrentBranch ( projectPath : string ) : Promise < string | null > {
3129 try {
32- const { stdout } = await execAsync ( `git -C "${ projectPath } " rev-parse --abbrev-ref HEAD` ) ;
30+ using proc = execAsync ( `git -C "${ projectPath } " rev-parse --abbrev-ref HEAD` ) ;
31+ const { stdout } = await proc . result ;
3332 const branch = stdout . trim ( ) ;
3433 if ( ! branch || branch === "HEAD" ) {
3534 return null ;
@@ -108,19 +107,26 @@ export async function createWorktree(
108107
109108 // If branch already exists locally, reuse it instead of creating a new one
110109 if ( localBranches . includes ( branchName ) ) {
111- await execAsync ( `git -C "${ projectPath } " worktree add "${ workspacePath } " "${ branchName } "` ) ;
110+ using proc = execAsync (
111+ `git -C "${ projectPath } " worktree add "${ workspacePath } " "${ branchName } "`
112+ ) ;
113+ await proc . result ;
112114 return { success : true , path : workspacePath } ;
113115 }
114116
115117 // Check if branch exists remotely (origin/<branchName>)
116- const { stdout : remoteBranchesRaw } = await execAsync ( `git -C "${ projectPath } " branch -a` ) ;
118+ using remoteBranchesProc = execAsync ( `git -C "${ projectPath } " branch -a` ) ;
119+ const { stdout : remoteBranchesRaw } = await remoteBranchesProc . result ;
117120 const branchExists = remoteBranchesRaw
118121 . split ( "\n" )
119122 . map ( ( b ) => b . trim ( ) . replace ( / ^ ( \* ) \s + / , "" ) )
120123 . some ( ( b ) => b === branchName || b === `remotes/origin/${ branchName } ` ) ;
121124
122125 if ( branchExists ) {
123- await execAsync ( `git -C "${ projectPath } " worktree add "${ workspacePath } " "${ branchName } "` ) ;
126+ using proc = execAsync (
127+ `git -C "${ projectPath } " worktree add "${ workspacePath } " "${ branchName } "`
128+ ) ;
129+ await proc . result ;
124130 return { success : true , path : workspacePath } ;
125131 }
126132
@@ -131,9 +137,10 @@ export async function createWorktree(
131137 } ;
132138 }
133139
134- await execAsync (
140+ using proc = execAsync (
135141 `git -C "${ projectPath } " worktree add -b "${ branchName } " "${ workspacePath } " "${ normalizedTrunkBranch } "`
136142 ) ;
143+ await proc . result ;
137144
138145 return { success : true , path : workspacePath } ;
139146 } catch ( error ) {
@@ -149,9 +156,10 @@ export async function removeWorktree(
149156) : Promise < WorktreeResult > {
150157 try {
151158 // Remove the worktree (from the main repository context)
152- await execAsync (
159+ using proc = execAsync (
153160 `git -C "${ projectPath } " worktree remove "${ workspacePath } " ${ options . force ? "--force" : "" } `
154161 ) ;
162+ await proc . result ;
155163 return { success : true } ;
156164 } catch ( error ) {
157165 const message = error instanceof Error ? error . message : String ( error ) ;
@@ -161,7 +169,8 @@ export async function removeWorktree(
161169
162170export async function pruneWorktrees ( projectPath : string ) : Promise < WorktreeResult > {
163171 try {
164- await execAsync ( `git -C "${ projectPath } " worktree prune` ) ;
172+ using proc = execAsync ( `git -C "${ projectPath } " worktree prune` ) ;
173+ await proc . result ;
165174 return { success : true } ;
166175 } catch ( error ) {
167176 const message = error instanceof Error ? error . message : String ( error ) ;
@@ -190,7 +199,8 @@ export async function moveWorktree(
190199 }
191200
192201 // Move the worktree using git (from the main repository context)
193- await execAsync ( `git -C "${ projectPath } " worktree move "${ oldPath } " "${ newPath } "` ) ;
202+ using proc = execAsync ( `git -C "${ projectPath } " worktree move "${ oldPath } " "${ newPath } "` ) ;
203+ await proc . result ;
194204 return { success : true , path : newPath } ;
195205 } catch ( error ) {
196206 const message = error instanceof Error ? error . message : String ( error ) ;
@@ -200,7 +210,8 @@ export async function moveWorktree(
200210
201211export async function listWorktrees ( projectPath : string ) : Promise < string [ ] > {
202212 try {
203- const { stdout } = await execAsync ( `git -C "${ projectPath } " worktree list --porcelain` ) ;
213+ using proc = execAsync ( `git -C "${ projectPath } " worktree list --porcelain` ) ;
214+ const { stdout } = await proc . result ;
204215 const worktrees : string [ ] = [ ] ;
205216 const lines = stdout . split ( "\n" ) ;
206217
@@ -223,7 +234,8 @@ export async function listWorktrees(projectPath: string): Promise<string[]> {
223234
224235export async function isGitRepository ( projectPath : string ) : Promise < boolean > {
225236 try {
226- await execAsync ( `git -C "${ projectPath } " rev-parse --git-dir` ) ;
237+ using proc = execAsync ( `git -C "${ projectPath } " rev-parse --git-dir` ) ;
238+ await proc . result ;
227239 return true ;
228240 } catch {
229241 return false ;
@@ -238,7 +250,8 @@ export async function isGitRepository(projectPath: string): Promise<boolean> {
238250export async function getMainWorktreeFromWorktree ( worktreePath : string ) : Promise < string | null > {
239251 try {
240252 // Get the worktree list from the worktree itself
241- const { stdout } = await execAsync ( `git -C "${ worktreePath } " worktree list --porcelain` ) ;
253+ using proc = execAsync ( `git -C "${ worktreePath } " worktree list --porcelain` ) ;
254+ const { stdout } = await proc . result ;
242255 const lines = stdout . split ( "\n" ) ;
243256
244257 // The first worktree in the list is always the main worktree
0 commit comments