UNPKG

48.2 kBMarkdownView Raw
1# Simple Git
2
3[![NPM version](https://img.shields.io/npm/v/simple-git.svg)](https://www.npmjs.com/package/simple-git)
4
5A lightweight interface for running `git` commands in any [node.js](https://nodejs.org) application.
6
7# Installation
8
9Use your favourite package manager:
10
11- [npm](https://npmjs.org): `npm install simple-git`
12- [yarn](https://yarnpkg.com/): `yarn add simple-git`
13
14# System Dependencies
15
16Requires [git](https://git-scm.com/downloads) to be installed and that it can be called using the command `git`.
17
18# Usage
19
20Include into your JavaScript app using common js:
21
22```javascript
23// require the library, main export is a function
24const simpleGit = require('simple-git');
25simpleGit().clean(simpleGit.CleanOptions.FORCE);
26
27// or use named properties
28const { simpleGit, CleanOptions } = require('simple-git');
29simpleGit().clean(CleanOptions.FORCE);
30```
31
32Include into your JavaScript app as an ES Module:
33
34```javascript
35import { simpleGit, CleanOptions } from 'simple-git';
36
37simpleGit().clean(CleanOptions.FORCE);
38```
39
40Include in a TypeScript app using the bundled type definitions:
41
42```typescript
43import { simpleGit, SimpleGit, CleanOptions } from 'simple-git';
44
45const git: SimpleGit = simpleGit().clean(CleanOptions.FORCE);
46```
47
48## Configuration
49
50Configure each `simple-git` instance with a properties object passed to the main `simpleGit` function:
51
52```typescript
53import { simpleGit, SimpleGit, SimpleGitOptions } from 'simple-git';
54
55const options: Partial<SimpleGitOptions> = {
56 baseDir: process.cwd(),
57 binary: 'git',
58 maxConcurrentProcesses: 6,
59 trimmed: false,
60};
61
62// when setting all options in a single object
63const git: SimpleGit = simpleGit(options);
64
65// or split out the baseDir, supported for backward compatibility
66const git: SimpleGit = simpleGit('/some/path', { binary: 'git' });
67```
68
69The first argument can be either a string (representing the working directory for `git` commands to run in),
70`SimpleGitOptions` object or `undefined`, the second parameter is an optional `SimpleGitOptions` object.
71
72All configuration properties are optional, the default values are shown in the example above.
73
74## Per-command Configuration
75
76To prefix the commands run by `simple-git` with custom configuration not saved in the git config (ie: using the
77`-c` command) supply a `config` option to the instance builder:
78
79```typescript
80// configure the instance with a custom configuration property
81const git: SimpleGit = simpleGit('/some/path', { config: ['http.proxy=someproxy'] });
82
83// any command executed will be prefixed with this config
84// runs: git -c http.proxy=someproxy pull
85await git.pull();
86```
87
88## Configuring Plugins
89
90- [AbortController](https://github.com/steveukx/git-js/blob/main/docs/PLUGIN-ABORT-CONTROLLER.md)
91 Terminate pending and future tasks in a `simple-git` instance (requires node >= 16).
92
93- [Custom Binary](https://github.com/steveukx/git-js/blob/main/docs/PLUGIN-CUSTOM-BINARY.md)
94 Customise the `git` binary `simple-git` uses when spawning `git` child processes.
95
96- [Completion Detection](https://github.com/steveukx/git-js/blob/main/docs/PLUGIN-COMPLETION-DETECTION.md)
97 Customise how `simple-git` detects the end of a `git` process.
98
99- [Error Detection](https://github.com/steveukx/git-js/blob/main/docs/PLUGIN-ERRORS.md)
100 Customise the detection of errors from the underlying `git` process.
101
102- [Progress Events](https://github.com/steveukx/git-js/blob/main/docs/PLUGIN-PROGRESS-EVENTS.md)
103 Receive progress events as `git` works through long-running processes.
104
105- [Spawned Process Ownership](https://github.com/steveukx/git-js/blob/main/docs/PLUGIN-SPAWN-OPTIONS.md)
106 Configure the system `uid` / `gid` to use for spawned `git` processes.
107
108- [Timeout](https://github.com/steveukx/git-js/blob/main/docs/PLUGIN-TIMEOUT.md)
109 Automatically kill the wrapped `git` process after a rolling timeout.
110
111- [Unsafe](https://github.com/steveukx/git-js/blob/main/docs/PLUGIN-UNSAFE-ACTIONS.md)
112 Selectively opt out of `simple-git` safety precautions - for advanced users and use cases.
113
114## Using Task Promises
115
116Each task in the API returns the `simpleGit` instance for chaining together multiple tasks, and each
117step in the chain is also a `Promise` that can be `await` ed in an `async` function or returned in a
118`Promise` chain.
119
120```javascript
121const git = simpleGit();
122
123// chain together tasks to await final result
124await git.init().addRemote('origin', '...remote.git');
125
126// or await each step individually
127await git.init();
128await git.addRemote('origin', '...remote.git');
129```
130
131### Catching errors in async code
132
133To catch errors in async code, either wrap the whole chain in a try/catch:
134
135```javascript
136const git = simpleGit();
137try {
138 await git.init();
139 await git.addRemote(name, repoUrl);
140} catch (e) {
141 /* handle all errors here */
142}
143```
144
145or catch individual steps to permit the main chain to carry on executing rather than
146jumping to the final `catch` on the first error:
147
148```javascript
149const git = simpleGit();
150try {
151 await git.init().catch(ignoreError);
152 await git.addRemote(name, repoUrl);
153} catch (e) {
154 /* handle all errors here */
155}
156
157function ignoreError() {}
158```
159
160## Using Task Callbacks
161
162In addition to returning a promise, each method can also be called with a trailing callback argument
163to handle the result of the task.
164
165```javascript
166const git = simpleGit();
167git.init(onInit).addRemote('origin', 'git@github.com:steveukx/git-js.git', onRemoteAdd);
168
169function onInit(err, initResult) {}
170function onRemoteAdd(err, addRemoteResult) {}
171```
172
173If any of the steps in the chain result in an error, all pending steps will be cancelled, see the
174[parallel tasks](<(#concurrent--parallel-requests)>) section for more information on how to run tasks in parallel rather than in series .
175
176## Task Responses
177
178Whether using a trailing callback or a Promise, tasks either return the raw `string` or `Buffer` response from the
179`git` binary, or where possible a parsed interpretation of the response.
180
181For type details of the response for each of the tasks, please see the [TypeScript definitions](https://github.com/steveukx/git-js/blob/main/simple-git/typings/simple-git.d.ts).
182
183# Upgrading from Version 2
184
185From v3 of `simple-git` you can now import as an ES module, Common JS module or as TypeScript with bundled type
186definitions. Upgrading from v2 will be seamless for any application not relying on APIs that were marked as deprecated
187in v2 (deprecation notices were logged to `stdout` as `console.warn` in v2).
188
189# API
190
191| API | What it does |
192| ---------------------------------------------------- |------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
193| `.add([fileA, ...], handlerFn)` | adds one or more files to be under source control |
194| `.addAnnotatedTag(tagName, tagMessage, handlerFn)` | adds an annotated tag to the head of the current branch |
195| `.addTag(name, handlerFn)` | adds a lightweight tag to the head of the current branch |
196| `.catFile(options, [handlerFn])` | generate `cat-file` detail, `options` should be an array of strings as supported arguments to the [cat-file](https://git-scm.com/docs/git-cat-file) command |
197| `.checkIgnore([filepath, ...], handlerFn)` | checks if filepath excluded by .gitignore rules |
198| `.clearQueue()` | immediately clears the queue of pending tasks (note: any command currently in progress will still call its completion callback) |
199| `.commit(message, handlerFn)` | commits changes in the current working directory with the supplied message where the message can be either a single string or array of strings to be passed as separate arguments (the `git` command line interface converts these to be separated by double line breaks) |
200| `.commit(message, [fileA, ...], options, handlerFn)` | commits changes on the named files with the supplied message, when supplied, the optional options object can contain any other parameters to pass to the commit command, setting the value of the property to be a string will add `name=value` to the command string, setting any other type of value will result in just the key from the object being passed (ie: just `name`), an example of setting the author is below |
201| `.customBinary(gitPath)` | sets the command to use to reference git, allows for using a git binary not available on the path environment variable [docs](https://github.com/steveukx/git-js/blob/main/docs/PLUGIN-CUSTOM-BINARY.md) |
202| `.env(name, value)` | Set environment variables to be passed to the spawned child processes, [see usage in detail below](#environment-variables). |
203| `.exec(handlerFn)` | calls a simple function in the current step |
204| `.fetch([options, ] handlerFn)` | update the local working copy database with changes from the default remote repo and branch, when supplied the options argument can be a standard [options object](#how-to-specify-options) either an array of string commands as supported by the [git fetch](https://git-scm.com/docs/git-fetch). |
205| `.fetch(remote, branch, handlerFn)` | update the local working copy database with changes from a remote repo |
206| `.fetch(handlerFn)` | update the local working copy database with changes from the default remote repo and branch |
207| `.outputHandler(handlerFn)` | attaches a handler that will be called with the name of the command being run and the `stdout` and `stderr` [readable streams](https://nodejs.org/api/stream.html#stream_class_stream_readable) created by the [child process](https://nodejs.org/api/child_process.html#child_process_class_childprocess) running that command, see [examples](https://github.com/steveukx/git-js/blob/main/examples/git-output-handler.md) |
208| `.raw(args, [handlerFn])` | Execute any arbitrary array of commands supported by the underlying git binary. When the git process returns a non-zero signal on exit and it printed something to `stderr`, the command will be treated as an error, otherwise treated as a success. |
209| `.rebase([options,] handlerFn)` | Rebases the repo, `options` should be supplied as an array of string parameters supported by the [git rebase](https://git-scm.com/docs/git-rebase) command, or an object of options (see details below for option formats). |
210| `.revert(commit , [options , [handlerFn]])` | reverts one or more commits in the working copy. The commit can be any regular commit-ish value (hash, name or offset such as `HEAD~2`) or a range of commits (eg: `master~5..master~2`). When supplied the [options](#how-to-specify-options) argument contain any options accepted by [git-revert](https://git-scm.com/docs/git-revert). |
211| `.rm([fileA, ...], handlerFn)` | removes any number of files from source control |
212| `.rmKeepLocal([fileA, ...], handlerFn)` | removes files from source control but leaves them on disk |
213| `.tag(args[], handlerFn)` | Runs any supported [git tag](https://git-scm.com/docs/git-tag) commands with arguments passed as an array of strings . |
214| `.tags([options, ] handlerFn)` | list all tags, use the optional [options](#how-to-specify-options) object to set any options allows by the [git tag](https://git-scm.com/docs/git-tag) command. Tags will be sorted by semantic version number by default, for git versions 2.7 and above, use the `--sort` option to set a custom sort. |
215
216## git apply
217
218- `.applyPatch(patch, [options])` applies a single string patch (as generated by `git diff`), optionally configured with the supplied [options](#how-to-specify-options) to set any arguments supported by the [apply](https://git-scm.com/docs/git-apply) command. Returns the unmodified string response from `stdout` of the `git` binary.
219- `.applyPatch(patches, [options])` applies an array of string patches (as generated by `git diff`), optionally configured with the supplied [options](#how-to-specify-options) to set any arguments supported by the [apply](https://git-scm.com/docs/git-apply) command. Returns the unmodified string response from `stdout` of the `git` binary.
220
221## git branch
222
223- `.branch([options])` uses the supplied [options](#how-to-specify-options) to run any arguments supported by the [branch](https://git-scm.com/docs/git-branch) command. Either returns a [BranchSummaryResult](https://github.com/steveukx/git-js/blob/main/simple-git/src/lib/responses/BranchSummary.ts) instance when listing branches, or a [BranchSingleDeleteResult](https://github.com/steveukx/git-js/blob/main/simple-git/typings/response.d.ts) type object when the options included `-d`, `-D` or `--delete` which cause it to delete a named branch rather than list existing branches.
224- `.branchLocal()` gets a list of local branches as a [BranchSummaryResult](https://github.com/steveukx/git-js/blob/main/simple-git/src/lib/responses/BranchSummary.ts) instance
225- `.deleteLocalBranch(branchName)` deletes a local branch - treats a failed attempt as an error
226- `.deleteLocalBranch(branchName, forceDelete)` deletes a local branch, optionally explicitly setting forceDelete to true - treats a failed attempt as an error
227- `.deleteLocalBranches(branchNames)` deletes multiple local branches
228- `.deleteLocalBranches(branchNames, forceDelete)` deletes multiple local branches, optionally explicitly setting forceDelete to true
229
230## git clean
231
232- `.clean(mode)` clean the working tree. Mode should be "n" - dry run or "f" - force
233- `.clean(cleanSwitches [,options])` set `cleanSwitches` to a string containing any number of the supported single character options, optionally with a standard [options](#how-to-specify-options) object
234
235## git checkout
236
237- `.checkout(checkoutWhat , [options])` - checks out the supplied tag, revision or branch when supplied as a string,
238 additional arguments supported by [git checkout](https://git-scm.com/docs/git-checkout) can be supplied as an
239 [options](#how-to-specify-options) object/array.
240
241- `.checkout(options)` - check out a tag or revision using the supplied [options](#how-to-specify-options)
242
243- `.checkoutBranch(branchName, startPoint)` - checks out a new branch from the supplied start point.
244
245- `.checkoutLocalBranch(branchName)` - checks out a new local branch
246
247## git clone
248
249- `.clone(repoPath, [localPath, [options]])` clone a remote repo at `repoPath` to a local directory at `localPath`, optionally with a standard [options](#how-to-specify-options) object of additional arguments to include between `git clone` and the trailing `repo local` arguments
250- `.clone(repoPath, [options])` clone a remote repo at `repoPath` to a directory in the current working directory with the same name as the repo
251
252- `mirror(repoPath, [localPath, [options]])` behaves the same as the `.clone` interface with the [`--mirror` flag](https://git-scm.com/docs/git-clone#Documentation/git-clone.txt---mirror) enabled.
253
254## git config
255
256- `.addConfig(key, value, append = false, scope = 'local')` add a local configuration property, when `append` is set to
257 `true` the configuration setting is appended to rather than overwritten in the local config. Use the `scope` argument
258 to pick where to save the new configuration setting (use the exported `GitConfigScope` enum, or equivalent string
259 values - `worktree | local | global | system`).
260- `.getConfig(key)` get the value(s) for a named key as a [ConfigGetResult](https://github.com/steveukx/git-js/blob/main/simple-git/typings/response.d.ts)
261- `.getConfig(key, scope)` get the value(s) for a named key as a [ConfigGetResult](https://github.com/steveukx/git-js/blob/main/simple-git/typings/response.d.ts) but limit the
262 scope of the properties searched to a single specified scope (use the exported `GitConfigScope` enum, or equivalent
263 string values - `worktree | local | global | system`)
264
265- `.listConfig()` reads the current configuration and returns a [ConfigListSummary](https://github.com/steveukx/git-js/blob/main/simple-git/src/lib/responses/ConfigList.ts)
266- `.listConfig(scope: GitConfigScope)` as with `listConfig` but returns only those items in a specified scope (note that configuration values are overlaid on top of each other to build the config `git` will actually use - to resolve the configuration you are using use `(await listConfig()).all` without the scope argument)
267
268## git count-objects
269
270- `.countObjects()` queries the pack and disk usage properties of the local repository and returns a [CountObjectsResult](https://github.com/steveukx/git-js/blob/main/simple-git/src/lib/tasks/count-objects.ts). All disk sizes are reported in Kb, see https://git-scm.com/docs/git-count-objects for full description of properties.
271
272## git diff
273
274- `.diff([ options ])` get the diff of the current repo compared to the last commit, optionally including
275 any number of other arguments supported by [git diff](https://git-scm.com/docs/git-diff) supplied as an
276 [options](#how-to-specify-options) object/array. Returns the raw `diff` output as a string.
277
278- `.diffSummary([ options ])` creates a [DiffResult](https://github.com/steveukx/git-js/blob/main/simple-git/src/lib/responses/DiffSummary.ts)
279 to summarise the diff for files in the repo. Uses the `--stat` format by default which can be overridden
280 by passing in any of the log format commands (eg: `--numstat` or `--name-stat`) as part of the optional
281 [options](#how-to-specify-options) object/array.
282
283## git grep [examples](https://github.com/steveukx/git-js/blob/main/examples/git-grep.md)
284
285- `.grep(searchTerm)` searches for a single search term across all files in the working tree, optionally passing a standard [options](#how-to-specify-options) object of additional arguments
286- `.grep(grepQueryBuilder(...))` use the `grepQueryBuilder` to create a complex query to search for, optionally passing a standard [options](#how-to-specify-options) object of additional arguments
287
288## git hash-object
289
290- `.hashObject(filePath, write = false)` computes the object ID value for the contents of the named file (which can be
291 outside of the work tree), optionally writing the resulting value to the object database.
292
293## git init
294
295- `.init(bare , [options])` initialize a repository using the boolean `bare` parameter to intialise a bare repository.
296 Any number of other arguments supported by [git init](https://git-scm.com/docs/git-init) can be supplied as an
297 [options](#how-to-specify-options) object/array.
298
299- `.init([options])` initialize a repository using any arguments supported by
300 [git init](https://git-scm.com/docs/git-init) supplied as an [options](#how-to-specify-options) object/array.
301
302## git log
303
304- `.log([options])` list commits between `options.from` and `options.to` tags or branch (if not specified will
305 show all history). Use the `options` object to set any [options](#how-to-specify-options) supported by the
306 [git log](https://git-scm.com/docs/git-log) command or any of the following:
307
308 - `options.file` - the path to a file in your repository to only consider this path.
309 - `options.format` - custom log format object, keys are the property names used on the returned object, values are the format string from [pretty formats](https://git-scm.com/docs/pretty-formats#Documentation/pretty-formats.txt)
310 - `options.from` - sets the oldest commit in the range to return, use along with `options.to` to set a bounded range
311 - `options.mailMap` - defaults to true, enables the use of [mail map](https://git-scm.com/docs/gitmailmap) in returned values for email and name from the default format
312 - `options.maxCount` - equivalent to setting the `--max-count` option
313 - `options.multiLine` - enables multiline body values in the default format (disabled by default)
314 - `options.splitter` - the character sequence to use as a delimiter between fields in the log, should be a value that doesn't appear in any log message (defaults to `ò`)
315 - `options.strictDate` - switches the authored date value from an ISO 8601-like format to be strict ISO 8601 format
316 - `options.symmetric` - defaults to true, enables [symmetric revision range](https://git-scm.com/docs/gitrevisions#_dotted_range_notations) rather than a two-dot range
317 - `options.to` - sets the newset commit in the range to return, use along with `options.from` to set a bounded range
318
319 When only one of `options.from` and `options.to` is supplied, the default value of the omitted option is equivalent to `HEAD`. For any other commit, explicitly supply both from and to commits (for example use `await git.firstCommit()` as the default value of `from` to log since the first commit of the repo).
320
321## git merge
322
323- `.merge(options)` runs a merge using any configuration [options](#how-to-specify-options) supported
324 by [git merge](https://git-scm.com/docs/git-merge).
325 Conflicts during the merge result in an error response, the response is an instance of
326 [MergeSummary](https://github.com/steveukx/git-js/blob/main/simple-git/src/lib/responses/MergeSummary.ts) whether it was an error or success.
327 When successful, the MergeSummary has all detail from a the [PullSummary](https://github.com/steveukx/git-js/blob/main/simple-git/src/lib/responses/PullSummary.ts)
328 along with summary detail for the merge.
329 When the merge failed, the MergeSummary contains summary detail for why the merge failed and which files
330 prevented the merge.
331
332- `.mergeFromTo(remote, branch , [options])` - merge from the specified branch into the currently checked out branch,
333 similar to `.merge` but with the `remote` and `branch` supplied as strings separately to any additional
334 [options](#how-to-specify-options).
335
336## git mv
337
338- `.mv(from, to)` rename or move a single file at `from` to `to`
339
340- `.mv(from, to)` move all files in the `from` array to the `to` directory
341
342## git pull
343
344- `.pull([options])` pulls all updates from the default tracked remote, any arguments supported by
345 [git pull](https://git-scm.com/docs/git-pull) can be supplied as an [options](#how-to-specify-options) object/array.
346
347- `.pull(remote, branch, [options])` pulls all updates from the specified remote branch (eg 'origin'/'master') along
348 with any custom [options](#how-to-specify-options) object/array
349
350## git push
351
352- `.push([options])` pushes to a named remote/branch using any supported [options](#how-to-specify-options)
353 from the [git push](https://git-scm.com/docs/git-push) command. Note that `simple-git` enforces the use of
354 `--verbose --porcelain` options in order to parse the response. You don't need to supply these options.
355
356- `.push(remote, branch, [options])` pushes to a named remote/branch, supports additional
357 [options](#how-to-specify-options) from the [git push](https://git-scm.com/docs/git-push) command.
358
359- `.pushTags(remote, [options])` pushes local tags to a named remote (equivalent to using `.push([remote, '--tags'])`)
360
361## git remote
362
363- `.addRemote(name, repo, [options])` adds a new named remote to be tracked as `name` at the path `repo`, optionally with any supported [options](#how-to-specify-options) for the [git add](https://git-scm.com/docs/git-remote#Documentation/git-remote.txt-emaddem) call.
364- `.getRemotes([verbose])` gets a list of the named remotes, supply the optional `verbose` option as `true` to include the URLs and purpose of each ref
365- `.listRemote([options])` lists remote repositories - there are so many optional arguments in the underlying `git ls-remote` call, just supply any you want to use as the optional [options](#how-to-specify-options) eg: `git.listRemote(['--heads', '--tags'], console.log)`
366- `.remote([options])` runs a `git remote` command with any number of [options](#how-to-specify-options)
367- `.removeRemote(name)` removes the named remote
368
369## git reset
370
371- `.reset(resetMode, [resetOptions])` resets the repository, sets the reset mode to one of the supported types (use a constant from
372 the exported `ResetMode` enum, or a string equivalent: `mixed`, `soft`, `hard`, `merge`, `keep`). Any number of other arguments
373 supported by [git reset](https://git-scm.com/docs/git-reset) can be supplied as an [options](#how-to-specify-options) object/array.
374
375- `.reset(resetOptions)` resets the repository with the supplied [options](#how-to-specify-options)
376
377- `.reset()` resets the repository in `soft` mode.
378
379## git rev-parse / repo properties
380
381- `.revparse([options])` sends the supplied [options](#how-to-specify-options) to [git rev-parse](https://git-scm.com/docs/git-rev-parse) and returns the string response from `git`.
382
383- `.checkIsRepo()` gets whether the current working directory is a descendent of a git repository.
384- `.checkIsRepo('bare')` gets whether the current working directory is within a bare git repo (see either [git clone --bare](https://git-scm.com/docs/git-clone#Documentation/git-clone.txt---bare) or [git init --bare](https://git-scm.com/docs/git-init#Documentation/git-init.txt---bare)).
385- `.checkIsRepo('root')` gets whether the current working directory is the root directory for a repo (sub-directories will return false).
386
387- `.firstCommit()` gets the commit hash of the first commit made to the current repo.
388
389## git show
390
391- `.show(options)` show various types of objects for example the file content at a certain commit. `options` is the single value string or any [options](#how-to-specify-options) supported by the [git show](https://git-scm.com/docs/git-show) command.
392- `.showBuffer(options)` same as the `.show` API, but returns the Buffer content directly to allow for showing binary file content.
393
394## git status
395
396- `.status([options])` gets the status of the current repo, resulting in a [StatusResult](https://github.com/steveukx/git-js/blob/main/simple-git/typings/response.d.ts). Additional arguments
397 supported by [git status](https://git-scm.com/docs/git-status) can be supplied as an [options](#how-to-specify-options) object/array.
398
399## git submodule
400
401- `.subModule(options)` Run a `git submodule` command with on or more arguments passed in as an [options](#how-to-specify-options) array or object
402- `.submoduleAdd(repo, path)` Adds a new sub module
403- `.submoduleInit([options]` Initialises sub modules, the optional [options](#how-to-specify-options) argument can be used to pass extra options to the `git submodule init` command.
404- `.submoduleUpdate(subModuleName, [options])` Updates sub modules, can be called with a sub module name and [options](#how-to-specify-options), just the options or with no arguments
405
406## git stash
407
408- `.stash([ options ])` Stash the working directory, optional first argument can be an array of string arguments or [options](#how-to-specify-options) object to pass to the [git stash](https://git-scm.com/docs/git-stash) command.
409
410- `.stashList([ options ])` Retrieves the stash list, optional first argument can be an object in the same format as used in [git log](#git-log).
411
412## git version [examples](https://github.com/steveukx/git-js/blob/main/examples/git-version.md)
413
414- `.version()` retrieve the major, minor and patch for the currently installed `git`. Use the `.installed` property of the result to determine whether `git` is accessible on the path.
415
416## changing the working directory [examples](https://github.com/steveukx/git-js/blob/main/examples/git-change-working-directory.md)
417
418- `.cwd(workingDirectory)` Sets the working directory for all future commands - note, this will change the working for the root instance, any chain created from the root will also be changed.
419- `.cwd({ path, root = false })` Sets the working directory for all future commands either in the current chain of commands (where `root` is omitted or set to `false`) or in the main instance (where `root` is `true`).
420
421## How to Specify Options
422
423Where the task accepts custom options (eg: `pull` or `commit`), these can be supplied as an object, the keys of which
424will all be merged as trailing arguments in the command string, or as a simple array of strings.
425
426### Options as an Object
427
428When the value of the property in the options object is a `string`, that name value
429pair will be included in the command string as `name=value`. For example:
430
431```javascript
432// results in 'git pull origin master --no-rebase'
433git.pull('origin', 'master', { '--no-rebase': null });
434
435// results in 'git pull origin master --rebase=true'
436git.pull('origin', 'master', { '--rebase': 'true' });
437```
438
439### Options as an Array
440
441Options can also be supplied as an array of strings to be merged into the task's commands
442in the same way as when an object is used:
443
444```javascript
445// results in 'git pull origin master --no-rebase'
446git.pull('origin', 'master', ['--no-rebase']);
447```
448
449# Release History
450
451Major release 3.x changes the packaging of the library, making it consumable as a CommonJS module, ES module as well as
452with TypeScript (see [usage](#usage) above). The library is now published as a single file, so please ensure your
453application hasn't been making use of non-documented APIs by importing from a sub-directory path.
454
455See also:
456
457- [release notes v3](https://github.com/steveukx/git-js/blob/main/simple-git/CHANGELOG.md)
458- [release notes v2](https://github.com/steveukx/git-js/blob/main/docs/RELEASE-NOTES-V2.md)
459
460# Concurrent / Parallel Requests
461
462When the methods of `simple-git` are chained together, they create an execution chain that will run in series, useful
463for when the tasks themselves are order-dependent, eg:
464
465```typescript
466simpleGit().init().addRemote('origin', 'https://some-repo.git').fetch();
467```
468
469Each task requires that the one before it has been run successfully before it is called, any errors in a
470step of the chain should prevent later steps from being attempted.
471
472When the methods of `simple-git` are called on the root instance (ie: `git = simpleGit()`) rather than chained
473off another task, it starts a new chain and will not be affected failures in tasks already being run. Useful
474for when the tasks are independent of each other, eg:
475
476```typescript
477const git = simpleGit();
478const results = await Promise.all([
479 git.raw('rev-parse', '--show-cdup').catch(swallow),
480 git.raw('rev-parse', '--show-prefix').catch(swallow),
481]);
482function swallow(err) {
483 return null;
484}
485```
486
487Each `simple-git` instance limits the number of spawned child processes that can be run simultaneously and
488manages the queue of pending tasks for you. Configure this value by passing an options object to the
489`simpleGit` function, eg:
490
491```typescript
492const git = simpleGit({ maxConcurrentProcesses: 10 });
493```
494
495Treating tasks called on the root instance as the start of separate chains is a change to the behaviour of
496`simple-git` and was added in version `2.11.0`.
497
498# Complex Requests
499
500When no suitable wrapper exists in the interface for creating a request, run the command directly
501using `git.raw([...], handler)`. The array of commands are passed directly to the `git` binary:
502
503```javascript
504const path = '/path/to/repo';
505const commands = ['config', '--global', 'advice.pushNonFastForward', 'false'];
506
507// using an array of commands and node-style callback
508simpleGit(path).raw(commands, (err, result) => {
509 // err is null unless this command failed
510 // result is the raw output of this command
511});
512
513// using a var-args of strings and awaiting rather than using the callback
514const result = await simpleGit(path).raw(...commands);
515
516// automatically trim trailing white-space in responses
517const result = await simpleGit(path, { trimmed: true }).raw(...commands);
518```
519
520# Authentication
521
522The easiest way to supply a username / password to the remote host is to include it in the URL, for example:
523
524```javascript
525const USER = 'something';
526const PASS = 'somewhere';
527const REPO = 'github.com/username/private-repo';
528
529const remote = `https://${USER}:${PASS}@${REPO}`;
530
531simpleGit()
532 .clone(remote)
533 .then(() => console.log('finished'))
534 .catch((err) => console.error('failed: ', err));
535```
536
537Be sure to not enable debug logging when using this mechanism for authentication
538to ensure passwords aren't logged to stdout.
539
540# Environment Variables
541
542Pass one or more environment variables to the child processes spawned by `simple-git` with the `.env` method which
543supports passing either an object of name=value pairs or setting a single variable at a time:
544
545```javascript
546const GIT_SSH_COMMAND = 'ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no';
547
548simpleGit()
549 .env('GIT_SSH_COMMAND', GIT_SSH_COMMAND)
550 .status((err, status) => {
551 /* */
552 });
553
554simpleGit()
555 .env({ ...process.env, GIT_SSH_COMMAND })
556 .status()
557 .then((status) => {})
558 .catch((err) => {});
559```
560
561Note - when passing environment variables into the child process, these will replace the standard `process.env`
562variables, the example above creates a new object based on `process.env` but with the `GIT_SSH_COMMAND` property added.
563
564# Exception Handling
565
566When the `git` process exits with a non-zero status (or in some cases like `merge` the git process exits with a
567successful zero code but there are conflicts in the merge) the task will reject with a `GitError` when there is no
568available parser to handle the error or a
569`GitResponseError` for when there is.
570
571See the `err` property of the callback:
572
573```javascript
574git.merge((err, mergeSummary) => {
575 if (err.git) {
576 mergeSummary = err.git; // the failed mergeSummary
577 }
578});
579```
580
581Catch errors with try/catch in async code:
582
583```javascript
584try {
585 const mergeSummary = await git.merge();
586 console.log(`Merged ${mergeSummary.merges.length} files`);
587} catch (err) {
588 // err.message - the string summary of the error
589 // err.stack - some stack trace detail
590 // err.git - where a parser was able to run, this is the parsed content
591
592 console.error(`Merge resulted in ${err.git.conflicts.length} conflicts`);
593}
594```
595
596Catch errors with a `.catch` on the promise:
597
598```javascript
599const mergeSummary = await git.merge().catch((err) => {
600 if (err.git) {
601 return err.git;
602 } // the unsuccessful mergeSummary
603 throw err; // some other error, so throw
604});
605
606if (mergeSummary.failed) {
607 console.error(`Merge resulted in ${mergeSummary.conflicts.length} conflicts`);
608}
609```
610
611With typed errors available in TypeScript
612
613```typescript
614import { simpleGit, MergeSummary, GitResponseError } from 'simple-git';
615try {
616 const mergeSummary = await simpleGit().merge();
617 console.log(`Merged ${mergeSummary.merges.length} files`);
618} catch (err) {
619 // err.message - the string summary of the error
620 // err.stack - some stack trace detail
621 // err.git - where a parser was able to run, this is the parsed content
622 const mergeSummary: MergeSummary = (err as GitResponseError<MergeSummary>).git;
623 const conflicts = mergeSummary?.conflicts || [];
624
625 console.error(`Merge resulted in ${conflicts.length} conflicts`);
626}
627```
628
629# Troubleshooting / FAQ
630
631### Enable logging
632
633See the [debug logging guide](https://github.com/steveukx/git-js/blob/main/docs/DEBUG-LOGGING-GUIDE.md) for logging examples and how to
634make use of the [debug](https://www.npmjs.com/package/debug) library's programmatic interface
635in your application.
636
637### Enable Verbose Logging
638
639See the [debug logging guide](https://github.com/steveukx/git-js/blob/main/docs/DEBUG-LOGGING-GUIDE.md#verbose-logging-options) for
640the full list of verbose logging options to use with the
641[debug](https://www.npmjs.com/package/debug) library.
642
643### Every command returns ENOENT error message
644
645There are a few potential reasons:
646
647- `git` isn't available as a binary for the user running the main `node` process, custom paths to the binary can be used
648 with the `.customBinary(...)` API option.
649
650- the working directory passed in to the main `simple-git` function isn't accessible, check it is read/write accessible
651 by the user running the `node` process. This library uses
652 [@kwsites/file-exists](https://www.npmjs.com/package/@kwsites/file-exists) to validate the working directory exists,
653 to output its logs add `@kwsites/file-exists` to your `DEBUG` environment variable. eg:
654
655 `DEBUG=@kwsites/file-exists,simple-git node ./your-app.js`
656
657### Log format fails
658
659The properties of `git log` are fetched using the `--pretty=format` argument which supports different tokens depending
660on the version of `git` - for example the `%D` token used to show the refs was added in git `2.2.3`, for any version
661before that please ensure you are supplying your own format object with properties supported by the version of git you
662are using.
663
664For more details of the supported tokens, please see the
665[official `git log` documentation](https://git-scm.com/docs/git-log#_pretty_formats)
666
667### Log response properties are out of order
668
669The properties of `git.log` are fetched using the character sequence `ò` as a delimiter. If your commit messages
670use this sequence, supply a custom `splitter` in the options, for example: `git.log({ splitter: '💻' })`
671
672### Pull / Diff / Merge summary responses don't recognise any files
673
674- Enable verbose logs with the environment variable `DEBUG=simple-git:task:*,simple-git:output:*`
675- Check the output (for example: `simple-git:output:diff:1 [stdOut] 1 file changed, 1 insertion(+)`)
676- Check the `stdOut` output is the same as you would expect to see when running the command directly in terminal
677- Check the language used in the response is english locale
678
679In some cases `git` will show progress messages or additional detail on error states in the output for
680`stdErr` that will help debug your issue, these messages are also included in the verbose log.
681
682### Legacy Node Versions
683
684From `v3.x`, `simple-git` will drop support for `node.js` version 10 or below, to use in a lower version of node will
685result in errors such as:
686
687- `Object.fromEntries is not a function`
688- `Object.entries is not a function`
689- `message.flatMap is not a function`
690
691To resolve these issues, either upgrade to a newer version of node.js or ensure you are using the necessary polyfills
692from `core-js` - see [Legacy Node Versions](https://github.com/steveukx/git-js/blob/main/docs/LEGACY_NODE_VERSIONS.md).
693
694# Examples
695
696### using a pathspec to limit the scope of the task
697
698If the `simple-git` API doesn't explicitly limit the scope of the task being run (ie: `git.add()` requires the files to
699be added, but `git.status()` will run against the entire repo), add a `pathspec` to the command using trailing options:
700
701```typescript
702import { simpleGit, pathspec } from "simple-git";
703
704const git = simpleGit();
705const wholeRepoStatus = await git.status();
706const subDirStatusUsingOptArray = await git.status([pathspec('sub-dir')]);
707const subDirStatusUsingOptObject = await git.status({ 'sub-dir': pathspec('sub-dir') });
708```
709
710### async await
711
712```javascript
713async function status(workingDir) {
714 let statusSummary = null;
715 try {
716 statusSummary = await simpleGit(workingDir).status();
717 } catch (e) {
718 // handle the error
719 }
720
721 return statusSummary;
722}
723
724// using the async function
725status(__dirname + '/some-repo').then((status) => console.log(status));
726```
727
728### Initialise a git repo if necessary
729
730```javascript
731const git = simpleGit(__dirname);
732
733git.checkIsRepo()
734 .then((isRepo) => !isRepo && initialiseRepo(git))
735 .then(() => git.fetch());
736
737function initialiseRepo(git) {
738 return git.init().then(() => git.addRemote('origin', 'https://some.git.repo'));
739}
740```
741
742### Update repo and get a list of tags
743
744```javascript
745simpleGit(__dirname + '/some-repo')
746 .pull()
747 .tags((err, tags) => console.log('Latest available tag: %s', tags.latest));
748
749// update repo and when there are changes, restart the app
750simpleGit().pull((err, update) => {
751 if (update && update.summary.changes) {
752 require('child_process').exec('npm restart');
753 }
754});
755```
756
757### Starting a new repo
758
759```javascript
760simpleGit()
761 .init()
762 .add('./*')
763 .commit('first commit!')
764 .addRemote('origin', 'https://github.com/user/repo.git')
765 .push('origin', 'master');
766```
767
768### push with `-u`
769
770```javascript
771simpleGit()
772 .add('./*')
773 .commit('first commit!')
774 .addRemote('origin', 'some-repo-url')
775 .push(['-u', 'origin', 'master'], () => console.log('done'));
776```
777
778### Piping to the console for long-running tasks
779
780See [progress events](https://github.com/steveukx/git-js/blob/main/docs/PLUGIN-PROGRESS-EVENTS.md) for more details on
781logging progress updates.
782
783```javascript
784const git = simpleGit({
785 progress({ method, stage, progress }) {
786 console.log(`git.${method} ${stage} stage ${progress}% complete`);
787 },
788});
789git.checkout('https://github.com/user/repo.git');
790```
791
792### Update repo and print messages when there are changes, restart the app
793
794```javascript
795// when using a chain
796simpleGit()
797 .exec(() => console.log('Starting pull...'))
798 .pull((err, update) => {
799 if (update && update.summary.changes) {
800 require('child_process').exec('npm restart');
801 }
802 })
803 .exec(() => console.log('pull done.'));
804
805// when using async and optional chaining
806const git = simpleGit();
807console.log('Starting pull...');
808if ((await git.pull())?.summary.changes) {
809 require('child_process').exec('npm restart');
810}
811console.log('pull done.');
812```
813
814### Get a full commits list, and then only between 0.11.0 and 0.12.0 tags
815
816```javascript
817console.log(await simpleGit().log());
818console.log(await simpleGit().log('0.11.0', '0.12.0'));
819```
820
821### Set the local configuration for author, then author for an individual commit
822
823```javascript
824simpleGit()
825 .addConfig('user.name', 'Some One')
826 .addConfig('user.email', 'some@one.com')
827 .commit('committed as "Some One"', 'file-one')
828 .commit('committed as "Another Person"', 'file-two', {
829 '--author': '"Another Person <another@person.com>"',
830 });
831```
832
833### Get remote repositories
834
835```javascript
836simpleGit().listRemote(['--get-url'], (err, data) => {
837 if (!err) {
838 console.log('Remote url for repository at ' + __dirname + ':');
839 console.log(data);
840 }
841});
842```