simple-git

repository·main·Indexed 26 days ago

https://github.com/steveukx/git-js

A Promise-based or callback-based Node.js wrapper around the Git CLI. It provides a lightweight interface for performing Git operations, including cloning, committing, branching, and executing arbitrary Git commands via .raw(). It supports CommonJS, ES Modules, and TypeScript, and requires git to be installed on the system.

Tokens
22.1K
Snippets
75
Records
160
Agent score
86%

What's inside simple-git

  1. Install simple-git

    main

    Install simple-git using npm or yarn to use it as a lightweight interface for running git commands in your Node.js application.

    System Dependency: You must have git installed on your system and accessible via the git command.

    npm install simple-git
    # or
    yarn add simple-git
  2. Handle automated issue closures

    main

    The project uses automated processes to close issues that have not received requested additional details within a set timeframe. This is done to ensure the issue tracker remains focused on active investigations.

    If your issue has been closed:

    • If the issue is not locked: You can simply re-open the issue and add the requested details.
    • If the issue is locked: You must create a new issue. To maintain context, link the new issue to the old one by providing its ID or URL in your description.
  3. Use simple-git in JavaScript and TypeScript

    main

    You can include simple-git in your application using CommonJS, ES Modules, or TypeScript. The main export is a function that initializes a SimpleGit instance.

    CommonJS

    const simpleGit = require('simple-git');
    simpleGit().clean(simpleGit.CleanOptions.FORCE);

    ES Modules

    import { simpleGit, CleanOptions } from 'simple-git';
    simpleGit().clean(CleanOptions.FORCE);

    TypeScript

    import { simpleGit, SimpleGit, CleanOptions } from 'simple-git';
    
    const git: SimpleGit = simpleGit().clean(CleanOptions.FORCE);
  4. Enable progress events for commands that do not support them automatically

    main
    For Git commands that do not automatically trigger progress events (unlike pull or clone), you must explicitly pass the --progress flag via TaskOptions. You can do this by passing an object with the flag set to null or by passing the flag as an element in an array.
  5. Configure custom error detection with the errors plugin

    main

    By default, simple-git treats a task as an error if the process exit code is non-zero and data was sent to stdErr. Error handlers receive stdOut and stdErr concatenated.

    You can override this behavior by providing an errors plugin function in the simpleGit configuration. This function is called after every task.

    To implement custom logic:

    1. The function receives two arguments: error (the original error, if any) and result (the task result object).
    2. Return undefined to treat the task as a success.
    3. Return a Buffer or Error to treat the task as a failure.
    4. If an error already exists, you can return it directly to let it bubble up, or inspect result.exitCode to decide if a non-zero exit code should actually be treated as a success.
    import { simpleGit } from 'simple-git';
    
    const git = simpleGit({
       errors(error, result) {
          // optionally pass through any errors reported before this plugin runs
          if (error) return error;
    
          // customise the `errorCode` values to treat as success
          if (result.exitCode === 0) {
             return;
          }
    
          // the default error messages include both stdOut and stdErr, but that
          // can be changed here, or completely replaced with some other content
          return Buffer.concat([...result.stdOut, ...result.stdErr]);
       }
    })
  6. Configure timeout behavior with progress events

    main

    By default, the timeout plugin resets its timer whenever data is received on stdOut or stdErr. When using the progress plugin, git streams regular updates to stdErr, which can prevent the timeout from ever triggering.

    To prevent progress updates from resetting the timeout timer, set stdErr: false in the timeout configuration. You can also explicitly set stdOut: true (the default behavior) to reset the timer whenever data arrives on stdOut.

    import { simpleGit, SimpleGit } from "simple-git";
    
    const git: SimpleGit = simpleGit({
       progress({method, stage, progress}) {
          console.log(`git.${method} ${stage} stage ${progress}% complete`);
       },
       timeout: {
          block: 2000,
          stdOut: true, // default behaviour, resets the 2s timer every time data arrives on stdOut
          stdErr: false // custom behaviour, ignore the progress events being written to stdErr
       }
    });
  7. Terminate git tasks using AbortController

    main

    You can terminate git child processes created by simple-git by passing an AbortController.signal to the simpleGit constructor options. This sends a SIGKILL to the underlying processes.

    When a task is aborted, it will throw a GitPluginError. You can identify an abort-specific failure by checking if err.plugin === 'abort'.

    import { simpleGit, GitPluginError, SimpleGit } from 'simple-git';
    
    const controller = new AbortController();
    
    const git: SimpleGit = simpleGit({
       baseDir: '/some/path', 
       abort: controller.signal,
    });
    
    try {
      await git.pull();
    }
    catch (err) {
        if (err instanceof GitPluginError && err.plugin === 'abort') {
            // task failed because `controller.abort` was called while waiting for the `git.pull`
        }
    }
  8. Handle non-English locales for command parsing

    main

    Some simple-git methods return raw stdout (like git.raw()), but others parse the output into structured data (like git.branchLocal() returning a BranchSummary). If your system locale is not set to English, these parsers may fail. To ensure consistent parsing, set the LANG and LC_ALL environment variables to 'C' using the .env() method.

    import { simpleGit } from 'simple-git';
    
    const git = simpleGit().env({
       LANG: 'C',
       LC_ALL: 'C',
    });
    const branches = await git.branchLocal();
  9. Set absolute timeouts for git processes

    main

    By default, the timeout plugin only kills processes that appear to be hanging (it resets the timer on data arrival). To change this to an absolute timeout—where the process is killed after a fixed duration regardless of activity—set both stdOut and stdErr to false in the timeout configuration.

    import { simpleGit, SimpleGit } from "simple-git";
    
    // create a simple-git instance that kills any process after 5s
    // whether it's still receiving data or not:
    const git: SimpleGit = simpleGit({
       timeout: {
          block: 5000,
          stdOut: false,
          stdErr: false
       }
    });
  10. Handle Unsafe Actions in simple-git

    main

    Because simple-git passes arguments directly to a git child process, all user-provided input must be validated and sanitized. To prevent arbitrary command execution or credential disclosure, simple-git throws a GitPluginError when it detects high-risk patterns (like custom binaries or protocol overrides) unless you explicitly opt-in using the unsafe configuration object during initialization.

    Warning: These opt-in flags are safety nets and do not replace the need for proper input validation.

  11. Authenticate via remote URL

    main

    The simplest way to provide credentials is to include the username and password directly in the remote URL: https://username:password@repository-url.

    const USER = 'something';
    const PASS = 'somewhere';
    const REPO = 'github.com/username/private-repo';
    const remote = `https://${USER}:${PASS}@${REPO}`;
    
    simpleGit().clone(remote);
  12. Execute concurrent or parallel requests

    main

    Simple Git handles execution in two ways:

    1. Chained Commands (Series): When methods are chained, they run in series. Each task waits for the previous one to succeed. If one fails, the chain stops.
    2. Root Instance (Parallel): Calling methods on the root instance (git = simpleGit()) starts independent chains. This allows for parallel execution using Promise.all().

    You can limit the number of simultaneous child processes by passing maxConcurrentProcesses to the simpleGit constructor.

    // Chained (Series)
    simpleGit().init().addRemote('origin', 'https://some-repo.git').fetch();
    
    // Root instance (Parallel)
    const git = simpleGit();
    const results = await Promise.all([
       git.raw('rev-parse', '--show-cdup').catch(swallow),
       git.raw('rev-parse', '--show-prefix').catch(swallow),
    ]);
    
    // Limiting concurrency
    const git = simpleGit({ maxConcurrentProcesses: 10 });