src — git

Module: src-git Cohesion: 0.80 Members: 0

src — git

This document provides a technical overview and usage guide for the src/git/worktree-sessions.ts module, which manages Git worktrees and links them to application-level sessions.


Git Worktree Session Manager

The src/git/worktree-sessions.ts module provides a robust mechanism for managing Git worktrees, enabling developers to work on multiple branches simultaneously within a single repository context. It abstracts the underlying Git commands and maintains a registry of active worktree sessions, facilitating parallel development workflows.

Purpose

The primary goals of this module are:

Core Concepts

WorktreeSession

The WorktreeSession interface defines the structure for tracking an active worktree. Each session represents a specific branch being worked on in an isolated worktree.

export interface WorktreeSession {
  branch: string;        class="hl-cmt">// The Git branch associated with this worktree.
  worktreePath: string;  class="hl-cmt">// The absolute file system path to the worktree directory.
  sessionId: string;     class="hl-cmt">// A unique identifier for this application session (e.g., 'wt-feature-branch-1678886400000').
  createdAt: number;     class="hl-cmt">// Timestamp when the session was created.
}

WorktreeSessionManager (Singleton)

The WorktreeSessionManager class is the central component of this module. It follows the singleton pattern, meaning only one instance of this class can exist at any given time. This ensures consistent state management for all active worktree sessions across the application.

classDiagram
    direction LR
    class WorktreeSessionManager {
        -static instance: WorktreeSessionManager
        -sessions: Map<string, WorktreeSession>
        +static getInstance(): WorktreeSessionManager
        +createWorktreeSession(branch, basePath): WorktreeSession
        +cleanupWorktree(branch): boolean
        +listWorktreeSessions(): WorktreeSession[]
        +getSessionForWorktree(worktreePath): WorktreeSession | undefined
        +isWorktreeActive(branch): boolean
    }
    class WorktreeSession {
        +branch: string
        +worktreePath: string
        +sessionId: string
        +createdAt: number
    }
    WorktreeSessionManager "1" *-- "0..*" WorktreeSession : manages

How It Works

1. Initialization and Singleton Access

The WorktreeSessionManager is initialized lazily via its static getInstance() method. The first call creates the instance, and subsequent calls return the same instance. This ensures global coordination of worktree states.

import { WorktreeSessionManager } from &#39;./git/worktree-sessions.js&#39;;

const manager = WorktreeSessionManager.getInstance();
class="hl-cmt">// manager is now the single, globally accessible instance.

The resetInstance() static method is provided primarily for testing purposes, allowing the singleton to be reset between test runs.

2. Creating Worktree Sessions

The createWorktreeSession(branch: string, basePath: string) method is responsible for:

  1. Path Construction: It determines the worktree's location, typically within a .worktrees subdirectory of the basePath (e.g., basePath/.worktrees/my-feature-branch).
  2. Directory Creation: Ensures the parent directories for the new worktree exist using fs.mkdirSync.
  3. Git Worktree Creation: Executes the git worktree add command.

  1. Session Registration: Upon successful Git worktree creation, a WorktreeSession object is created with a unique sessionId and stored internally in a Map, keyed by the branch name.

3. Managing Active Sessions

The manager maintains an internal Map to keep track of all active worktree sessions.

4. Cleaning Up Worktrees

The cleanupWorktree(branch: string) method handles the removal of a worktree and its associated session:

  1. Session Lookup: It retrieves the WorktreeSession for the specified branch.
  2. Git Worktree Removal: If a session is found, it executes git worktree remove "${session.worktreePath}" --force to delete the worktree from the file system and Git's internal tracking.
  3. Session Deregistration: The session is then removed from the internal sessions Map.

API Reference

Integration Points

This module interacts with the following:

Consumers:

The primary consumer identified is tests/features/basse-features.test.ts, which extensively uses all public methods of WorktreeSessionManager to validate its functionality. This indicates its role as a foundational utility for features requiring isolated Git environments.

Usage Example

import { WorktreeSessionManager } from &#39;./git/worktree-sessions.js&#39;;
import * as path from &#39;path&#39;;
import * as os from &#39;os&#39;;
import * as fs from &#39;fs&#39;;

async function demonstrateWorktreeManagement() {
  const manager = WorktreeSessionManager.getInstance();
  const repoBasePath = path.join(os.tmpdir(), &#39;my-test-repo&#39;);

  class="hl-cmt">// Ensure a dummy git repo exists for demonstration
  if (!fs.existsSync(repoBasePath)) {
    fs.mkdirSync(repoBasePath, { recursive: true });
    execSync(&#39;git init&#39;, { cwd: repoBasePath });
    execSync(&#39;git config user.email "test@example.com"&#39;, { cwd: repoBasePath });
    execSync(&#39;git config user.name "Test User"&#39;, { cwd: repoBasePath });
    fs.writeFileSync(path.join(repoBasePath, &#39;README.md&#39;), &#39;# My Test Repo&#39;);
    execSync(&#39;git add . && git commit -m "Initial commit"&#39;, { cwd: repoBasePath });
    execSync(&#39;git branch feature-a&#39;, { cwd: repoBasePath });
    execSync(&#39;git branch feature-b&#39;, { cwd: repoBasePath });
  }

  console.log(&#39;--- Creating Worktree for feature-a ---&#39;);
  try {
    const sessionA = manager.createWorktreeSession(&#39;feature-a&#39;, repoBasePath);
    console.log(`Created session for branch: ${sessionA.branch} at ${sessionA.worktreePath}`);
  } catch (error) {
    console.error(&#39;Failed to create worktree for feature-a:&#39;, error.message);
  }

  console.log(&#39;\n--- Creating Worktree for feature-b ---&#39;);
  try {
    const sessionB = manager.createWorktreeSession(&#39;feature-b&#39;, repoBasePath);
    console.log(`Created session for branch: ${sessionB.branch} at ${sessionB.worktreePath}`);
  } catch (error) {
    console.error(&#39;Failed to create worktree for feature-b:&#39;, error.message);
  }

  console.log(&#39;\n--- Listing active sessions ---&#39;);
  const activeSessions = manager.listWorktreeSessions();
  activeSessions.forEach(s => console.log(`- Branch: ${s.branch}, Path: ${s.worktreePath}`));

  console.log(&#39;\n--- Checking if feature-a is active ---&#39;);
  console.log(`Is feature-a active? ${manager.isWorktreeActive(&#39;feature-a&#39;)}`);

  console.log(&#39;\n--- Cleaning up worktree for feature-a ---&#39;);
  const cleanedUp = manager.cleanupWorktree(&#39;feature-a&#39;);
  console.log(`Cleaned up feature-a? ${cleanedUp}`);

  console.log(&#39;\n--- Listing active sessions after cleanup ---&#39;);
  manager.listWorktreeSessions().forEach(s => console.log(`- Branch: ${s.branch}, Path: ${s.worktreePath}`));

  class="hl-cmt">// Clean up the remaining worktree and the dummy repo
  manager.cleanupWorktree(&#39;feature-b&#39;);
  execSync(`rm -rf "${repoBasePath}"`);
  console.log(&#39;\nDemonstration complete. Temporary repo removed.&#39;);
}

class="hl-cmt">// Note: execSync is imported from &#39;child_process&#39; in the actual module.
class="hl-cmt">// For this example, we&#39;ll assume it&#39;s available.
import { execSync } from &#39;child_process&#39;;
demonstrateWorktreeManagement();