dugite

repository·main·Indexed 19 days ago

https://github.com/desktop/dugite

Elegant Node.js bindings for Git that allow applications to interact with Git repositories using the same command-line interface as Git core. It provides a Promise-based `exec` function for running commands, a `spawn` function for raw child process access, and utilities like `parseError` to map Git stderr output to known `GitError` constants. Primarily used by GitHub-related projects such as GitHub Desktop.

Tokens
7.1K
Snippets
22
Records
35
Agent score
67%

What's inside dugite

  1. Core functions for interacting with Git

    main

    Dugite provides two primary ways to interact with the Git CLI:

    1. exec: The core function used to run Git commands. It returns an IGitResult object containing the exit code and the standard output/error text.
    2. spawn: Exposes the raw child process, allowing callers to manipulate the process directly for more complex requirements.
  2. Understand Git results with IGitResult

    main

    When using exec, the returned IGitResult is an abstraction representing the outcome of a Git command. It contains:

    • The exit code of the process.
    • Standard output (stdout) and standard error (stderr) text, which can be provided as either a string or a Buffer.
  3. Handle execution failures with ExecError

    main
    When exec fails to execute a command, it throws an ExecError. This error class includes the stdout and stderr from the failed process, allowing you to inspect the output to determine why the command failed.
  4. Use a custom Git distribution for Dugite execution

    main

    By default, dugite manages its own Git distribution. To force dugite to use a separate, pre-installed Git distribution, you must set the following two environment variables:

    • LOCAL_GIT_DIRECTORY: The root location of Git (the directory containing bin/git).
    • GIT_EXEC_PATH: The location where Git's subprograms are located.

    To automate finding these paths, it is recommended to use the find-git-exec module.

    import { dirname } from 'path'
    import { default as findGit, Git } from 'find-git-exec'
    
    let git: Git | undefined = undefined
    
    try {
      git = await findGit()
    } catch {}
    
    if (git.path && git.execPath) {
      const { path, execPath } = git
      // Set the environment variable to be able to use an external Git.
      process.env.GIT_EXEC_PATH = execPath
      process.env.LOCAL_GIT_DIRECTORY = dirname(dirname(path))
    }
  5. Handle Git errors with parseError and GitError

    main
    To detect specific Git failures, use parseError to parse error messages returned by the Git CLI. This function maps messages to GitError, which is a collection of known error codes that Dugite can understand and identify.
  6. Install and set up Dugite

    main

    To use Dugite, ensure you have NodeJS v20 or higher installed.

    After cloning the repository, run the following command from the root to install dependencies, compile the library source, and execute the test suite:

    yarn
  7. Cancel Git operations using AbortSignal

    main

    You can cancel long-running Git operations (like clone) by passing an AbortSignal in the options object of the exec call. This is achieved using the standard AbortController API.

    Manual Cancellation

    Create an AbortController and pass its signal to exec. You can then call controller.abort() to stop the process.

    Automatic Timeout

    Use AbortSignal.timeout(ms) to automatically cancel the operation if it exceeds a specific duration.

    Note: When a process is cancelled, the exec promise will reject, and you should handle the error in a try/catch block.

    import { exec } from 'dugite'
    
    // Manual cancellation
    const controller = new AbortController()
    const resultPromise = exec(['clone', 'https://github.com/example/repo'], '/path/to/dir', {
      signal: controller.signal,
    })
    
    // Cancel if needed
    controller.abort()
    
    try {
      const result = await resultPromise
    } catch (error) {
      // Handle cancellation
    }
    
    // Automatic timeout cancellation
    const result = await exec(['clone', 'https://github.com/example/repo'], '/path/to/dir', {
      signal: AbortSignal.timeout(5000), // Auto-cancel after 5 seconds
    })
  8. Validate and apply coding style with Prettier

    main

    Dugite uses Prettier for coding style. You can validate the current formatting or automatically apply fixes using the following commands:

    • Validate formatting: Check if the code matches the style guide.
    • Apply formatting: Automatically fix formatting issues to match the style guide before committing.
    # Validate formatting
    yarn is-it-pretty
    
    # Apply formatting
    yarn prettify
  9. Configure the Dugite installation cache directory

    main
    When installing dugite, you can use the DUGITE_CACHE_DIR environment variable to specify a custom directory for caching platform-specific upstream packages that contain the Git distributable. This is useful for build servers to speed up testing by persisting assets. If not provided, dugite falls back to the Node.js os.tmpdir().