Skip to content

Releases: desktop/dugite

v3.0.0

11 Nov 07:41

Choose a tag to compare

What's included

Git: v2.47.3
Git for Windows: v2.47.3.windows.1
Git LFS: v3.7.1
Git Credential Manager: v2.6.1

What's Changed

The API has been significantly reworked, removing the static class GitProcess in favor of more idiomatic exec and spawn functions (#591). These new functions support cancellation via AbortSignal that gets passed down to the underlying spawn allowing termination of Git processes via signals.

Breaking changes

  • Drop support for node 14 and 16 by @niik in #566
  • Use dugite system config by @niik in #563
  • Handle env vars in a case-preserving, case-insensitive manner on Windows by @niik in #574
  • For macOS and Linux dugite now overrides the system level gitconfig with its own (which inherits the system config) in order for us to be able to provide sane defaults for credential managers, see https://github.com/desktop/dugite-native/blob/main/resources/posix.gitconfig
  • maxBuffer is now Infinity by default
  • Exceptions returned from exec are now of the ExecError type which includes the raw stdout and stderr

Notable changes

  • Removed jest in favor of Node test runner by @niik in #583
  • Add support for detecting push with secrets error by @tidy-dev in #608

Migration guide

API Restructuring

Removed: GitProcess Class

2.7.1:

import { GitProcess } from 'dugite'

// Using static methods
const result = await GitProcess.exec(['status'], '/path/to/repo')
const child = GitProcess.spawn(['log'], '/path/to/repo')
const error = GitProcess.parseError(stderr)

3.0.0:

import { exec, spawn, parseError } from 'dugite'

// Using standalone functions
const result = await exec(['status'], '/path/to/repo')
const child = spawn(['log'], '/path/to/repo')
const error = parseError(stderr)

Migration: Replace all GitProcess.method() calls with direct function imports and calls.

Removed: GitProcess.execTask() and IGitTask

The execTask() method and its associated IGitTask interface have been removed entirely in 3.0.0. It's sole purpose
was to provide cancellation support, which is now handled via passing an AbortSignal to exec() or spawn().

2.7.1:

const task = GitProcess.execTask(['clone', url], '/path/to/repo')
// Access result promise
const result = await task.result
// Cancel the task
const cancelResult = await task.cancel()

3.0.0 Alternative:

// Use AbortController for cancellation
const controller = new AbortController()
const resultPromise = exec(['clone', url], '/path/to/repo', {
  signal: controller.signal,
})

// Cancel if needed
controller.abort()

try {
  const result = await resultPromise
} catch (error) {
  // Handle cancellation
}

Migration:

  • Replace execTask() with exec()
  • Use AbortController and signal option for cancellation support
  • Remove references to IGitTask and GitTaskCancelResult

Removed: GitTaskCancelResult Enum

The GitTaskCancelResult enum has been removed along with IGitTask.

Migration: Handle cancellation using standard promise rejection with AbortController.

Type System Changes

1. Environment Variable Types

2.7.1:

interface IGitExecutionOptions {
  readonly env?: object // Generic object type
}

interface IGitSpawnExecutionOptions {
  readonly env?: object // Generic object type
}

3.0.0:

interface IGitExecutionOptions {
  readonly env?: Record<string, string | undefined> // More specific type
}

interface IGitSpawnOptions {
  readonly env?: Record<string, string | undefined> // More specific type
}

Migration: Ensure environment variables are typed as Record<string, string | undefined> instead of generic object.

2. Encoding support

Both exec and spawn now support returning output as either string or Buffer based on the encoding option.

2.7.1:

interface IGitResult {
  readonly stdout: string // Always string
  readonly stderr: string // Always string
  readonly exitCode: number
}

3.0.0:

interface IGitResult {
  readonly stdout: string | Buffer // Can be Buffer
  readonly stderr: string | Buffer // Can be Buffer
  readonly exitCode: number
}

// New specialized interfaces
interface IGitStringResult extends IGitResult {
  readonly stdout: string
  readonly stderr: string
}

interface IGitBufferResult extends IGitResult {
  readonly stdout: Buffer
  readonly stderr: Buffer
}

Migration:

  • If you need string output (default), use type narrowing or the IGitStringResult type
  • For buffer output, explicitly set encoding: 'buffer' and use IGitBufferResult
  • Update code that assumes stdout/stderr are always strings

3. Execution Options Enhancements

New in 3.0.0:

interface IGitExecutionOptions {
  // New options
  readonly encoding?: BufferEncoding | 'buffer' // Control output encoding
  readonly signal?: AbortSignal // AbortController support
  readonly killSignal?: ExecFileOptions['killSignal'] // Custom kill signal

  // Changed: maxBuffer now defaults to Infinity instead of 10MB
  readonly maxBuffer?: number
}

Migration:

  • The default maxBuffer changed from 10MB (10485760 bytes) to Infinity
  • If you relied on the 10MB limit, explicitly set maxBuffer: 10485760
  • Use encoding option to control output format (string vs buffer)
  • Use signal option with AbortController for cancellation

4. Interface Renames

2.7.1:

IGitSpawnExecutionOptions // For spawn options

3.0.0:

IGitSpawnOptions // Renamed, shorter name

Migration: Rename IGitSpawnExecutionOptions to IGitSpawnOptions.

Function Changes

1. New Exported Functions

3.0.0 exposes several new utility functions:

// Git directory resolution
function resolveEmbeddedGitDir(): string
function resolveGitDir(localGitDir?: string): string
function resolveGitBinary(localGitDir?: string): string
function resolveGitExecPath(localGitDir?: string, gitExecPath?: string): string

// Input stream handling
function ignoreClosedInputStream({ stdin }: ChildProcess): void

Migration: These are new utilities you can optionally use for advanced scenarios.

2. New Export: EnvMap Class

A platform-aware environment variable map (case-insensitive on Windows):

class EnvMap implements Map<string, string | undefined> {
  // Standard Map interface
}

New Features

1. New Error Class: ExecError

3.0.0 introduces a structured error class for execution failures:

class ExecError extends Error {
  readonly message: string
  readonly stdout: Buffer | string
  readonly stderr: Buffer | string
  readonly code?: string
  readonly signal?: string
  readonly killed?: boolean
}

3. AbortController Support

You can now cancel long-running git operations:

const controller = new AbortController()
const result = exec(['clone', 'https://...'], '/path', {
  signal: AbortController.timeout(5000), // Auto-cancel after 5 seconds
})

Migration Guide

Step 1: Update Imports

Before (2.7.1):

import {
  GitProcess,
  IGitResult,
  IGitExecutionOptions,
  IGitTask,
  GitTaskCancelResult,
  GitError,
} from 'dugite'

After (3.0.0):

import {
  exec,
  spawn,
  parseError,
  parseBadConfigValueErrorInfo,
  IGitResult,
  IGitStringResult,
  IGitBufferResult,
  IGitExecutionOptions,
  IGitSpawnOptions,
  GitError,
  ExecError,
} from 'dugite'

Step 2: Replace GitProcess Static Methods

Before:

const result = await GitProcess.exec(args, path, options)
const child = GitProcess.spawn(args, path, options)
const error = GitProcess.parseError(stderr)

After:

const result = await exec(args, path, options)
const child = spawn(args, path, options)
const error = parseError(stderr)

Step 3: Replace execTask() with exec() + AbortController

Before:

const task = GitProcess.execTask(['clone', url], path)
// Later...
await task.cancel()
const result = await task.result

After:

const controller = new AbortController()
const resultPromise = exec(['clone', url], path, {
  signal: controller.signal,
})

// Later...
controller.abort()

Step 4: Review maxBuffer Usage

If you were relying on the default 10MB limit:

Before (2.7.1):

// Default maxBuffer was 10485760 (10MB)
const result = await GitProcess.exec(args, path)

After (3.0.0):

// Default is now Infinity, explicitly set if needed
const result = await exec(args, path, {
  maxBuffer: 10485760, // Restore old default
})

Summary

The migration from 2.7.1 to 3.0.0 primarily involves:

  1. ✅ Replace GitProcess.method() with standalone function imports
  2. ✅ Remove usage of execTask(), IGitTask, and GitTaskCancelResult
  3. ✅ Use AbortController for cancellation
  4. ✅ Update environment variable types to Record<string, string | undefined>
  5. ✅ Handle stdout/stderr as potentially Buffer or use specialized result types
  6. ✅ Rename IGitSpawnExecutionOptions to IGitSpawnOptions
  7. ✅ Review and explicitly set maxBuffer if the old 10MB default was important
  8. ✅ Update setupEnvironment() calls wi...
Read more

v2.7.1

14 May 19:33

Choose a tag to compare

  • Parse HTTP authentication errors #560

v2.7.0

14 May 17:41

Choose a tag to compare

  • Bump git to v2.43.4

v2.6.1

14 Mar 16:45

Choose a tag to compare

  • Add new GitProcess.parseBadConfigValueErrorInfo API #558

v2.6.0

13 Mar 12:42

Choose a tag to compare

  • Updates the embedded version of Git to 2.43.3 (or 2.43.0.windows.1) and Git LFS to 3.5.1.
  • Parses bad git config values #556

v2.5.2

12 Jul 15:05

Choose a tag to compare

  • Use ia32 suffix for Linux x86 binaries #529

v2.5.1

07 Jul 16:12

Choose a tag to compare

Updates dugite-native to v2.39.3-1 which brings lower glibc requirements for Linux binaries, and also support for Linux arm, arm64 and x86 architectures - #547

v2.5.0

25 Apr 19:06

Choose a tag to compare

Updates the embedded version of Git to 2.39.3 and 2.39.3.windows.1

v2.4.0

16 Feb 14:22

Choose a tag to compare

Updates the embedded version of Git to 2.39.2 and 2.39.2.windows.1

v2.3.0

18 Jan 13:00

Choose a tag to compare

Updates the embedded version of Git to 2.39.1 (or 2.39.1.windows.1) and Git LFS to 3.3.0.