Files
XCOpenCodeWeb/web/server/lib/git/DOCUMENTATION.md

8.1 KiB

Git Module Documentation

Purpose

This module provides Git repository operations for the web server runtime, including repository management, branch/worktree operations, status/diff queries, commit handling, and merge/rebase workflows.

Entrypoints and structure

  • packages/web/server/lib/git/: Git module directory containing all Git-related functionality.
    • index.js: Public API entry point imported by packages/web/server/index.js.
    • service.js: Core Git operations (repository, branch, worktree, commit, merge/rebase, status/diff, log).
    • credentials.js: Git credentials management.
    • identity-storage.js: Git identity (user.name, user.email) storage.

Public API

The following functions are exported and used by the web server:

Repository Operations

  • isGitRepository(directory): Check if a directory is a Git repository.
  • getGlobalIdentity(): Get global Git user.name, user.email, and core.sshCommand.
  • getCurrentIdentity(directory): Get local Git identity (fallback to global if not set locally).
  • hasLocalIdentity(directory): Check if local Git identity is configured.
  • setLocalIdentity(directory, profile): Set local Git identity (userName, userEmail, authType, sshKey/host).
  • getRemoteUrl(directory, remoteName): Get URL for a specific remote.

Status and Diff Operations

  • getStatus(directory): Get comprehensive Git status including current branch, tracking, ahead/behind, file changes, diff stats, merge/rebase state.
  • getDiff(directory, { path, staged, contextLines }): Get diff output for files or entire working tree.
  • getRangeDiff(directory, { base, head, path, contextLines }): Get diff between two refs.
  • getRangeFiles(directory, { base, head }): Get list of changed files between two refs.
  • getFileDiff(directory, { path, staged }): Get original and modified file contents for a single file (handles images as data URLs).
  • collectDiffs(directory, files): Collect diff output for multiple files.
  • revertFile(directory, filePath): Revert a file to HEAD state.

Branch Operations

  • getBranches(directory): Get list of local and remote branches (filtered to active remote branches).
  • createBranch(directory, branchName, options): Create and checkout a new branch.
  • checkoutBranch(directory, branchName): Checkout an existing branch.
  • deleteBranch(directory, branch, options): Delete a branch (supports force flag).
  • renameBranch(directory, oldName, newName): Rename a branch and preserve upstream tracking.
  • getRemotes(directory): Get list of configured remotes.

Worktree Operations

  • getWorktrees(directory): List all git worktrees for a repository.
  • validateWorktreeCreate(directory, input): Validate worktree creation parameters (mode, branchName, startRef, upstream config).
  • createWorktree(directory, input): Create a new worktree (supports 'new' and 'existing' modes, upstream setup).
  • removeWorktree(directory, input): Remove a worktree (optionally delete local branch).
  • isLinkedWorktree(directory): Check if directory is a linked worktree (not primary).

Commit and Remote Operations

  • commit(directory, message, options): Create a commit (supports addAll or specific files).
  • pull(directory, options): Pull changes from remote.
  • push(directory, options): Push changes to remote (auto-sets upstream if needed).
  • fetch(directory, options): Fetch changes from remote.
  • deleteRemoteBranch(directory, options): Delete a remote branch.

Log Operations

  • getLog(directory, options): Get commit history with stats (supports maxCount, from, to, file filters).
  • getCommitFiles(directory, commitHash): Get file changes for a specific commit.

Merge and Rebase Operations

  • rebase(directory, options): Start a rebase onto a target branch.
  • abortRebase(directory): Abort an in-progress rebase.
  • continueRebase(directory): Continue a rebase after conflict resolution.
  • merge(directory, options): Merge a branch into current branch.
  • abortMerge(directory): Abort an in-progress merge.
  • continueMerge(directory): Continue a merge after conflict resolution.
  • getConflictDetails(directory): Get detailed conflict information including operation type, unmerged files, and diff.

Stash Operations

  • stash(directory, options): Stash changes (supports message and includeUntracked options).
  • stashPop(directory): Pop and apply the most recent stash.

Internal Helpers

The following functions are internal helpers used by exported functions:

  • buildSshCommand(sshKeyPath): Build SSH command string for git config.
  • buildGitEnv(): Build Git environment with SSH_AUTH_SOCK resolution.
  • createGit(directory): Create simple-git instance with environment.
  • normalizeDirectoryPath(value): Normalize directory paths (supports ~ expansion).
  • cleanBranchName(branch): Remove refs/heads/ or refs/ prefixes.
  • parseWorktreePorcelain(raw): Parse git worktree list --porcelain output.
  • resolveWorktreeProjectContext(directory): Resolve project context (projectID, primaryWorktree, worktreeRoot).
  • resolveCandidateDirectory(...): Generate unique worktree directory candidates.
  • resolveBranchForExistingMode(...): Resolve branch for existing-mode worktree creation.
  • applyUpstreamConfiguration(...): Set upstream tracking for new branches.
  • And various other internal helpers for Git command execution and parsing.

Response Contracts

Status Response

  • current: Current branch name.
  • tracking: Upstream branch (e.g., 'origin/main').
  • ahead: Number of commits ahead of upstream.
  • behind: Number of commits behind upstream.
  • files: Array of file objects with path, index, working_dir status codes.
  • isClean: Boolean indicating if working tree is clean.
  • diffStats: Object mapping file paths to { insertions, deletions }.
  • mergeInProgress: Object with { head, message } if merge in progress.
  • rebaseInProgress: Object with { headName, onto } if rebase in progress.

Worktree Create/Remove Response

  • head: HEAD commit SHA.
  • name: Worktree name.
  • branch: Local branch name.
  • path: Absolute path to worktree directory.

Log Response

  • all: Array of commit objects with hash, date, message, author info, stats.
  • latest: Latest commit object or null.
  • total: Total number of commits.

Notes for Contributors

Adding a New Git Operation

  1. Add the function to packages/web/server/lib/git/service.js.
  2. Export the function if it's part of the public API.
  3. Use createGit(directory) to get a simple-git instance with the correct environment.
  4. Use runGitCommand(cwd, args) for direct git command execution with better error handling.
  5. Use runGitCommandOrThrow(cwd, args, fallbackMessage) for commands that must succeed.
  6. Return consistent error messages; use parseGitErrorText(error) to extract meaningful git errors.
  7. Update this file with the new function in the appropriate API section.

SSH Key Handling

  • SSH keys are escaped and validated via escapeSshKeyPath to prevent command injection.
  • On Windows, paths are converted to MSYS format (C:/path/c/path).
  • SSH_AUTH_SOCK is automatically resolved via resolveSshAuthSock (checks GPG agent, gpgconf).

Worktree Naming

  • Worktree names are slugified via slugWorktreeName.
  • Random names use adjectives/nouns from OPENCODE_ADJECTIVES and OPENCODE_NOUNS lists.
  • Branches created for new worktrees use openchamber/<worktree-name> pattern.

Cross-Platform Considerations

  • Use normalizeDirectoryPath for all directory inputs to handle ~ and path separators.
  • Use canonicalPath for path comparisons to handle case-insensitive filesystems (Windows).
  • Windows Git commands use MSYS/MinGW paths; avoid direct Windows paths in git commands.

Error Handling

  • All exported functions should throw errors with descriptive messages.
  • Use console.error for logging Git operation failures.
  • Return structured objects for operations that need partial success reporting (e.g., merge/rebase conflicts).

Testing

  • Run bun run type-check, bun run lint, and bun run build before finalizing changes.
  • Consider edge cases: non-Git directories, missing remotes, conflict states, concurrent worktree operations.