Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release: v1.9.2 #39

Merged
merged 2 commits into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 128 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,40 +1,76 @@
# git-client

Promise-based git client that mostly just executes the git binary
[![Tests](https://github.com/JarvusInnovations/git-client/actions/workflows/test.yml/badge.svg)](https://github.com/JarvusInnovations/git-client/actions/workflows/test.yml)
[![npm version](https://badge.fury.io/js/git-client.svg)](https://badge.fury.io/js/git-client)

## Usage
A lightweight, Promise-based Git client for Node.js that executes the git binary. This library provides a clean, Promise-based interface to Git operations while maintaining the full power and flexibility of the git command line.

### Basic usage
## Features

```js
const git = require('git-client');
const hash = await git('rev-parse HEAD');
- Promise-based API for all Git operations
- Supports all Git commands with automatic method generation
- Flexible option handling with both short and long format support
- Spawn mode for streaming operations
- Built-in support for common Git operations
- Minimal dependencies
- Full TypeScript support with type definitions

## Requirements

- Node.js 16.x or higher
- Git installed and available in PATH

## Installation

```bash
npm install git-client
```

### Multiple arguments
## Basic Usage

### Simple Command Execution

```js
const git = require('git-client');

// Get current commit hash
const hash = await git('rev-parse', 'HEAD');
```

### Option building
### Using Named Methods

```js
const hash = await git('rev-parse', { verify: true, short: 6 }, 'HEAD');
const git = require('git-client');

// Using the revParse method
const hash = await git.revParse({ verify: true }, 'HEAD');

// Using the status method
const status = await git.status({ porcelain: true });
```

### Named methods for common commands
### Working with Options

```js
const hash = await git.revParse({ verify: true }, 'HEAD');
// Short format options
const log = await git('log', { n: 5 });

// Long format options
const diff = await git('diff', { 'word-diff': true });

// Mixed options with arguments
const show = await git('show', { format: '%H', 'no-patch': true }, 'HEAD');
```

## Advanced Examples
## Advanced Usage

### Spawning Processes

### Save file from the web
Use spawn mode for operations that need streaming or real-time output:

```js
const writer = await git.hashObject({ w: true, stdin: true, $spawn: true });
// Save file from the web
const writer = await git.hashObject({ w: true, stdin: true, $spawn: true });
const response = await axios.get('https://placekitten.com/1000/1000', { responseType: 'stream' });

// pipe data from HTTP response into git
Expand All @@ -46,11 +82,11 @@ await new Promise((resolve, reject) => {
response.data.on('error', () => reject());
});

// read written hash and save to ref
// read written hash
const hash = await writer.captureOutputTrimmed();
```

### Build a tree
### Building Trees

```js
const lines = [
Expand All @@ -59,6 +95,81 @@ const lines = [
];

const mktree = await git.mktree({ $spawn: true });

const hash = await mktree.captureOutputTrimmed(lines.join('\n')+'\n');
```

### Custom Git Directory

```js
const customGit = new git.Git({ gitDir: '/path/to/repo/.git' });
const status = await customGit.status();
```

## TypeScript Support

The library includes TypeScript definitions for all methods and options. When using TypeScript, you'll get full type checking and autocompletion for:

- Git instance configuration options
- Command execution options
- All git commands and their parameters
- Spawn mode process types
- Event handlers and callbacks

## API Reference

### Main Function

The default export is a function that executes git commands:

```js
git(command: string, ...args: Array<string|object>): Promise<string>
```

### Special Options

When passing options objects, the following special keys are supported:

- `$gitDir`: Set custom git directory
- `$workTree`: Set custom working tree
- `$indexFile`: Set custom index file
- `$spawn`: Enable spawn mode
- `$shell`: Enable shell mode
- `$nullOnError`: Return null instead of throwing on error
- `$onStdout`: Callback for stdout in spawn mode
- `$onStderr`: Callback for stderr in spawn mode

### Common Methods

All git commands are available as methods. Some commonly used ones include:

- `git.status(options)`
- `git.add(options, ...files)`
- `git.commit(options, message)`
- `git.push(options)`
- `git.pull(options)`
- `git.checkout(options, ref)`
- `git.branch(options)`
- `git.merge(options, ref)`
- `git.log(options)`

## Contributing

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -am 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

### Running Tests

```bash
npm test
```

## License

MIT License - see the [LICENSE](LICENSE) file for details.

## Credits

Created and maintained by [Jarvus Innovations](https://github.com/JarvusInnovations).
115 changes: 115 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
declare module 'git-client' {
export interface GitOptions {
command?: string;
gitDir?: string;
workTree?: string;
indexFile?: string;
}

export interface ExecOptions {
/** Set custom git directory */
$gitDir?: string;
/** Set custom working tree */
$workTree?: string;
/** Set custom index file */
$indexFile?: string;
/** Enable spawn mode */
$spawn?: boolean;
/** Enable shell mode */
$shell?: boolean;
/** Return null instead of throwing on error */
$nullOnError?: boolean;
/** Callback for stdout in spawn mode */
$onStdout?: (line: string) => void;
/** Callback for stderr in spawn mode */
$onStderr?: (line: string) => void;
/** Enable passthrough mode */
$passthrough?: boolean;
/** Wait for process to complete */
$wait?: boolean;
/** Preserve environment variables */
$preserveEnv?: boolean;
/** Custom working directory */
$cwd?: string;
/** Custom environment variables */
$env?: Record<string, string>;
/** Additional options */
$options?: Record<string, any>;
/** Any git command options */
[key: string]: any;
}

export interface SpawnedProcess extends NodeJS.EventEmitter {
stdin: NodeJS.WritableStream;
stdout: NodeJS.ReadableStream;
stderr: NodeJS.ReadableStream;
captureOutput(input?: string | null): Promise<string>;
captureOutputTrimmed(input?: string | null): Promise<string>;
}

export interface TreeChild {
mode: string;
type: string;
hash: string;
name: string;
}

export class Git {
constructor(options?: GitOptions);

command: string;
gitDir: string | null;
workTree: string | null;
indexFile: string | null;
version: string | null;

static getGitDirFromEnvironment(): Promise<string>;
static getWorkTreeFromEnvironment(): Promise<string | null>;

getGitDir(): Promise<string>;
getWorkTree(): Promise<string | null>;
getIndexPath(): Promise<string>;
getVersion(): Promise<string | null>;
satisfiesVersion(range: string): Promise<boolean>;
requireVersion(range: string): Promise<this>;

readConfigSet(configPath: string): Promise<Set<string>>;
writeConfigSet(configPath: string, set: Set<string>): Promise<void>;
addToConfigSet(configPath: string, ...items: string[]): Promise<Set<string>>;
removeFromConfigSet(configPath: string, ...items: string[]): Promise<Set<string>>;

isHash(hash: string): boolean;
getTreeHash(ref: string, options?: { verify?: boolean }): Promise<string>;
hashObjectInternally(content: string | Buffer, options?: { type?: string; write?: boolean }): Promise<string>;
mktreeBatch(children: TreeChild[]): Promise<string>;
cleanup(): void;

exec(command: string, ...args: Array<string | ExecOptions>): Promise<string | SpawnedProcess>;

// Git commands as methods
add(options?: ExecOptions, ...files: string[]): Promise<string>;
commit(options?: ExecOptions, message?: string): Promise<string>;
push(options?: ExecOptions): Promise<string>;
pull(options?: ExecOptions): Promise<string>;
checkout(options?: ExecOptions, ref?: string): Promise<string>;
branch(options?: ExecOptions): Promise<string>;
merge(options?: ExecOptions, ref?: string): Promise<string>;
log(options?: ExecOptions): Promise<string>;
status(options?: ExecOptions): Promise<string>;
fetch(options?: ExecOptions): Promise<string>;
remote(options?: ExecOptions): Promise<string>;
reset(options?: ExecOptions): Promise<string>;
revert(options?: ExecOptions): Promise<string>;
tag(options?: ExecOptions): Promise<string>;
init(options?: ExecOptions): Promise<string>;
clone(options?: ExecOptions): Promise<string>;
diff(options?: ExecOptions): Promise<string>;
show(options?: ExecOptions): Promise<string>;
stash(options?: ExecOptions): Promise<string>;
revParse(options?: ExecOptions, ref?: string): Promise<string>;
[key: string]: any;
}

const git: Git & ((command: string, ...args: Array<string | ExecOptions>) => Promise<string | SpawnedProcess>);
export default git;
}
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"version": "1.8.3",
"description": "Promise-based git client that mostly just executes the git binary",
"main": "index.js",
"types": "index.d.ts",
"scripts": {
"test": "ava --no-worker-threads"
},
Expand All @@ -16,7 +17,8 @@
},
"keywords": [
"git",
"promise"
"promise",
"typescript"
],
"repository": "JarvusInnovations/git-client",
"homepage": "https://github.com/JarvusInnovations/git-client",
Expand Down
Loading