History

Update Git documentation (2.30.0)

Simon Legner committed 5 years ago

Commit 3600a9f1 parent 8f17cfa41 files · +4398 −1Browse files

Showing the changes to node_modules/simple-git (24 of 41 files). Show all

Unified · Split

24 files
  1. node_modules/simple-git/LICENSE +20 −0
  2. node_modules/simple-git/package.json +74 −0
  3. node_modules/simple-git/promise.d.ts +576 −0
  4. node_modules/simple-git/promise.js +96 −0
  5. node_modules/simple-git/readme.md +380 −0
  6. node_modules/simple-git/src/git.js +1592 −0
  7. node_modules/simple-git/src/index.js +14 −0
  8. node_modules/simple-git/src/responses/BranchDeleteSummary.js +26 −0
  9. node_modules/simple-git/src/responses/BranchSummary.js +52 −0
  10. node_modules/simple-git/src/responses/CommitSummary.js +60 −0
  11. node_modules/simple-git/src/responses/DiffSummary.js +92 −0
  12. node_modules/simple-git/src/responses/FetchSummary.js +55 −0
  13. node_modules/simple-git/src/responses/FileStatusSummary.js +22 −0
  14. node_modules/simple-git/src/responses/ListLogSummary.js +72 −0
  15. node_modules/simple-git/src/responses/MergeSummary.js +103 −0
  16. node_modules/simple-git/src/responses/MoveSummary.js +32 −0
  17. node_modules/simple-git/src/responses/PullSummary.js +137 −0
  18. node_modules/simple-git/src/responses/StatusSummary.js +188 −0
  19. node_modules/simple-git/src/responses/TagList.js +50 −0
  20. node_modules/simple-git/src/responses/index.js +15 −0
  21. node_modules/simple-git/src/util/deferred.js +10 −0
  22. node_modules/simple-git/src/util/dependencies.js +12 −0
  23. node_modules/simple-git/src/util/exists.js +33 −0
  24. node_modules/simple-git/typings/response.d.ts +220 −0
node_modules/simple-git/LICENSE+20−0
@@ -0,0 +1,20 @@
1+The MIT License (MIT)
2+
3+Copyright (c) 2015 Steve King
4+
5+Permission is hereby granted, free of charge, to any person obtaining a copy of
6+this software and associated documentation files (the "Software"), to deal in
7+the Software without restriction, including without limitation the rights to
8+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9+the Software, and to permit persons to whom the Software is furnished to do so,
10+subject to the following conditions:
11+
12+The above copyright notice and this permission notice shall be included in all
13+copies or substantial portions of the Software.
14+
15+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
node_modules/simple-git/package.json+74−0
@@ -0,0 +1,74 @@
1+{
2+ "_from": "simple-git@^1.70.0",
3+ "_id": "simple-git@1.132.0",
4+ "_inBundle": false,
5+ "_integrity": "sha512-xauHm1YqCTom1sC9eOjfq3/9RKiUA9iPnxBbrY2DdL8l4ADMu0jjM5l5lphQP5YWNqAL2aXC/OeuQ76vHtW5fg==",
6+ "_location": "/simple-git",
7+ "_phantomChildren": {},
8+ "_requested": {
9+ "type": "range",
10+ "registry": true,
11+ "raw": "simple-git@^1.70.0",
12+ "name": "simple-git",
13+ "escapedName": "simple-git",
14+ "rawSpec": "^1.70.0",
15+ "saveSpec": null,
16+ "fetchSpec": "^1.70.0"
17+ },
18+ "_requiredBy": [
19+ "/bulk-decaffeinate"
20+ ],
21+ "_resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.132.0.tgz",
22+ "_shasum": "53ac4c5ec9e74e37c2fd461e23309f22fcdf09b1",
23+ "_spec": "simple-git@^1.70.0",
24+ "_where": "/home/simon/src/devdocs/node_modules/bulk-decaffeinate",
25+ "author": {
26+ "name": "Steve King",
27+ "email": "steve@mydev.co"
28+ },
29+ "bugs": {
30+ "url": "https://github.com/steveukx/git-js/issues"
31+ },
32+ "bundleDependencies": false,
33+ "contributors": [
34+ {
35+ "name": "Steve King",
36+ "email": "steve@mydev.co"
37+ }
38+ ],
39+ "dependencies": {
40+ "debug": "^4.0.1"
41+ },
42+ "deprecated": false,
43+ "description": "Simple GIT interface for node.js",
44+ "devDependencies": {
45+ "@kwsites/test-runner": "^0.1.1",
46+ "sinon": "^7.3.2"
47+ },
48+ "files": [
49+ "promise.*",
50+ "src/",
51+ "typings/"
52+ ],
53+ "homepage": "https://github.com/steveukx/git-js#readme",
54+ "keywords": [
55+ "git",
56+ "source control",
57+ "vcs"
58+ ],
59+ "license": "MIT",
60+ "main": "./src/index.js",
61+ "name": "simple-git",
62+ "repository": {
63+ "type": "git",
64+ "url": "git://github.com/steveukx/git-js.git"
65+ },
66+ "scripts": {
67+ "postversion": "npm publish && git push && git push --tags",
68+ "preversion": "yarn test",
69+ "test": "runner test/**/test*.js ",
70+ "test:integration": "runner test/integration/test*.js",
71+ "test:unit": "runner test/unit/test*.js"
72+ },
73+ "version": "1.132.0"
74+}
node_modules/simple-git/promise.d.ts+576−0
@@ -0,0 +1,576 @@
1+import * as resp from "./typings/response";
2+
3+declare function simplegit(basePath?: string): simplegit.SimpleGit;
4+
5+declare namespace simplegit {
6+
7+ interface SimpleGit {
8+ /**
9+ * Adds one or more files to source control
10+ *
11+ * @param {string|string[]} files
12+ * @returns {Promise<void>}
13+ */
14+ add(files: string | string[]): Promise<void>;
15+
16+ /**
17+ * Add an annotated tag to the head of the current branch
18+ *
19+ * @param {string} tagName
20+ * @param {string} tagMessage
21+ * @returns {Promise<void>}
22+ */
23+ addAnnotatedTag(tagName: string, tagMessage: string): Promise<void>;
24+
25+ /**
26+ * Add config to local git instance
27+ *
28+ * @param {string} key configuration key (e.g user.name)
29+ * @param {string} value for the given key (e.g your name)
30+ * @returns {Promise<string>}
31+ */
32+ addConfig(key: string, value: string): Promise<string>;
33+
34+ /**
35+ * Adds a remote to the list of remotes.
36+ *
37+ * @param {string} remoteName Name of the repository - eg "upstream"
38+ * @param {string} remoteRepo Fully qualified SSH or HTTP(S) path to the remote repo
39+ * @returns {Promise<void>}
40+ */
41+ addRemote(remoteName: string, remoteRepo: string): Promise<void>;
42+
43+ /**
44+ * Add a lightweight tag to the head of the current branch
45+ *
46+ * @param {string} name
47+ * @returns {Promise<string>}
48+ */
49+ addTag(name: string): Promise<string>;
50+
51+ /**
52+ * Equivalent to `catFile` but will return the native `Buffer` of content from the git command's stdout.
53+ *
54+ * @param {string[]} options
55+ */
56+ binaryCatFile(options: string[]): Promise<any>;
57+
58+ /**
59+ * List all branches
60+ */
61+ branch(): Promise<BranchSummary>;
62+ branch(options: Options | string[]): Promise<BranchSummary>;
63+
64+ /**
65+ * List of local branches
66+ *
67+ * @returns {Promise<BranchSummary>}
68+ */
69+ branchLocal(): Promise<BranchSummary>;
70+
71+ /**
72+ * Returns a list of objects in a tree based on commit hash.
73+ * Passing in an object hash returns the object's content, size, and type.
74+ *
75+ * Passing "-p" will instruct cat-file to determine the object type, and display its formatted contents.
76+ *
77+ * @param {string[]} [options]
78+ * @returns {Promise<string>}
79+ *
80+ * @see https://git-scm.com/docs/git-cat-file
81+ */
82+ catFile(options: string[]): Promise<string>;
83+
84+ /**
85+ * Check if a pathname or pathnames are excluded by .gitignore
86+ *
87+ * @param {string|string[]} pathnames
88+ */
89+ checkIgnore(pathnames: string[]): Promise<string[]>;
90+
91+ checkIgnore(path: string): Promise<string[]>;
92+
93+ /**
94+ * Validates that the current repo is a Git repo.
95+ *
96+ * @returns {Promise<boolean>}
97+ */
98+ checkIsRepo(): Promise<boolean>;
99+
100+ /**
101+ * Checkout a tag or revision, any number of additional arguments can be passed to the `git* checkout` command
102+ by supplying either a string or array of strings as the `what` parameter.
103+ *
104+ * @param {(string | string[])} what one or more commands to pass to `git checkout`.
105+ * @returns {Promise<void>}
106+ */
107+ checkout(what: string | string[]): Promise<void>;
108+
109+ /**
110+ * Checkout a remote branch.
111+ *
112+ * @param {string} branchName name of branch.
113+ * @param {string} startPoint (e.g origin/development).
114+ * @returns {Promise<void>}
115+ */
116+ checkoutBranch(branchName: string, startPoint: string): Promise<void>;
117+
118+ /**
119+ * Internally uses pull and tags to get the list of tags then checks out the latest tag.
120+ */
121+ checkoutLatestTag(branchName: string, startPoint: string): Promise<void>;
122+
123+ /**
124+ * Checkout a local branch
125+ *
126+ * @param {string} branchName name of branch.
127+ * @returns {Promise<void>}
128+ */
129+ checkoutLocalBranch(branchName: string): Promise<void>;
130+
131+ /**
132+ * @param {string} mode Required parameter "n" or "f"
133+ * @param {string[]} options
134+ */
135+ clean(
136+ mode: 'd' | 'f' | 'i' | 'n' | 'q' | 'x' | 'X',
137+ options?: string[]
138+ ): Promise<string>;
139+
140+ /**
141+ * Clears the queue of pending commands and returns the wrapper instance for chaining.
142+ */
143+ clearQueue(): this;
144+
145+ /**
146+ * Clone a repository into a new directory.
147+ *
148+ * @param {string} repoPath repository url to clone e.g. https://github.com/steveukx/git-js.git
149+ * @param {string} localPath local folder path to clone to.
150+ * @param {string[]} [options] options supported by [git](https://git-scm.com/docs/git-clone).
151+ * @returns {Promise<void>}
152+ */
153+ clone(repoPath: string, localPath: string, options?: Options | string[]): Promise<string>;
154+ clone(repoPath: string, options?: Options | string[]): Promise<string>;
155+
156+ /**
157+ * Commits changes in the current working directory - when specific file paths are supplied, only changes on those
158+ * files will be committed.
159+ *
160+ * @param {string|string[]} message
161+ * @param {string|string[]} [files]
162+ * @param {Object} [options]
163+ */
164+ commit(
165+ message: string | string[],
166+ files?: string | string[],
167+ options?: Options
168+ ): Promise<resp.CommitSummary>;
169+
170+ /**
171+ * Sets the path to a custom git binary, should either be `git` when there is an installation of git available on
172+ * the system path, or a fully qualified path to the executable.
173+ *
174+ * @param {string} command
175+ */
176+ customBinary(command: string): this;
177+
178+ /**
179+ * Sets the working directory of the subsequent commands.
180+ *
181+ * @param {string} workingDirectory
182+ */
183+ cwd<path extends string>(workingDirectory: path): Promise<path>;
184+
185+ /**
186+ * Delete a local branch
187+ *
188+ * @param {string} branchName name of branch
189+ */
190+ deleteLocalBranch(branchName: string):
191+ Promise<resp.BranchDeletionSummary>;
192+
193+ /**
194+ * Get the diff of the current repo compared to the last commit with a set of options supplied as a string.
195+ *
196+ * @param {string[]} [options] options supported by [git](https://git-scm.com/docs/git-diff).
197+ * @returns {Promise<string>} raw string result.
198+ */
199+ diff(options?: string[]): Promise<string>;
200+
201+ /**
202+ * Gets a summary of the diff for files in the repo, uses the `git diff --stat` format to calculate changes.
203+ *
204+ * in order to get staged (only): `--cached` or `--staged`.
205+ *
206+ * @param {string[]} [options] options supported by [git](https://git-scm.com/docs/git-diff).
207+ * @returns {Promise<DiffResult>} Parsed diff summary result.
208+ */
209+ diffSummary(options?: string[]): Promise<DiffResult>;
210+
211+ /**
212+ * Sets an environment variable for the spawned child process, either supply both a name and value as strings or
213+ * a single object to entirely replace the current environment variables.
214+ *
215+ * @param {string|Object} name
216+ * @param {string} [value]
217+ */
218+ env(name: string, value: string): this;
219+
220+ env(env: object): this;
221+
222+ /**
223+ * Updates the local working copy database with changes from the default remote repo and branch.
224+ *
225+ * @param {string | string[]} [remote] remote to fetch from.
226+ * @param {string} [branch] branch to fetch from.
227+ * @param {string[]} [options] options supported by [git](https://git-scm.com/docs/git-fetch).
228+ * @returns {Promise<FetchResult>} Parsed fetch result.
229+ */
230+ fetch(remote?: string | string[], branch?: string, options?: Options): Promise<FetchResult>;
231+
232+ /**
233+ * Gets the currently available remotes, setting the optional verbose argument to true includes additional
234+ * detail on the remotes themselves.
235+ *
236+ * @param {boolean} [verbose=false]
237+ */
238+ getRemotes(verbose: false | undefined): Promise<resp.RemoteWithoutRefs[]>;
239+
240+ getRemotes(verbose: true): Promise<resp.RemoteWithRefs[]>;
241+
242+ /**
243+ * Initialize a git repo
244+ *
245+ * @param {Boolean} [bare=false]
246+ */
247+ init(bare?: boolean): Promise<void>;
248+
249+ /**
250+ * List remote
251+ *
252+ * @param {string[]} [args]
253+ */
254+ listRemote(args: string[]): Promise<string>;
255+
256+ /**
257+ * Show commit logs from `HEAD` to the first commit.
258+ * If provided between `options.from` and `options.to` tags or branch.
259+ *
260+ * You can provide `options.file`, which is the path to a file in your repository. Then only this file will be considered.
261+ *
262+ * To use a custom splitter in the log format, set `options.splitter` to be the string the log should be split on.
263+ *
264+ * By default the following fields will be part of the result:
265+ * `hash`: full commit hash
266+ * `date`: author date, ISO 8601-like format
267+ * `message`: subject + ref names, like the --decorate option of git-log
268+ * `author_name`: author name
269+ * `author_email`: author mail
270+ * You can specify `options.format` to be an mapping from key to a format option like `%H` (for commit hash).
271+ * The fields specified in `options.format` will be the fields in the result.
272+ *
273+ * Options can also be supplied as a standard options object for adding custom properties supported by the git log command.
274+ * For any other set of options, supply options as an array of strings to be appended to the git log command.
275+ *
276+ * @param {LogOptions} [options]
277+ *
278+ * @returns Promise<ListLogSummary>
279+ *
280+ * @see https://git-scm.com/docs/git-log
281+ */
282+ log<T = resp.DefaultLogFields>(options?: LogOptions<T>): Promise<resp.ListLogSummary<T>>;
283+
284+ /**
285+ * Runs a merge, `options` can be either an array of arguments
286+ * supported by the [`git merge`](https://git-scm.com/docs/git-merge)
287+ * or an options object.
288+ *
289+ * Conflicts during the merge result in an error response,
290+ * the response type whether it was an error or success will be a MergeSummary instance.
291+ * When successful, the MergeSummary has all detail from a the PullSummary
292+ *
293+ * @param {Options | string[]} [options] options supported by [git](https://git-scm.com/docs/git-merge).
294+ * @returns {Promise<any>}
295+ *
296+ * @see https://github.com/steveukx/git-js/blob/master/src/responses/MergeSummary.js
297+ * @see https://github.com/steveukx/git-js/blob/master/src/responses/PullSummary.js
298+ */
299+ merge(options: Options | string[]): Promise<MergeSummary>;
300+
301+ /**
302+ * Merges from one branch to another, equivalent to running `git merge ${from} $[to}`, the `options` argument can
303+ * either be an array of additional parameters to pass to the command or null / omitted to be ignored.
304+ *
305+ * @param {string} from branch to merge from.
306+ * @param {string} to branch to merge to.
307+ * @param {string[]} [options] options supported by [git](https://git-scm.com/docs/git-merge).
308+ * @returns {Promise<string>}
309+ */
310+ mergeFromTo(from: string, to: string, options?: string[]): Promise<string>;
311+
312+ /**
313+ * Mirror a git repo
314+ *
315+ * @param {string} repoPath
316+ * @param {string} localPath
317+ */
318+ mirror(repoPath: string, localPath: string): Promise<string>;
319+
320+ /**
321+ * Moves one or more files to a new destination.
322+ *
323+ * @see https://git-scm.com/docs/git-mv
324+ *
325+ * @param {string|string[]} from
326+ * @param {string} to
327+ */
328+ mv(from: string | string[], to: string): Promise<resp.MoveSummary>;
329+
330+ /**
331+ * Sets a handler function to be called whenever a new child process is created, the handler function will be called
332+ * with the name of the command being run and the stdout & stderr streams used by the ChildProcess.
333+ *
334+ * @example
335+ * require('simple-git')
336+ * .outputHandler(function (command, stdout, stderr) {
337+ * stdout.pipe(process.stdout);
338+ * })
339+ * .checkout('https://github.com/user/repo.git');
340+ *
341+ * @see https://nodejs.org/api/child_process.html#child_process_class_childprocess
342+ * @see https://nodejs.org/api/stream.html#stream_class_stream_readable
343+ * @param {Function} outputHandler
344+ */
345+ outputHandler(handler: outputHandler | void): this;
346+
347+ /**
348+ * Fetch from and integrate with another repository or a local branch.
349+ *
350+ * @param {string} [remote] remote to pull from.
351+ * @param {string} [branch] branch to pull from.
352+ * @param {Options} [options] options supported by [git](https://git-scm.com/docs/git-pull).
353+ * @returns {Promise<PullResult>} Parsed pull result.
354+ */
355+ pull(remote?: string, branch?: string, options?: Options): Promise<PullResult>;
356+
357+ /**
358+ * Update remote refs along with associated objects.
359+ *
360+ * @param {string} [remote] remote to push to.
361+ * @param {string} [branch] branch to push to.
362+ * @param {Options} [options] options supported by [git](https://git-scm.com/docs/git-push).
363+ * @returns {Promise<void>}
364+ */
365+ push(remote?: string, branch?: string, options?: Options): Promise<void>;
366+
367+ /**
368+ * Pushes the current tag changes to a remote which can be either a URL or named remote. When not specified uses the
369+ * default configured remote spec.
370+ *
371+ * @param {string} [remote]
372+ */
373+ pushTags(remote?: string): Promise<string>;
374+
375+ /**
376+ * Executes any command against the git binary.
377+ *
378+ * @param {string[]|Object} commands
379+ */
380+ raw(commands: string | string[]): Promise<string>;
381+
382+ /**
383+ * Rebases the current working copy. Options can be supplied either as an array of string parameters
384+ * to be sent to the `git rebase` command, or a standard options object.
385+ *
386+ * @param {Object|String[]} [options]
387+ */
388+ rebase(options?: Options | string[]): Promise<string>;
389+
390+ /**
391+ * Call any `git remote` function with arguments passed as an array of strings.
392+ *
393+ * @param {string[]} options
394+ */
395+ remote(options: string[]): Promise<void | string>;
396+
397+ /**
398+ * Removes an entry from the list of remotes.
399+ *
400+ * @param {string} remoteName Name of the repository - eg "upstream"
401+ * @returns {*}
402+ */
403+ removeRemote(remote: string): Promise<void>;
404+
405+ /**
406+ * Reset a repo
407+ *
408+ * @param {string|string[]} [mode=soft] Either an array of arguments supported by the 'git reset' command, or the string value 'soft' or 'hard' to set the reset mode.
409+ */
410+ reset(mode?: 'soft' | 'mixed' | 'hard' | 'merge' | 'keep'): Promise<null>;
411+
412+ reset(commands?: string[]): Promise<void>;
413+
414+ /**
415+ * Revert one or more commits in the local working copy
416+ *
417+ * @param {string} commit The commit to revert. Can be any hash, offset (eg: `HEAD~2`) or range (eg: `master~5..master~2`)
418+ * @param {Object} [options] Optional options object
419+ */
420+ revert(commit: String, options?: Options): Promise<void>;
421+
422+ /**
423+ * Wraps `git rev-parse`. Primarily used to convert friendly commit references (ie branch names) to SHA1 hashes.
424+ *
425+ * Options should be an array of string options compatible with the `git rev-parse`
426+ *
427+ * @param {string[]} [options]
428+ *
429+ * @returns Promise<string>
430+ *
431+ * @see https://git-scm.com/docs/git-rev-parse
432+ */
433+ revparse(options?: string[]): Promise<string>;
434+
435+ /**
436+ * Removes the named files from source control.
437+ *
438+ * @param {string|string[]} files
439+ */
440+ rm(paths: string | string[]): Promise<void>;
441+
442+ /**
443+ * Removes the named files from source control but keeps them on disk rather than deleting them entirely. To
444+ * completely remove the files, use `rm`.
445+ *
446+ * @param {string|string[]} files
447+ */
448+ rmKeepLocal(paths: string | string[]): Promise<void>;
449+
450+ /**
451+ * Show various types of objects, for example the file at a certain commit
452+ *
453+ * @param {string[]} [options]
454+ */
455+ show(options?: string[]): Promise<string>;
456+
457+ /**
458+ * Disables/enables the use of the console for printing warnings and errors, by default messages are not shown in
459+ * a production environment.
460+ *
461+ * @param {boolean} silence
462+ * @returns {simplegit.SimpleGit}
463+ */
464+ silent(silence?: boolean): simplegit.SimpleGit;
465+
466+ /**
467+ * Stash the local repo
468+ *
469+ * @param {Object|Array} [options]
470+ */
471+ stash(options?: Options | any[]): Promise<string>;
472+
473+ /**
474+ * List the stash(s) of the local repo
475+ *
476+ * @param {Object|Array} [options]
477+ */
478+ stashList(options?: Options | string[]): Promise<resp.ListLogSummary>;
479+
480+ /**
481+ * Show the working tree status.
482+ *
483+ * @returns {Promise<StatusResult>} Parsed status result.
484+ */
485+ status(): Promise<StatusResult>;
486+
487+ /**
488+ * Call any `git submodule` function with arguments passed as an array of strings.
489+ *
490+ * @param {string[]} options
491+ */
492+ subModule(options: string[]): Promise<string>;
493+
494+ /**
495+ * Add a submodule
496+ *
497+ * @param {string} repo
498+ * @param {string} path
499+ */
500+ submoduleAdd(repo: string, path: string): Promise<void>;
501+
502+ /**
503+ * Initialize submodules
504+ *
505+ * @param {string[]} [args]
506+ */
507+ submoduleInit(options?: string[]): Promise<string>;
508+
509+ /**
510+ * Update submodules
511+ *
512+ * @param {string[]} [args]
513+ */
514+ submoduleUpdate(options?: string[]): Promise<string>;
515+
516+ /**
517+ * List all tags. When using git 2.7.0 or above, include an options object with `"--sort": "property-name"` to
518+ * sort the tags by that property instead of using the default semantic versioning sort.
519+ *
520+ * Note, supplying this option when it is not supported by your Git version will cause the operation to fail.
521+ *
522+ * @param {Object} [options]
523+ */
524+ tag(options?: Options | string[]): Promise<string>;
525+
526+ /**
527+ * Gets a list of tagged versions.
528+ *
529+ * @param {Options} options
530+ * @returns {Promise<TagResult>} Parsed tag list.
531+ */
532+ tags(options?: Options): Promise<TagResult>;
533+
534+ /**
535+ * Updates repository server info
536+ */
537+ updateServerInfo(): Promise<string>;
538+ }
539+
540+ type Options = { [key: string]: null | string | any };
541+
542+ type LogOptions<T = resp.DefaultLogFields> = Options & {
543+ format?: T;
544+ file?: string;
545+ from?: string;
546+ multiLine?: boolean;
547+ symmetric?: boolean;
548+ to?: string;
549+ };
550+
551+ // responses
552+ // ---------------------
553+ interface BranchSummary extends resp.BranchSummary {}
554+
555+ interface CommitSummary extends resp.CommitSummary {}
556+
557+ interface MergeSummary extends resp.MergeSummary {}
558+
559+ interface PullResult extends resp.PullResult {}
560+
561+ interface FetchResult extends resp.FetchResult {}
562+
563+ interface StatusResult extends resp.StatusResult {}
564+
565+ interface DiffResult extends resp.DiffResult {}
566+
567+ interface TagResult extends resp.TagResult {}
568+
569+ type outputHandler = (
570+ command: string,
571+ stdout: NodeJS.ReadableStream,
572+ stderr: NodeJS.ReadableStream
573+ ) => void
574+}
575+
576+export = simplegit;
node_modules/simple-git/promise.js+96−0
@@ -0,0 +1,96 @@
1+
2+if (typeof Promise === 'undefined') {
3+ throw new ReferenceError("Promise wrappers must be enabled to use the promise API");
4+}
5+
6+function isAsyncCall (fn) {
7+ return /^[^)]+then\s*\)/.test(fn) || /\._run\(/.test(fn);
8+}
9+
10+module.exports = function (baseDir) {
11+
12+ var Git = require('./src/git');
13+ var gitFactory = require('./src');
14+ var git;
15+
16+
17+ var chain = Promise.resolve();
18+
19+ try {
20+ git = gitFactory(baseDir);
21+ }
22+ catch (e) {
23+ chain = Promise.reject(e);
24+ }
25+
26+ return Object.keys(Git.prototype).reduce(function (promiseApi, fn) {
27+ if (/^_|then/.test(fn)) {
28+ return promiseApi;
29+ }
30+
31+ if (isAsyncCall(Git.prototype[fn])) {
32+ promiseApi[fn] = git ? asyncWrapper(fn, git) : function () {
33+ return chain;
34+ };
35+ }
36+
37+ else {
38+ promiseApi[fn] = git ? syncWrapper(fn, git, promiseApi) : function () {
39+ return promiseApi;
40+ };
41+ }
42+
43+ return promiseApi;
44+
45+ }, {});
46+
47+ function asyncWrapper (fn, git) {
48+ return function () {
49+ var args = [].slice.call(arguments);
50+
51+ if (typeof args[args.length] === 'function') {
52+ throw new TypeError(
53+ "Promise interface requires that handlers are not supplied inline, " +
54+ "trailing function not allowed in call to " + fn);
55+ }
56+
57+ return chain.then(function () {
58+ return new Promise(function (resolve, reject) {
59+ args.push(function (err, result) {
60+ if (err) {
61+ return reject(toError(err));
62+ }
63+
64+ resolve(result);
65+ });
66+
67+ git[fn].apply(git, args);
68+ });
69+ });
70+ };
71+ }
72+
73+ function syncWrapper (fn, git, api) {
74+ return function () {
75+ git[fn].apply(git, arguments);
76+
77+ return api;
78+ };
79+ }
80+
81+};
82+
83+function toError (error) {
84+
85+ if (error instanceof Error) {
86+ return error;
87+ }
88+
89+ if (typeof error === 'string') {
90+ return new Error(error);
91+ }
92+
93+ return Object.create(new Error(error), {
94+ git: { value: error },
95+ });
96+}
node_modules/simple-git/readme.md+380−0
@@ -0,0 +1,380 @@
1+# Simple Git
2+[![NPM version](https://img.shields.io/npm/v/simple-git.svg)](https://www.npmjs.com/package/simple-git) [![Build Status](https://travis-ci.org/steveukx/git-js.svg?branch=master)](https://travis-ci.org/steveukx/git-js)
3+
4+A light weight interface for running git commands in any [node.js](https://nodejs.org) application.
5+
6+# Installation
7+
8+Easiest through [npm](https://npmjs.org): `npm install simple-git`
9+
10+# Dependencies
11+
12+Requires [git](https://git-scm.com/downloads) to be installed and that it can be called using the command `git`.
13+
14+# Usage
15+
16+Include into your app using:
17+
18+```js
19+const simpleGit = require('simple-git')(workingDirPath);
20+```
21+
22+> where the `workingDirPath` is optional, defaulting to the current directory.
23+
24+Use `simpleGit` by chaining any of its functions together. Each function accepts an optional final argument which will
25+be called when that step has been completed. When it is called it has two arguments - firstly an error object (or null
26+when no error occurred) and secondly the data generated by that call.
27+
28+| API | What it does |
29+|-----|--------------|
30+| `.add([fileA, ...], handlerFn)` | adds one or more files to be under source control |
31+| `.addAnnotatedTag(tagName, tagMessage, handlerFn)` | adds an annotated tag to the head of the current branch |
32+| `.addConfig(key, value[, handlerFn])` | add a local configuration property |
33+| `.addRemote(name, repo, handlerFn)` | adds a new named remote to be tracked as `name` at the path `repo` |
34+| `.addTag(name, handlerFn)` | adds a lightweight tag to the head of the current branch |
35+| `.branch([options, ][handlerFn])` | gets a list of all branches, calls `handlerFn` with two arguments, an error object and [BranchSummary](src/responses/BranchSummary.js) instance. When supplied, the options can be either an array of arguments supported by the [branch](https://git-scm.com/docs/git-branch) command or a standard [options](#how-to-specify-options) object. |
36+| `.branchLocal([handlerFn])` | gets a list of local branches, calls `handlerFn` with two arguments, an error object and [BranchSummary](src/responses/BranchSummary.js) instance |
37+| `.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 |
38+| `.checkIgnore([filepath, ...], handlerFn)` | checks if filepath excluded by .gitignore rules |
39+| `.checkIsRepo(handlerFn)` | Determines whether the current working directory is part of a git repository, the handler will be called with standard error object and a boolean response. |
40+| `.checkout(checkoutWhat, handlerFn)` | checks out the supplied tag, revision or branch. `checkoutWhat` can be one or more strings to be used as parameters appended to the `git checkout` command. |
41+| `.checkoutBranch(branchName, startPoint, handlerFn)` | checks out a new branch from the supplied start point |
42+| `.checkoutLatestTag(handlerFn)` | convenience method to pull then checkout the latest tag |
43+| `.checkoutLocalBranch(branchName, handlerFn)` | checks out a new local branch |
44+| `.clean(mode [, options [, handlerFn]])` | clean the working tree. Mode should be "n" - dry run or "f" - force |
45+| `.clearQueue()` | immediately clears the queue of pending tasks (note: any command currently in progress will still call its completion callback) |
46+| `.clone(repoPath, [localPath, [options]], [handlerFn])` | clone a remote repo at `repoPath` to a local directory at `localPath` (can be omitted to use the default of a directory with the same name as the repo name) with an optional array of additional arguments to include between `git clone` and the trailing `repo local` arguments |
47+| `.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) |
48+| `.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 |
49+| `.customBinary(gitPath)` | sets the command to use to reference git, allows for using a git binary not available on the path environment variable |
50+| `.cwd(workingDirectory)` | Sets the current working directory for all commands after this step in the chain |
51+| `.deleteLocalBranch(branchName, handlerFn)` | deletes a local branch |
52+| `.diff(options, handlerFn)` | get the diff of the current repo compared to the last commit with a set of options supplied as a string |
53+| `.diff(handlerFn)` | get the diff for all file in the current repo compared to the last commit |
54+| `.diffSummary(handlerFn)` | gets a summary of the diff for files in the repo, uses the `git diff --stat` format to calculate changes. Handler is called with a nullable error object and an instance of the [DiffSummary](src/responses/DiffSummary.js) |
55+| `.diffSummary(options, handlerFn)` | includes options in the call to `diff --stat options` and returns a [DiffSummary](src/responses/DiffSummary.js) |
56+| `.env(name, value)` | Set environment variables to be passed to the spawned child processes, [see usage in detail below](#environment-variables). |
57+| `.exec(handlerFn)` | calls a simple function in the current step |
58+| `.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). On success, the returned data will be an instance of the [FetchSummary](src/responses/FetchSummary.js) |
59+| `.fetch(remote, branch, handlerFn)` | update the local working copy database with changes from a remote repo |
60+| `.fetch(handlerFn)` | update the local working copy database with changes from the default remote repo and branch |
61+| `.getRemotes([verbose], handlerFn)` | gets a list of the named remotes, when the verbose option is supplied as true, includes the URLs and purpose of each ref |
62+| `.init(bare, handlerFn)` | initialize a repository, optional `bare` parameter makes intialized repository bare |
63+| `.listRemote([args], handlerFn)` | 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 `args` array of strings eg: `git.listRemote(['--heads', '--tags'], console.log.bind(console))` |
64+| `.log([options], handlerFn)` | list commits between `options.from` and `options.to` tags or branch (if not specified will show all history). Additionally you can provide `options.file`, which is the path to a file in your repository. Then only this file will be considered. `options.symmetric` allows you to specify whether you want to use [symmetric revision range](https://git-scm.com/docs/gitrevisions#_dotted_range_notations) (To be compatible, by default, its value is true). For any other set of options, supply `options` as an array of strings to be appended to the `git log` command. To use a custom splitter in the log format, set `options.splitter` to be the string the log should be split on. Set `options.multiLine` to true to include a multi-line body in the output format. Options can also be supplied as a standard [options](#how-to-specify-options) object for adding custom properties supported by the [git log](https://git-scm.com/docs/git-log) command. |
65+| `.mergeFromTo(from, to, [[options,] handlerFn])` | merge from one branch to another, when supplied the options should be an array of additional parameters to pass into the [git merge](https://git-scm.com/docs/git-merge) command |
66+| `.merge(options, handlerFn)` | runs a merge, `options` can be either an array of arguments supported by the [git merge](https://git-scm.com/docs/git-merge) command or an [options](#how-to-specify-options) object. Conflicts during the merge result in an error response, the response type whether it was an error or success will be a [MergeSummary](src/responses/MergeSummary.js) instance. When successful, the MergeSummary has all detail from a the [PullSummary](src/responses/PullSummary.js) |
67+| `.mirror(repoPath, localPath, handlerFn])` | clone and mirror the repo to local |
68+| `.mv(from, to, handlerFn])` | rename or move a single file at `from` to `to`. On success the `handlerFn` will be called with a [MoveSummary](src/responses/MoveSummary.js) |
69+| `.mv(from, to, handlerFn])` | move all files in the `from` array to the `to` directory. On success the `handlerFn` will be called with a [MoveSummary](src/responses/MoveSummary.js) |
70+| `.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 |
71+| `.pull(handlerFn)` | Pulls all updates from the default tracked repo |
72+| `.pull(remote, branch, handlerFn)` | pull all updates from the specified remote branch (eg 'origin'/'master') |
73+| `.pull(remote, branch, options, handlerFn)` | Pulls from named remote with any necessary options |
74+| `.push(remote, branch[, options] handlerFn)` | pushes to a named remote/branch, supports additional [options](#how-to-specify-options) from the [git push](https://git-scm.com/docs/git-push) command. |
75+| `.pushTags(remote, handlerFn)` | pushes tags to a named remote |
76+| `.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 commmand will be treated as an error, otherwise treated as a success. |
77+| `.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). |
78+| `.removeRemote(name, handlerFn)` | removes the named remote |
79+| `.reset([resetMode,] handlerFn)` | resets the repository, the optional first argument can either be an array of options supported by the `git reset` command or one of the string constants `mixed`, `hard`, or `soft`, if omitted the reset will be a soft reset to head, handlerFn: (err) |
80+| `.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). |
81+| `.revparse([options], handlerFn)` | wraps git rev-parse. Primarily used to convert friendly commit references (ie branch names) to SHA1 hashes. Options should be an array of string options compatible with the [git rev-parse](https://git-scm.com/docs/git-rev-parse) |
82+| `.rm([fileA, ...], handlerFn)` | removes any number of files from source control |
83+| `.rmKeepLocal([fileA, ...], handlerFn)` | removes files from source control but leaves them on disk |
84+| `.silent(isSilent)` | sets whether the console should be used for logging errors (defaults to `true` when the `NODE_ENV` contains the string `prod`) |
85+| `.stash([options, ][ handlerFn])` | 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. |
86+| `.stashList([options, ][handlerFn])` | Retrieves the stash list, optional first argument can be an object specifying `options.splitter` to override the default value of `;;;;`, alternatively options can be a set of arguments as supported by the `git stash list` command. |
87+| `.subModule(args [, handlerFn])` | Run a `git submodule` command with on or more arguments passed in as an `args` array |
88+| `.submoduleAdd(repo, path[, handlerFn])` | adds a new sub module |
89+| `.submoduleInit([args, ][handlerFn])` | inits sub modules, args should be an array of string arguments to pass to the `git submodule init` command |
90+| `.submoduleUpdate([args, ][handlerFn])` | updates sub modules, args should be an array of string arguments to pass to the `git submodule update` command |
91+| `.tag(args[], handlerFn)` | Runs any supported [git tag](https://git-scm.com/docs/git-tag) commands with arguments passed as an array of strings . |
92+| `.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. |
93+| `.show([options], handlerFn)` | Show various types of objects, for example the file content at a certain commit. `options` is the single value string or array of string commands you want to run |
94+| `.status(handlerFn)` | gets the status of the current repo |
95+
96+# How to Specify Options
97+
98+For `.pull` or `.commit` options are included as an object, the keys of which will all be merged as trailing
99+arguments in the command string. When the value of the property in the options object is a `string`, that name value
100+pair will be included in the command string as `name=value`. For example:
101+
102+```js
103+// results in 'git pull origin master --no-rebase'
104+git().pull('origin', 'master', {'--no-rebase': null})
105+
106+// results in 'git pull origin master --rebase=true'
107+git().pull('origin', 'master', {'--rebase': 'true'})
108+```
109+
110+# Release History
111+
112+Bumped to a new major revision in the 1.x branch, now uses `ChildProcess.spawn` in place of `ChildProcess.exec` to
113+add escaping to the arguments passed to each of the tasks.
114+
115+# Deprecated APIs
116+
117+Use of these APIs is deprecated and should be avoided as support for them will be removed in future release:
118+
119+`.then(func)` In versions 1.72 and below, it was possible to add a regular function call to the queue of tasks to be
120+ run. As this name clashes with the use of Promises, in version 1.73.0 it is renamed to `.exec(fn)` and a warning will
121+ be logged to `stdout` if `.then` is used. From version 2.0 the library will support promises without the need to wrap
122+ or use the alternative require `require('simple-git/promise')`.
123+
124+`.log([from, to], handlerFn)` list commits between `from` and `to` tags or branch, switch to supplying the revisions
125+as an options object instead.
126+
127+# Complex Requests
128+
129+When no suitable wrapper exists in the interface for creating a request, it is possible to run a command directly
130+using `git.raw([...], handler)`. The array of commands are passed directly to the `git` binary:
131+
132+```js
133+const git = require('simple-git');
134+const path = '/path/to/repo';
135+
136+git(path).raw(
137+[
138+ 'config',
139+ '--global',
140+ 'advice.pushNonFastForward',
141+ 'false'
142+], (err, result) => {
143+
144+ // err is null unless this command failed
145+ // result is the raw output of this command
146+
147+});
148+```
149+
150+# Authentication
151+
152+The easiest way to supply a username / password to the remote host is to include it in the URL, for example:
153+
154+```js
155+const USER = 'something';
156+const PASS = 'somewhere';
157+const REPO = 'github.com/username/private-repo';
158+
159+const git = require('simple-git/promise');
160+const remote = `https://${USER}:${PASS}@${REPO}`;
161+
162+git().silent(true)
163+ .clone(remote)
164+ .then(() => console.log('finished'))
165+ .catch((err) => console.error('failed: ', err));
166+
167+```
168+
169+Be sure to enable silent mode to prevent fatal errors from being logged to stdout.
170+
171+# Environment Variables
172+
173+Pass one or more environment variables to the child processes spawned by `simple-git` with the `.env` method which
174+supports passing either an object of name=value pairs or setting a single variable at a time:
175+
176+```js
177+const GIT_SSH_COMMAND = "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no";
178+
179+const git = require('simple-git');
180+
181+git()
182+ .env('GIT_SSH_COMMAND', GIT_SSH_COMMAND)
183+ .status((err, status) => { /* */ })
184+
185+
186+const gitP = require('simple-git/promise');
187+
188+gitP().env({ ...process.env, GIT_SSH_COMMAND })
189+ .status()
190+ .then(status => { })
191+ .catch(err => {});
192+
193+```
194+
195+Note - when passing environment variables into the child process, these will replace the standard `process.env`
196+variables, the example above creates a new object based on `process.env` but with the `GIT_SSH_COMMAND` property
197+added.
198+
199+# TypeScript
200+
201+To import with TypeScript:
202+
203+```typescript
204+import gitP, { SimpleGit, StatusResult } from 'simple-git/promise';
205+
206+const git: SimpleGit = gitP();
207+const status: StatusResult = await git.status();
208+```
209+
210+# Promise and async compatible
211+
212+To work with promises (either directly or as part of async/await), load the promise wrappers library:
213+
214+```js
215+const simpleGit = require('simple-git/promise');
216+const git = simpleGit();
217+
218+const status = await git.status();
219+```
220+
221+Exceptions (generally recognised by the git process exiting with a non-zero status, or in some cases
222+like `merge` the git process exits with a successful zero code but there are conflicts in the merge)
223+should be handled by catching:
224+
225+```js
226+try {
227+ const mergeSummary = await git.merge();
228+ console.log(`Merged ${ mergeSummary.merges.length } files`);
229+}
230+catch (err) {
231+ // err.message - the string summary of the error
232+ // err.stack - some stack trace detail
233+ // err.git - where a parser was able to run, this is the parsed content
234+
235+ console.error(`Merge resulted in ${ err.git.conflicts.length } conflicts`);
236+}
237+```
238+
239+# Response Object Revisions
240+
241+| Class | Version | Change |
242+| ListLogLine | v1.110.0 | The default format expression used in `.log` splits ref data out of the `message` into a property of its own: `{ message: 'Some commit message (some-branch-name)' }` becomes `{ message: 'Some commit message', refs: 'some-branch-name' }` |
243+| ListLogLine | v1.110.0 | The commit body content is now included in the default format expression and can be used to identify the content of merge conflicts eg: `{ body: '# Conflicts:\n# some-file.txt' }` |
244+
245+# Troubleshooting
246+
247+### Every command returns ENOENT error message
248+
249+There are a few potential reasons:
250+
251+- `git` isn't available as a binary for the user running the main `node` process, custom paths to the binary can be used
252+ with the `.customBinary(...)` api option.
253+- the working directory passed in to the main `simple-git` function isn't accessible, check it is read/write accessible
254+ by the user running the `node` process.
255+
256+### Log response properties are out of order
257+
258+The properties of `git.log` are fetched using a `;` as a delimiter. If your commit messages use the `;` character,
259+supply a custom `splitter` in the options, for example: `git.log({ splitter: '|||' })`
260+
261+# Examples
262+
263+### async await with simple-git/promise:
264+
265+```js
266+async function status (workingDir) {
267+ const git = require('simple-git/promise');
268+
269+ let statusSummary = null;
270+ try {
271+ statusSummary = await git(workingDir).status();
272+ }
273+ catch (e) {
274+ // handle the error
275+ }
276+
277+ return statusSummary;
278+}
279+
280+// using the async function
281+status(__dirname + '/some-repo').then(status => console.log(status));
282+```
283+
284+### Initialise a git repo if necessary
285+```js
286+const gitP = require('simple-git/promise');
287+const git = gitP(__dirname);
288+
289+git.checkIsRepo()
290+ .then(isRepo => !isRepo && initialiseRepo(git))
291+ .then(() => git.fetch());
292+
293+function initialiseRepo (git) {
294+ return git.init()
295+ .then(() => git.addRemote('origin', 'https://some.git.repo'))
296+}
297+```
298+
299+### Update repo and get a list of tags
300+```js
301+require('simple-git')(__dirname + '/some-repo')
302+ .pull()
303+ .tags((err, tags) => console.log("Latest available tag: %s", tags.latest));
304+
305+// update repo and when there are changes, restart the app
306+require('simple-git')()
307+ .pull((err, update) => {
308+ if(update && update.summary.changes) {
309+ require('child_process').exec('npm restart');
310+ }
311+ });
312+```
313+
314+### Starting a new repo
315+```js
316+require('simple-git')()
317+ .init()
318+ .add('./*')
319+ .commit("first commit!")
320+ .addRemote('origin', 'https://github.com/user/repo.git')
321+ .push('origin', 'master');
322+```
323+
324+### push with `-u`
325+```js
326+require('simple-git')()
327+ .add('./*')
328+ .commit("first commit!")
329+ .addRemote('origin', 'some-repo-url')
330+ .push(['-u', 'origin', 'master'], () => console.log('done'));
331+```
332+
333+### Piping to the console for long running tasks
334+```js
335+require('simple-git')()
336+ .outputHandler((command, stdout, stderr) => {
337+ stdout.pipe(process.stdout);
338+ stderr.pipe(process.stderr);
339+ })
340+ .checkout('https://github.com/user/repo.git');
341+```
342+
343+### Update repo and print messages when there are changes, restart the app
344+```js
345+require('simple-git')()
346+ .exec(() => console.log('Starting pull...'))
347+ .pull((err, update) => {
348+ if(update && update.summary.changes) {
349+ require('child_process').exec('npm restart');
350+ }
351+ })
352+ .exec(() => console.log('pull done.'));
353+```
354+
355+### Get a full commits list, and then only between 0.11.0 and 0.12.0 tags
356+```js
357+require('simple-git')()
358+ .log((err, log) => console.log(log))
359+ .log('0.11.0', '0.12.0', (err, log) => console.log(log));
360+```
361+
362+### Set the local configuration for author, then author for an individual commit
363+```js
364+require('simple-git')()
365+ .addConfig('user.name', 'Some One')
366+ .addConfig('user.email', 'some@one.com')
367+ .commit('committed as "Some One"', 'file-one')
368+ .commit('committed as "Another Person"', 'file-two', { '--author': '"Another Person <another@person.com>"' });
369+```
370+
371+### Get remote repositories
372+```js
373+require('simple-git')()
374+ .listRemote(['--get-url'], (err, data) => {
375+ if (!err) {
376+ console.log('Remote url for repository at ' + __dirname + ':');
377+ console.log(data);
378+ }
379+ });
380+```
node_modules/simple-git/src/git.js+1592−0
@@ -0,0 +1,1592 @@
1+(function () {
2+
3+ 'use strict';
4+
5+ var debug = require('debug')('simple-git');
6+ var deferred = require('./util/deferred');
7+ var exists = require('./util/exists');
8+ var NOOP = function () {};
9+ var responses = require('./responses');
10+
11+ /**
12+ * Git handling for node. All public functions can be chained and all `then` handlers are optional.
13+ *
14+ * @param {string} baseDir base directory for all processes to run
15+ *
16+ * @param {Object} ChildProcess The ChildProcess module
17+ * @param {Function} Buffer The Buffer implementation to use
18+ *
19+ * @constructor
20+ */
21+ function Git (baseDir, ChildProcess, Buffer) {
22+ this._baseDir = baseDir;
23+ this._runCache = [];
24+
25+ this.ChildProcess = ChildProcess;
26+ this.Buffer = Buffer;
27+ }
28+
29+ /**
30+ * @type {string} The command to use to reference the git binary
31+ */
32+ Git.prototype._command = 'git';
33+
34+ /**
35+ * @type {[key: string]: string} An object of key=value pairs to be passed as environment variables to the
36+ * spawned child process.
37+ */
38+ Git.prototype._env = null;
39+
40+ /**
41+ * @type {Function} An optional handler to use when a child process is created
42+ */
43+ Git.prototype._outputHandler = null;
44+
45+ /**
46+ * @type {boolean} Property showing whether logging will be silenced - defaults to true in a production environment
47+ */
48+ Git.prototype._silentLogging = /prod/.test(process.env.NODE_ENV);
49+
50+ /**
51+ * Sets the path to a custom git binary, should either be `git` when there is an installation of git available on
52+ * the system path, or a fully qualified path to the executable.
53+ *
54+ * @param {string} command
55+ * @returns {Git}
56+ */
57+ Git.prototype.customBinary = function (command) {
58+ this._command = command;
59+ return this;
60+ };
61+
62+ /**
63+ * Sets an environment variable for the spawned child process, either supply both a name and value as strings or
64+ * a single object to entirely replace the current environment variables.
65+ *
66+ * @param {string|Object} name
67+ * @param {string} [value]
68+ * @returns {Git}
69+ */
70+ Git.prototype.env = function (name, value) {
71+ if (arguments.length === 1 && typeof name === 'object') {
72+ this._env = name;
73+ }
74+ else {
75+ (this._env = this._env || {})[name] = value;
76+ }
77+
78+ return this;
79+ };
80+
81+ /**
82+ * Sets the working directory of the subsequent commands.
83+ *
84+ * @param {string} workingDirectory
85+ * @param {Function} [then]
86+ * @returns {Git}
87+ */
88+ Git.prototype.cwd = function (workingDirectory, then) {
89+ var git = this;
90+ var next = Git.trailingFunctionArgument(arguments);
91+
92+ return this.exec(function () {
93+ git._baseDir = workingDirectory;
94+ if (!exists(workingDirectory, exists.FOLDER)) {
95+ Git.exception(git, 'Git.cwd: cannot change to non-directory "' + workingDirectory + '"', next);
96+ }
97+ else {
98+ next && next(null, workingDirectory);
99+ }
100+ });
101+ };
102+
103+ /**
104+ * Sets a handler function to be called whenever a new child process is created, the handler function will be called
105+ * with the name of the command being run and the stdout & stderr streams used by the ChildProcess.
106+ *
107+ * @example
108+ * require('simple-git')
109+ * .outputHandler(function (command, stdout, stderr) {
110+ * stdout.pipe(process.stdout);
111+ * })
112+ * .checkout('https://github.com/user/repo.git');
113+ *
114+ * @see https://nodejs.org/api/child_process.html#child_process_class_childprocess
115+ * @see https://nodejs.org/api/stream.html#stream_class_stream_readable
116+ * @param {Function} outputHandler
117+ * @returns {Git}
118+ */
119+ Git.prototype.outputHandler = function (outputHandler) {
120+ this._outputHandler = outputHandler;
121+ return this;
122+ };
123+
124+ /**
125+ * Initialize a git repo
126+ *
127+ * @param {Boolean} [bare=false]
128+ * @param {Function} [then]
129+ */
130+ Git.prototype.init = function (bare, then) {
131+ var commands = ['init'];
132+ var next = Git.trailingFunctionArgument(arguments);
133+
134+ if (bare === true) {
135+ commands.push('--bare');
136+ }
137+
138+ return this._run(commands, function (err) {
139+ next && next(err);
140+ });
141+ };
142+
143+ /**
144+ * Check the status of the local repo
145+ *
146+ * @param {Function} [then]
147+ */
148+ Git.prototype.status = function (then) {
149+ return this._run(
150+ ['status', '--porcelain', '-b', '-u'],
151+ Git._responseHandler(then, 'StatusSummary')
152+ );
153+ };
154+
155+ /**
156+ * List the stash(s) of the local repo
157+ *
158+ * @param {Object|Array} [options]
159+ * @param {Function} [then]
160+ */
161+ Git.prototype.stashList = function (options, then) {
162+ var handler = Git.trailingFunctionArgument(arguments);
163+ var opt = (handler === then ? options : null) || {};
164+
165+ var splitter = opt.splitter || requireResponseHandler('ListLogSummary').SPLITTER;
166+ var command = ["stash", "list", "--pretty=format:"
167+ + requireResponseHandler('ListLogSummary').START_BOUNDARY
168+ + "%H %ai %s%d %aN %ae".replace(/\s+/g, splitter)
169+ + requireResponseHandler('ListLogSummary').COMMIT_BOUNDARY
170+ ];
171+
172+ if (Array.isArray(opt)) {
173+ command = command.concat(opt);
174+ }
175+
176+ return this._run(command,
177+ Git._responseHandler(handler, 'ListLogSummary', splitter)
178+ );
179+ };
180+
181+ /**
182+ * Stash the local repo
183+ *
184+ * @param {Object|Array} [options]
185+ * @param {Function} [then]
186+ */
187+ Git.prototype.stash = function (options, then) {
188+ var command = ['stash'];
189+ Git._appendOptions(command, Git.trailingOptionsArgument(arguments));
190+ command.push.apply(command, Git.trailingArrayArgument(arguments));
191+
192+ return this._run(command, Git._responseHandler(Git.trailingFunctionArgument(arguments)));
193+ };
194+
195+ /**
196+ * Clone a git repo
197+ *
198+ * @param {string} repoPath
199+ * @param {string} localPath
200+ * @param {String[]} [options] Optional array of options to pass through to the clone command
201+ * @param {Function} [then]
202+ */
203+ Git.prototype.clone = function (repoPath, localPath, options, then) {
204+ var next = Git.trailingFunctionArgument(arguments);
205+ var command = ['clone'].concat(Git.trailingArrayArgument(arguments));
206+
207+ for (var i = 0, iMax = arguments.length; i < iMax; i++) {
208+ if (typeof arguments[i] === 'string') {
209+ command.push(arguments[i]);
210+ }
211+ }
212+
213+ return this._run(command, function (err, data) {
214+ next && next(err, data);
215+ });
216+ };
217+
218+ /**
219+ * Mirror a git repo
220+ *
221+ * @param {string} repoPath
222+ * @param {string} localPath
223+ * @param {Function} [then]
224+ */
225+ Git.prototype.mirror = function (repoPath, localPath, then) {
226+ return this.clone(repoPath, localPath, ['--mirror'], then);
227+ };
228+
229+ /**
230+ * Moves one or more files to a new destination.
231+ *
232+ * @see https://git-scm.com/docs/git-mv
233+ *
234+ * @param {string|string[]} from
235+ * @param {string} to
236+ * @param {Function} [then]
237+ */
238+ Git.prototype.mv = function (from, to, then) {
239+ var handler = Git.trailingFunctionArgument(arguments);
240+
241+ var command = [].concat(from);
242+ command.unshift('mv', '-v');
243+ command.push(to);
244+
245+ this._run(command, Git._responseHandler(handler, 'MoveSummary'))
246+ };
247+
248+ /**
249+ * Internally uses pull and tags to get the list of tags then checks out the latest tag.
250+ *
251+ * @param {Function} [then]
252+ */
253+ Git.prototype.checkoutLatestTag = function (then) {
254+ var git = this;
255+ return this.pull(function () {
256+ git.tags(function (err, tags) {
257+ git.checkout(tags.latest, then);
258+ });
259+ });
260+ };
261+
262+ /**
263+ * Adds one or more files to source control
264+ *
265+ * @param {string|string[]} files
266+ * @param {Function} [then]
267+ */
268+ Git.prototype.add = function (files, then) {
269+ return this._run(['add'].concat(files), function (err, data) {
270+ then && then(err);
271+ });
272+ };
273+
274+ /**
275+ * Commits changes in the current working directory - when specific file paths are supplied, only changes on those
276+ * files will be committed.
277+ *
278+ * @param {string|string[]} message
279+ * @param {string|string[]} [files]
280+ * @param {Object} [options]
281+ * @param {Function} [then]
282+ */
283+ Git.prototype.commit = function (message, files, options, then) {
284+ var handler = Git.trailingFunctionArgument(arguments);
285+
286+ var command = ['commit'];
287+
288+ [].concat(message).forEach(function (message) {
289+ command.push('-m', message);
290+ });
291+
292+ [].push.apply(command, [].concat(typeof files === "string" || Array.isArray(files) ? files : []));
293+
294+ Git._appendOptions(command, Git.trailingOptionsArgument(arguments));
295+
296+ return this._run(
297+ command,
298+ Git._responseHandler(handler, 'CommitSummary')
299+ );
300+ };
301+
302+ /**
303+ * Gets a function to be used for logging.
304+ *
305+ * @param {string} level
306+ * @param {string} [message]
307+ *
308+ * @returns {Function}
309+ * @private
310+ */
311+ Git.prototype._getLog = function (level, message) {
312+ var log = this._silentLogging ? NOOP : console[level].bind(console);
313+ if (arguments.length > 1) {
314+ log(message);
315+ }
316+ return log;
317+ };
318+
319+ /**
320+ * Pull the updated contents of the current repo
321+ *
322+ * @param {string} [remote] When supplied must also include the branch
323+ * @param {string} [branch] When supplied must also include the remote
324+ * @param {Object} [options] Optionally include set of options to merge into the command
325+ * @param {Function} [then]
326+ */
327+ Git.prototype.pull = function (remote, branch, options, then) {
328+ var command = ["pull"];
329+ var handler = Git.trailingFunctionArgument(arguments);
330+
331+ if (typeof remote === 'string' && typeof branch === 'string') {
332+ command.push(remote, branch);
333+ }
334+
335+ Git._appendOptions(command, Git.trailingOptionsArgument(arguments));
336+
337+ return this._run(command, Git._responseHandler(handler, 'PullSummary'));
338+ };
339+
340+ /**
341+ * Fetch the updated contents of the current repo.
342+ *
343+ * @example
344+ * .fetch('upstream', 'master') // fetches from master on remote named upstream
345+ * .fetch(function () {}) // runs fetch against default remote and branch and calls function
346+ *
347+ * @param {string} [remote]
348+ * @param {string} [branch]
349+ * @param {Function} [then]
350+ */
351+ Git.prototype.fetch = function (remote, branch, then) {
352+ var command = ["fetch"];
353+ var next = Git.trailingFunctionArgument(arguments);
354+ Git._appendOptions(command, Git.trailingOptionsArgument(arguments));
355+
356+ if (typeof remote === 'string' && typeof branch === 'string') {
357+ command.push(remote, branch);
358+ }
359+
360+ if (Array.isArray(remote)) {
361+ command = command.concat(remote);
362+ }
363+
364+ return this._run(
365+ command,
366+ Git._responseHandler(next, 'FetchSummary'),
367+ {
368+ concatStdErr: true
369+ }
370+ );
371+ };
372+
373+ /**
374+ * Disables/enables the use of the console for printing warnings and errors, by default messages are not shown in
375+ * a production environment.
376+ *
377+ * @param {boolean} silence
378+ * @returns {Git}
379+ */
380+ Git.prototype.silent = function (silence) {
381+ this._silentLogging = !!silence;
382+ return this;
383+ };
384+
385+ /**
386+ * List all tags. When using git 2.7.0 or above, include an options object with `"--sort": "property-name"` to
387+ * sort the tags by that property instead of using the default semantic versioning sort.
388+ *
389+ * Note, supplying this option when it is not supported by your Git version will cause the operation to fail.
390+ *
391+ * @param {Object} [options]
392+ * @param {Function} [then]
393+ */
394+ Git.prototype.tags = function (options, then) {
395+ var next = Git.trailingFunctionArgument(arguments);
396+
397+ var command = ['-l'];
398+ Git._appendOptions(command, Git.trailingOptionsArgument(arguments));
399+
400+ var hasCustomSort = command.some(function (option) {
401+ return /^--sort=/.test(option);
402+ });
403+
404+ return this.tag(
405+ command,
406+ Git._responseHandler(next, 'TagList', [hasCustomSort])
407+ );
408+ };
409+
410+ /**
411+ * Rebases the current working copy. Options can be supplied either as an array of string parameters
412+ * to be sent to the `git rebase` command, or a standard options object.
413+ *
414+ * @param {Object|String[]} [options]
415+ * @param {Function} [then]
416+ * @returns {Git}
417+ */
418+ Git.prototype.rebase = function (options, then) {
419+ var command = ['rebase'];
420+ Git._appendOptions(command, Git.trailingOptionsArgument(arguments));
421+ command.push.apply(command, Git.trailingArrayArgument(arguments));
422+
423+
424+ return this._run(command, Git._responseHandler(Git.trailingFunctionArgument(arguments)));
425+ };
426+
427+ /**
428+ * Reset a repo
429+ *
430+ * @param {string|string[]} [mode=soft] Either an array of arguments supported by the 'git reset' command, or the
431+ * string value 'soft' or 'hard' to set the reset mode.
432+ * @param {Function} [then]
433+ */
434+ Git.prototype.reset = function (mode, then) {
435+ var command = ['reset'];
436+ var next = Git.trailingFunctionArgument(arguments);
437+ if (next === mode || typeof mode === 'string' || !mode) {
438+ var modeStr = ['mixed', 'soft', 'hard'].includes(mode) ? mode : 'soft';
439+ command.push('--' + modeStr);
440+ }
441+ else if (Array.isArray(mode)) {
442+ command.push.apply(command, mode);
443+ }
444+
445+ return this._run(command, function (err) {
446+ next && next(err || null);
447+ });
448+ };
449+
450+ /**
451+ * Revert one or more commits in the local working copy
452+ *
453+ * @param {string} commit The commit to revert. Can be any hash, offset (eg: `HEAD~2`) or range (eg: `master~5..master~2`)
454+ * @param {Object} [options] Optional options object
455+ * @param {Function} [then]
456+ */
457+ Git.prototype.revert = function (commit, options, then) {
458+ var next = Git.trailingFunctionArgument(arguments);
459+ var command = ['revert'];
460+
461+ Git._appendOptions(command, Git.trailingOptionsArgument(arguments));
462+
463+ if (typeof commit !== 'string') {
464+ return this.exec(function () {
465+ next && next(new TypeError("Commit must be a string"));
466+ });
467+ }
468+
469+ command.push(commit);
470+ return this._run(command, function (err) {
471+ next && next(err || null);
472+ });
473+ };
474+
475+ /**
476+ * Add a lightweight tag to the head of the current branch
477+ *
478+ * @param {string} name
479+ * @param {Function} [then]
480+ */
481+ Git.prototype.addTag = function (name, then) {
482+ if (typeof name !== "string") {
483+ return this.exec(function () {
484+ then && then(new TypeError("Git.addTag requires a tag name"));
485+ });
486+ }
487+
488+ var command = [name];
489+ return then ? this.tag(command, then) : this.tag(command);
490+ };
491+
492+ /**
493+ * Add an annotated tag to the head of the current branch
494+ *
495+ * @param {string} tagName
496+ * @param {string} tagMessage
497+ * @param {Function} [then]
498+ */
499+ Git.prototype.addAnnotatedTag = function (tagName, tagMessage, then) {
500+ return this.tag(['-a', '-m', tagMessage, tagName], function (err) {
501+ then && then(err);
502+ });
503+ };
504+
505+ /**
506+ * Check out a tag or revision, any number of additional arguments can be passed to the `git checkout` command
507+ * by supplying either a string or array of strings as the `what` parameter.
508+ *
509+ * @param {string|string[]} what One or more commands to pass to `git checkout`
510+ * @param {Function} [then]
511+ */
512+ Git.prototype.checkout = function (what, then) {
513+ var command = ['checkout'];
514+ command = command.concat(what);
515+
516+ return this._run(command, function (err, data) {
517+ then && then(err, !err && this._parseCheckout(data));
518+ });
519+ };
520+
521+ /**
522+ * Check out a remote branch
523+ *
524+ * @param {string} branchName name of branch
525+ * @param {string} startPoint (e.g origin/development)
526+ * @param {Function} [then]
527+ */
528+ Git.prototype.checkoutBranch = function (branchName, startPoint, then) {
529+ return this.checkout(['-b', branchName, startPoint], then);
530+ };
531+
532+ /**
533+ * Check out a local branch
534+ *
535+ * @param {string} branchName of branch
536+ * @param {Function} [then]
537+ */
538+ Git.prototype.checkoutLocalBranch = function (branchName, then) {
539+ return this.checkout(['-b', branchName], then);
540+ };
541+
542+ /**
543+ * Delete a local branch
544+ *
545+ * @param {string} branchName name of branch
546+ * @param {Function} [then]
547+ */
548+ Git.prototype.deleteLocalBranch = function (branchName, then) {
549+ return this.branch(['-d', branchName], then);
550+ };
551+
552+ /**
553+ * List all branches
554+ *
555+ * @param {Object | string[]} [options]
556+ * @param {Function} [then]
557+ */
558+ Git.prototype.branch = function (options, then) {
559+ var isDelete, responseHandler;
560+ var next = Git.trailingFunctionArgument(arguments);
561+ var command = ['branch'];
562+
563+ command.push.apply(command, Git.trailingArrayArgument(arguments));
564+ Git._appendOptions(command, Git.trailingOptionsArgument(arguments));
565+
566+ if (!arguments.length || next === options) {
567+ command.push('-a');
568+ }
569+
570+ isDelete = ['-d', '-D', '--delete'].reduce(function (isDelete, flag) {
571+ return isDelete || command.indexOf(flag) > 0;
572+ }, false);
573+
574+ if (command.indexOf('-v') < 0) {
575+ command.splice(1, 0, '-v');
576+ }
577+
578+ responseHandler = isDelete
579+ ? Git._responseHandler(next, 'BranchDeleteSummary', false)
580+ : Git._responseHandler(next, 'BranchSummary');
581+
582+ return this._run(command, responseHandler);
583+ };
584+
585+ /**
586+ * Return list of local branches
587+ *
588+ * @param {Function} [then]
589+ */
590+ Git.prototype.branchLocal = function (then) {
591+ return this.branch(['-v'], then);
592+ };
593+
594+ /**
595+ * Add config to local git instance
596+ *
597+ * @param {string} key configuration key (e.g user.name)
598+ * @param {string} value for the given key (e.g your name)
599+ * @param {Function} [then]
600+ */
601+ Git.prototype.addConfig = function (key, value, then) {
602+ return this._run(['config', '--local', key, value], function (err, data) {
603+ then && then(err, !err && data);
604+ });
605+ };
606+
607+ /**
608+ * Executes any command against the git binary.
609+ *
610+ * @param {string[]|Object} commands
611+ * @param {Function} [then]
612+ *
613+ * @returns {Git}
614+ */
615+ Git.prototype.raw = function (commands, then) {
616+ var command = [];
617+ if (Array.isArray(commands)) {
618+ command = commands.slice(0);
619+ }
620+ else {
621+ Git._appendOptions(command, Git.trailingOptionsArgument(arguments));
622+ }
623+
624+ var next = Git.trailingFunctionArgument(arguments);
625+
626+ if (!command.length) {
627+ return this.exec(function () {
628+ next && next(new Error('Raw: must supply one or more command to execute'), null);
629+ });
630+ }
631+
632+ return this._run(command, function (err, data) {
633+ next && next(err, !err && data || null);
634+ });
635+ };
636+
637+ /**
638+ * Add a submodule
639+ *
640+ * @param {string} repo
641+ * @param {string} path
642+ * @param {Function} [then]
643+ */
644+ Git.prototype.submoduleAdd = function (repo, path, then) {
645+ return this._run(['submodule', 'add', repo, path], function (err) {
646+ then && then(err);
647+ });
648+ };
649+
650+ /**
651+ * Update submodules
652+ *
653+ * @param {string[]} [args]
654+ * @param {Function} [then]
655+ */
656+ Git.prototype.submoduleUpdate = function (args, then) {
657+ if (typeof args === 'string') {
658+ this._getLog('warn', 'Git#submoduleUpdate: args should be supplied as an array of individual arguments');
659+ }
660+
661+ var next = Git.trailingFunctionArgument(arguments);
662+ var command = (args !== next) ? args : [];
663+
664+ return this.subModule(['update'].concat(command), function (err, args) {
665+ next && next(err, args);
666+ });
667+ };
668+
669+ /**
670+ * Initialize submodules
671+ *
672+ * @param {string[]} [args]
673+ * @param {Function} [then]
674+ */
675+ Git.prototype.submoduleInit = function (args, then) {
676+ if (typeof args === 'string') {
677+ this._getLog('warn', 'Git#submoduleInit: args should be supplied as an array of individual arguments');
678+ }
679+
680+ var next = Git.trailingFunctionArgument(arguments);
681+ var command = (args !== next) ? args : [];
682+
683+ return this.subModule(['init'].concat(command), function (err, args) {
684+ next && next(err, args);
685+ });
686+ };
687+
688+ /**
689+ * Call any `git submodule` function with arguments passed as an array of strings.
690+ *
691+ * @param {string[]} options
692+ * @param {Function} [then]
693+ */
694+ Git.prototype.subModule = function (options, then) {
695+ if (!Array.isArray(options)) {
696+ return this.exec(function () {
697+ then && then(new TypeError("Git.subModule requires an array of arguments"));
698+ });
699+ }
700+
701+ if (options[0] !== 'submodule') {
702+ options.unshift('submodule');
703+ }
704+
705+ return this._run(options, function (err, data) {
706+ then && then(err || null, err ? null : data);
707+ });
708+ };
709+
710+ /**
711+ * List remote
712+ *
713+ * @param {string[]} [args]
714+ * @param {Function} [then]
715+ */
716+ Git.prototype.listRemote = function (args, then) {
717+ var next = Git.trailingFunctionArgument(arguments);
718+ var data = next === args || args === undefined ? [] : args;
719+
720+ if (typeof data === 'string') {
721+ this._getLog('warn', 'Git#listRemote: args should be supplied as an array of individual arguments');
722+ }
723+
724+ return this._run(['ls-remote'].concat(data), function (err, data) {
725+ next && next(err, data);
726+ });
727+ };
728+
729+ /**
730+ * Adds a remote to the list of remotes.
731+ *
732+ * @param {string} remoteName Name of the repository - eg "upstream"
733+ * @param {string} remoteRepo Fully qualified SSH or HTTP(S) path to the remote repo
734+ * @param {Function} [then]
735+ * @returns {*}
736+ */
737+ Git.prototype.addRemote = function (remoteName, remoteRepo, then) {
738+ return this._run(['remote', 'add', remoteName, remoteRepo], function (err) {
739+ then && then(err);
740+ });
741+ };
742+
743+ /**
744+ * Removes an entry from the list of remotes.
745+ *
746+ * @param {string} remoteName Name of the repository - eg "upstream"
747+ * @param {Function} [then]
748+ * @returns {*}
749+ */
750+ Git.prototype.removeRemote = function (remoteName, then) {
751+ return this._run(['remote', 'remove', remoteName], function (err) {
752+ then && then(err);
753+ });
754+ };
755+
756+ /**
757+ * Gets the currently available remotes, setting the optional verbose argument to true includes additional
758+ * detail on the remotes themselves.
759+ *
760+ * @param {boolean} [verbose=false]
761+ * @param {Function} [then]
762+ */
763+ Git.prototype.getRemotes = function (verbose, then) {
764+ var next = Git.trailingFunctionArgument(arguments);
765+ var args = verbose === true ? ['-v'] : [];
766+
767+ return this.remote(args, function (err, data) {
768+ next && next(err, !err && function () {
769+ return data.trim().split('\n').filter(Boolean).reduce(function (remotes, remote) {
770+ var detail = remote.trim().split(/\s+/);
771+ var name = detail.shift();
772+
773+ if (!remotes[name]) {
774+ remotes[name] = remotes[remotes.length] = {
775+ name: name,
776+ refs: {}
777+ };
778+ }
779+
780+ if (detail.length) {
781+ remotes[name].refs[detail.pop().replace(/[^a-z]/g, '')] = detail.pop();
782+ }
783+
784+ return remotes;
785+ }, []).slice(0);
786+ }());
787+ });
788+ };
789+
790+ /**
791+ * Call any `git remote` function with arguments passed as an array of strings.
792+ *
793+ * @param {string[]} options
794+ * @param {Function} [then]
795+ */
796+ Git.prototype.remote = function (options, then) {
797+ if (!Array.isArray(options)) {
798+ return this.exec(function () {
799+ then && then(new TypeError("Git.remote requires an array of arguments"));
800+ });
801+ }
802+
803+ if (options[0] !== 'remote') {
804+ options.unshift('remote');
805+ }
806+
807+ return this._run(options, function (err, data) {
808+ then && then(err || null, err ? null : data);
809+ });
810+ };
811+
812+ /**
813+ * Merges from one branch to another, equivalent to running `git merge ${from} $[to}`, the `options` argument can
814+ * either be an array of additional parameters to pass to the command or null / omitted to be ignored.
815+ *
816+ * @param {string} from
817+ * @param {string} to
818+ * @param {string[]} [options]
819+ * @param {Function} [then]
820+ */
821+ Git.prototype.mergeFromTo = function (from, to, options, then) {
822+ var commands = [
823+ from,
824+ to
825+ ];
826+ var callback = Git.trailingFunctionArgument(arguments);
827+
828+ if (Array.isArray(options)) {
829+ commands = commands.concat(options);
830+ }
831+
832+ return this.merge(commands, callback);
833+ };
834+
835+ /**
836+ * Runs a merge, `options` can be either an array of arguments
837+ * supported by the [`git merge`](https://git-scm.com/docs/git-merge)
838+ * or an options object.
839+ *
840+ * Conflicts during the merge result in an error response,
841+ * the response type whether it was an error or success will be a MergeSummary instance.
842+ * When successful, the MergeSummary has all detail from a the PullSummary
843+ *
844+ * @param {Object | string[]} [options]
845+ * @param {Function} [then]
846+ * @returns {*}
847+ *
848+ * @see ./responses/MergeSummary.js
849+ * @see ./responses/PullSummary.js
850+ */
851+ Git.prototype.merge = function (options, then) {
852+ var self = this;
853+ var userHandler = Git.trailingFunctionArgument(arguments) || NOOP;
854+ var mergeHandler = function (err, mergeSummary) {
855+ if (!err && mergeSummary.failed) {
856+ return Git.fail(self, mergeSummary, userHandler);
857+ }
858+
859+ userHandler(err, mergeSummary);
860+ };
861+
862+ var command = [];
863+ Git._appendOptions(command, Git.trailingOptionsArgument(arguments));
864+ command.push.apply(command, Git.trailingArrayArgument(arguments));
865+
866+ if (command[0] !== 'merge') {
867+ command.unshift('merge');
868+ }
869+
870+ if (command.length === 1) {
871+ return this.exec(function () {
872+ then && then(new TypeError("Git.merge requires at least one option"));
873+ });
874+ }
875+
876+ return this._run(command, Git._responseHandler(mergeHandler, 'MergeSummary'), {
877+ concatStdErr: true
878+ });
879+ };
880+
881+ /**
882+ * Call any `git tag` function with arguments passed as an array of strings.
883+ *
884+ * @param {string[]} options
885+ * @param {Function} [then]
886+ */
887+ Git.prototype.tag = function (options, then) {
888+ var command = [];
889+ Git._appendOptions(command, Git.trailingOptionsArgument(arguments));
890+ command.push.apply(command, Git.trailingArrayArgument(arguments));
891+
892+ if (command[0] !== 'tag') {
893+ command.unshift('tag');
894+ }
895+
896+ return this._run(command, Git._responseHandler(Git.trailingFunctionArgument(arguments)));
897+ };
898+
899+ /**
900+ * Updates repository server info
901+ *
902+ * @param {Function} [then]
903+ */
904+ Git.prototype.updateServerInfo = function (then) {
905+ return this._run(["update-server-info"], function (err, data) {
906+ then && then(err, !err && data);
907+ });
908+ };
909+
910+ /**
911+ * Pushes the current committed changes to a remote, optionally specify the names of the remote and branch to use
912+ * when pushing. Supply multiple options as an array of strings in the first argument - see examples below.
913+ *
914+ * @param {string|string[]} [remote]
915+ * @param {string} [branch]
916+ * @param {Function} [then]
917+ */
918+ Git.prototype.push = function (remote, branch, then) {
919+ var command = [];
920+ var handler = Git.trailingFunctionArgument(arguments);
921+
922+ if (typeof remote === 'string' && typeof branch === 'string') {
923+ command.push(remote, branch);
924+ }
925+
926+ if (Array.isArray(remote)) {
927+ command = command.concat(remote);
928+ }
929+
930+ Git._appendOptions(command, Git.trailingOptionsArgument(arguments));
931+
932+ if (command[0] !== 'push') {
933+ command.unshift('push');
934+ }
935+
936+ return this._run(command, function (err, data) {
937+ handler && handler(err, !err && data);
938+ });
939+ };
940+
941+ /**
942+ * Pushes the current tag changes to a remote which can be either a URL or named remote. When not specified uses the
943+ * default configured remote spec.
944+ *
945+ * @param {string} [remote]
946+ * @param {Function} [then]
947+ */
948+ Git.prototype.pushTags = function (remote, then) {
949+ var command = ['push'];
950+ if (typeof remote === "string") {
951+ command.push(remote);
952+ }
953+ command.push('--tags');
954+
955+ then = typeof arguments[arguments.length - 1] === "function" ? arguments[arguments.length - 1] : null;
956+
957+ return this._run(command, function (err, data) {
958+ then && then(err, !err && data);
959+ });
960+ };
961+
962+ /**
963+ * Removes the named files from source control.
964+ *
965+ * @param {string|string[]} files
966+ * @param {Function} [then]
967+ */
968+ Git.prototype.rm = function (files, then) {
969+ return this._rm(files, '-f', then);
970+ };
971+
972+ /**
973+ * Removes the named files from source control but keeps them on disk rather than deleting them entirely. To
974+ * completely remove the files, use `rm`.
975+ *
976+ * @param {string|string[]} files
977+ * @param {Function} [then]
978+ */
979+ Git.prototype.rmKeepLocal = function (files, then) {
980+ return this._rm(files, '--cached', then);
981+ };
982+
983+ /**
984+ * Returns a list of objects in a tree based on commit hash. Passing in an object hash returns the object's content,
985+ * size, and type.
986+ *
987+ * Passing "-p" will instruct cat-file to determine the object type, and display its formatted contents.
988+ *
989+ * @param {string[]} [options]
990+ * @param {Function} [then]
991+ */
992+ Git.prototype.catFile = function (options, then) {
993+ return this._catFile('utf-8', arguments);
994+ };
995+
996+ /**
997+ * Equivalent to `catFile` but will return the native `Buffer` of content from the git command's stdout.
998+ *
999+ * @param {string[]} options
1000+ * @param then
1001+ */
1002+ Git.prototype.binaryCatFile = function (options, then) {
1003+ return this._catFile('buffer', arguments);
1004+ };
1005+
1006+ Git.prototype._catFile = function (format, args) {
1007+ var handler = Git.trailingFunctionArgument(args);
1008+ var command = ['cat-file'];
1009+ var options = args[0];
1010+
1011+ if (typeof options === 'string') {
1012+ throw new TypeError('Git#catFile: options must be supplied as an array of strings');
1013+ }
1014+ else if (Array.isArray(options)) {
1015+ command.push.apply(command, options);
1016+ }
1017+
1018+ return this._run(command, function (err, data) {
1019+ handler && handler(err, data);
1020+ }, {
1021+ format: format
1022+ });
1023+ };
1024+
1025+ /**
1026+ * Return repository changes.
1027+ *
1028+ * @param {string[]} [options]
1029+ * @param {Function} [then]
1030+ */
1031+ Git.prototype.diff = function (options, then) {
1032+ var command = ['diff'];
1033+
1034+ if (typeof options === 'string') {
1035+ command[0] += ' ' + options;
1036+ this._getLog('warn',
1037+ 'Git#diff: supplying options as a single string is now deprecated, switch to an array of strings');
1038+ }
1039+ else if (Array.isArray(options)) {
1040+ command.push.apply(command, options);
1041+ }
1042+
1043+ if (typeof arguments[arguments.length - 1] === 'function') {
1044+ then = arguments[arguments.length - 1];
1045+ }
1046+
1047+ return this._run(command, function (err, data) {
1048+ then && then(err, data);
1049+ });
1050+ };
1051+
1052+ Git.prototype.diffSummary = function (options, then) {
1053+ var next = Git.trailingFunctionArgument(arguments);
1054+ var command = ['--stat=4096'];
1055+
1056+ if (options && options !== next) {
1057+ command.push.apply(command, [].concat(options));
1058+ }
1059+
1060+ return this.diff(command, Git._responseHandler(next, 'DiffSummary'));
1061+ };
1062+
1063+ /**
1064+ * Wraps `git rev-parse`. Primarily used to convert friendly commit references (ie branch names) to SHA1 hashes.
1065+ *
1066+ * Options should be an array of string options compatible with the `git rev-parse`
1067+ *
1068+ * @param {string|string[]} [options]
1069+ * @param {Function} [then]
1070+ *
1071+ * @see https://git-scm.com/docs/git-rev-parse
1072+ */
1073+ Git.prototype.revparse = function (options, then) {
1074+ var command = ['rev-parse'];
1075+
1076+ if (typeof options === 'string') {
1077+ command = command + ' ' + options;
1078+ this._getLog('warn',
1079+ 'Git#revparse: supplying options as a single string is now deprecated, switch to an array of strings');
1080+ }
1081+ else if (Array.isArray(options)) {
1082+ command.push.apply(command, options);
1083+ }
1084+
1085+ if (typeof arguments[arguments.length - 1] === 'function') {
1086+ then = arguments[arguments.length - 1];
1087+ }
1088+
1089+ return this._run(command, function (err, data) {
1090+ then && then(err, err ? null : String(data).trim());
1091+ });
1092+ };
1093+
1094+ /**
1095+ * Show various types of objects, for example the file at a certain commit
1096+ *
1097+ * @param {string[]} [options]
1098+ * @param {Function} [then]
1099+ */
1100+ Git.prototype.show = function (options, then) {
1101+ var args = [].slice.call(arguments, 0);
1102+ var handler = typeof args[args.length - 1] === "function" ? args.pop() : null;
1103+ var command = ['show'];
1104+ if (typeof options === 'string') {
1105+ command = command + ' ' + options;
1106+ this._getLog('warn',
1107+ 'Git#show: supplying options as a single string is now deprecated, switch to an array of strings');
1108+ }
1109+ else if (Array.isArray(options)) {
1110+ command.push.apply(command, options);
1111+ }
1112+
1113+ return this._run(command, function (err, data) {
1114+ handler && handler(err, !err && data);
1115+ });
1116+ };
1117+
1118+ /**
1119+ * @param {string} mode Required parameter "n" or "f"
1120+ * @param {string[]} options
1121+ * @param {Function} [then]
1122+ */
1123+ Git.prototype.clean = function (mode, options, then) {
1124+ var handler = Git.trailingFunctionArgument(arguments);
1125+
1126+ if (typeof mode !== 'string' || !/[nf]/.test(mode)) {
1127+ return this.exec(function () {
1128+ handler && handler(new TypeError('Git clean mode parameter ("n" or "f") is required'));
1129+ });
1130+ }
1131+
1132+ if (/[^dfinqxX]/.test(mode)) {
1133+ return this.exec(function () {
1134+ handler && handler(new TypeError('Git clean unknown option found in ' + JSON.stringify(mode)));
1135+ });
1136+ }
1137+
1138+ var command = ['clean', '-' + mode];
1139+ if (Array.isArray(options)) {
1140+ command = command.concat(options);
1141+ }
1142+
1143+ if (command.some(interactiveMode)) {
1144+ return this.exec(function () {
1145+ handler && handler(new TypeError('Git clean interactive mode is not supported'));
1146+ });
1147+ }
1148+
1149+ return this._run(command, function (err, data) {
1150+ handler && handler(err, !err && data);
1151+ });
1152+
1153+ function interactiveMode (option) {
1154+ if (/^-[^\-]/.test(option)) {
1155+ return option.indexOf('i') > 0;
1156+ }
1157+
1158+ return option === '--interactive';
1159+ }
1160+ };
1161+
1162+ /**
1163+ * Call a simple function at the next step in the chain.
1164+ * @param {Function} [then]
1165+ */
1166+ Git.prototype.exec = function (then) {
1167+ this._run([], function () {
1168+ typeof then === 'function' && then();
1169+ });
1170+ return this;
1171+ };
1172+
1173+ /**
1174+ * Deprecated means of adding a regular function call at the next step in the chain. Use the replacement
1175+ * Git#exec, the Git#then method will be removed in version 2.x
1176+ *
1177+ * @see exec
1178+ * @deprecated
1179+ */
1180+ Git.prototype.then = function (then) {
1181+ this._getLog(
1182+ 'error', `
1183+Git#then is deprecated after version 1.72 and will be removed in version 2.x
1184+To use promises switch to importing 'simple-git/promise'.`);
1185+
1186+ return this.exec(then);
1187+ };
1188+
1189+ /**
1190+ * Show commit logs from `HEAD` to the first commit.
1191+ * If provided between `options.from` and `options.to` tags or branch.
1192+ *
1193+ * Additionally you can provide options.file, which is the path to a file in your repository. Then only this file will be considered.
1194+ *
1195+ * To use a custom splitter in the log format, set `options.splitter` to be the string the log should be split on.
1196+ *
1197+ * Options can also be supplied as a standard options object for adding custom properties supported by the git log command.
1198+ * For any other set of options, supply options as an array of strings to be appended to the git log command.
1199+ *
1200+ * @param {Object|string[]} [options]
1201+ * @param {string} [options.from] The first commit to include
1202+ * @param {string} [options.to] The most recent commit to include
1203+ * @param {string} [options.file] A single file to include in the result
1204+ * @param {boolean} [options.multiLine] Optionally include multi-line commit messages
1205+ *
1206+ * @param {Function} [then]
1207+ */
1208+ Git.prototype.log = function (options, then) {
1209+ var handler = Git.trailingFunctionArgument(arguments);
1210+ var opt = (handler === then ? options : null) || {};
1211+
1212+ var splitter = opt.splitter || requireResponseHandler('ListLogSummary').SPLITTER;
1213+ var format = opt.format || {
1214+ hash: '%H',
1215+ date: '%ai',
1216+ message: '%s',
1217+ refs: '%D',
1218+ body: opt.multiLine ? '%B' : '%b',
1219+ author_name: '%aN',
1220+ author_email: '%ae'
1221+ };
1222+ var rangeOperator = (opt.symmetric !== false) ? '...' : '..';
1223+
1224+ var fields = Object.keys(format);
1225+ var formatstr = fields.map(function (k) {
1226+ return format[k];
1227+ }).join(splitter);
1228+ var suffix = [];
1229+ var command = ["log", "--pretty=format:"
1230+ + requireResponseHandler('ListLogSummary').START_BOUNDARY
1231+ + formatstr
1232+ + requireResponseHandler('ListLogSummary').COMMIT_BOUNDARY
1233+ ];
1234+
1235+ if (Array.isArray(opt)) {
1236+ command = command.concat(opt);
1237+ opt = {};
1238+ }
1239+ else if (typeof arguments[0] === "string" || typeof arguments[1] === "string") {
1240+ this._getLog('warn',
1241+ 'Git#log: supplying to or from as strings is now deprecated, switch to an options configuration object');
1242+ opt = {
1243+ from: arguments[0],
1244+ to: arguments[1]
1245+ };
1246+ }
1247+
1248+ if (opt.n || opt['max-count']) {
1249+ command.push("--max-count=" + (opt.n || opt['max-count']));
1250+ }
1251+
1252+ if (opt.from && opt.to) {
1253+ command.push(opt.from + rangeOperator + opt.to);
1254+ }
1255+
1256+ if (opt.file) {
1257+ suffix.push("--follow", options.file);
1258+ }
1259+
1260+ 'splitter n max-count file from to --pretty format symmetric multiLine'.split(' ').forEach(function (key) {
1261+ delete opt[key];
1262+ });
1263+
1264+ Git._appendOptions(command, opt);
1265+
1266+ return this._run(
1267+ command.concat(suffix),
1268+ Git._responseHandler(handler, 'ListLogSummary', [splitter, fields])
1269+ );
1270+ };
1271+
1272+ /**
1273+ * Clears the queue of pending commands and returns the wrapper instance for chaining.
1274+ *
1275+ * @returns {Git}
1276+ */
1277+ Git.prototype.clearQueue = function () {
1278+ this._runCache.length = 0;
1279+ return this;
1280+ };
1281+
1282+ /**
1283+ * Check if a pathname or pathnames are excluded by .gitignore
1284+ *
1285+ * @param {string|string[]} pathnames
1286+ * @param {Function} [then]
1287+ */
1288+ Git.prototype.checkIgnore = function (pathnames, then) {
1289+ var handler = Git.trailingFunctionArgument(arguments);
1290+ var command = ["check-ignore"];
1291+
1292+ if (handler !== pathnames) {
1293+ command = command.concat(pathnames);
1294+ }
1295+
1296+ return this._run(command, function (err, data) {
1297+ handler && handler(err, !err && this._parseCheckIgnore(data));
1298+ });
1299+ };
1300+
1301+ /**
1302+ * Validates that the current repo is a Git repo.
1303+ *
1304+ * @param {Function} [then]
1305+ */
1306+ Git.prototype.checkIsRepo = function (then) {
1307+ function onError (exitCode, stdErr, done, fail) {
1308+ if (exitCode === 128 && /(Not a git repository|Kein Git-Repository)/i.test(stdErr)) {
1309+ return done(false);
1310+ }
1311+
1312+ fail(stdErr);
1313+ }
1314+
1315+ function handler (err, isRepo) {
1316+ then && then(err, String(isRepo).trim() === 'true');
1317+ }
1318+
1319+ return this._run(['rev-parse', '--is-inside-work-tree'], handler, {onError: onError});
1320+ };
1321+
1322+ Git.prototype._rm = function (_files, options, then) {
1323+ var files = [].concat(_files);
1324+ var args = ['rm', options];
1325+ args.push.apply(args, files);
1326+
1327+ return this._run(args, function (err) {
1328+ then && then(err);
1329+ });
1330+ };
1331+
1332+ Git.prototype._parseCheckout = function (checkout) {
1333+ // TODO
1334+ };
1335+
1336+ /**
1337+ * Parser for the `check-ignore` command - returns each
1338+ * @param {string} [files]
1339+ * @returns {string[]}
1340+ */
1341+ Git.prototype._parseCheckIgnore = function (files) {
1342+ return files.split(/\n/g).filter(Boolean).map(function (file) {
1343+ return file.trim()
1344+ });
1345+ };
1346+
1347+ /**
1348+ * Schedules the supplied command to be run, the command should not include the name of the git binary and should
1349+ * be an array of strings passed as the arguments to the git binary.
1350+ *
1351+ * @param {string[]} command
1352+ * @param {Function} then
1353+ * @param {Object} [opt]
1354+ * @param {boolean} [opt.concatStdErr=false] Optionally concatenate stderr output into the stdout
1355+ * @param {boolean} [opt.format="utf-8"] The format to use when reading the content of stdout
1356+ * @param {Function} [opt.onError] Optional error handler for this command - can be used to allow non-clean exits
1357+ * without killing the remaining stack of commands
1358+ * @param {number} [opt.onError.exitCode]
1359+ * @param {string} [opt.onError.stdErr]
1360+ *
1361+ * @returns {Git}
1362+ */
1363+ Git.prototype._run = function (command, then, opt) {
1364+ if (typeof command === "string") {
1365+ command = command.split(" ");
1366+ }
1367+ this._runCache.push([command, then, opt || {}]);
1368+ this._schedule();
1369+
1370+ return this;
1371+ };
1372+
1373+ Git.prototype._schedule = function () {
1374+ if (!this._childProcess && this._runCache.length) {
1375+ var git = this;
1376+ var Buffer = git.Buffer;
1377+ var task = git._runCache.shift();
1378+
1379+ var command = task[0];
1380+ var then = task[1];
1381+ var options = task[2];
1382+
1383+ debug(command);
1384+
1385+ var result = deferred();
1386+
1387+ var attempted = false;
1388+ var attemptClose = function attemptClose (e) {
1389+
1390+ // closing when there is content, terminate immediately
1391+ if (attempted || stdErr.length || stdOut.length) {
1392+ result.resolve(e);
1393+ attempted = true;
1394+ }
1395+
1396+ // first attempt at closing but no content yet, wait briefly for the close/exit that may follow
1397+ if (!attempted) {
1398+ attempted = true;
1399+ setTimeout(attemptClose.bind(this, e), 50);
1400+ }
1401+
1402+ };
1403+
1404+ var stdOut = [];
1405+ var stdErr = [];
1406+ var spawned = git.ChildProcess.spawn(git._command, command.slice(0), {
1407+ cwd: git._baseDir,
1408+ env: git._env,
1409+ windowsHide: true
1410+ });
1411+
1412+ spawned.stdout.on('data', function (buffer) {
1413+ stdOut.push(buffer);
1414+ });
1415+
1416+ spawned.stderr.on('data', function (buffer) {
1417+ stdErr.push(buffer);
1418+ });
1419+
1420+ spawned.on('error', function (err) {
1421+ stdErr.push(Buffer.from(err.stack, 'ascii'));
1422+ });
1423+
1424+ spawned.on('close', attemptClose);
1425+ spawned.on('exit', attemptClose);
1426+
1427+ result.promise.then(function (exitCode) {
1428+ function done (output) {
1429+ then.call(git, null, output);
1430+ }
1431+
1432+ function fail (error) {
1433+ Git.fail(git, error, then);
1434+ }
1435+
1436+ delete git._childProcess;
1437+
1438+ if (exitCode && stdErr.length && options.onError) {
1439+ options.onError(exitCode, Buffer.concat(stdErr).toString('utf-8'), done, fail);
1440+ }
1441+ else if (exitCode && stdErr.length) {
1442+ fail(Buffer.concat(stdErr).toString('utf-8'));
1443+ }
1444+ else {
1445+ if (options.concatStdErr) {
1446+ [].push.apply(stdOut, stdErr);
1447+ }
1448+
1449+ var stdOutput = Buffer.concat(stdOut);
1450+ if (options.format !== 'buffer') {
1451+ stdOutput = stdOutput.toString(options.format || 'utf-8');
1452+ }
1453+
1454+ done(stdOutput);
1455+ }
1456+
1457+ process.nextTick(git._schedule.bind(git));
1458+ });
1459+
1460+ git._childProcess = spawned;
1461+
1462+ if (git._outputHandler) {
1463+ git._outputHandler(command[0], git._childProcess.stdout, git._childProcess.stderr);
1464+ }
1465+ }
1466+ };
1467+
1468+ /**
1469+ * Handles an exception in the processing of a command.
1470+ */
1471+ Git.fail = function (git, error, handler) {
1472+ git._getLog('error', error);
1473+ git._runCache.length = 0;
1474+ if (typeof handler === 'function') {
1475+ handler.call(git, error, null);
1476+ }
1477+ };
1478+
1479+ /**
1480+ * Given any number of arguments, returns the last argument if it is a function, otherwise returns null.
1481+ * @returns {Function|null}
1482+ */
1483+ Git.trailingFunctionArgument = function (args) {
1484+ var trailing = args[args.length - 1];
1485+ return (typeof trailing === "function") ? trailing : null;
1486+ };
1487+
1488+ /**
1489+ * Given any number of arguments, returns the trailing options argument, ignoring a trailing function argument
1490+ * if there is one. When not found, the return value is null.
1491+ * @returns {Object|null}
1492+ */
1493+ Git.trailingOptionsArgument = function (args) {
1494+ var options = args[(args.length - (Git.trailingFunctionArgument(args) ? 2 : 1))];
1495+ return Object.prototype.toString.call(options) === '[object Object]' ? options : null;
1496+ };
1497+
1498+ /**
1499+ * Given any number of arguments, returns the trailing options array argument, ignoring a trailing function argument
1500+ * if there is one. When not found, the return value is an empty array.
1501+ * @returns {Array}
1502+ */
1503+ Git.trailingArrayArgument = function (args) {
1504+ var options = args[(args.length - (Git.trailingFunctionArgument(args) ? 2 : 1))];
1505+ return Object.prototype.toString.call(options) === '[object Array]' ? options : [];
1506+ };
1507+
1508+ /**
1509+ * Mutates the supplied command array by merging in properties in the options object. When the
1510+ * value of the item in the options object is a string it will be concatenated to the key as
1511+ * a single `name=value` item, otherwise just the name will be used.
1512+ *
1513+ * @param {string[]} command
1514+ * @param {Object} options
1515+ * @private
1516+ */
1517+ Git._appendOptions = function (command, options) {
1518+ if (options === null) {
1519+ return;
1520+ }
1521+
1522+ Object.keys(options).forEach(function (key) {
1523+ var value = options[key];
1524+ if (typeof value === 'string') {
1525+ command.push(key + '=' + value);
1526+ }
1527+ else {
1528+ command.push(key);
1529+ }
1530+ });
1531+ };
1532+
1533+ /**
1534+ * Given the type of response and the callback to receive the parsed response,
1535+ * uses the correct parser and calls back the callback.
1536+ *
1537+ * @param {Function} callback
1538+ * @param {string} [type]
1539+ * @param {Object[]} [args]
1540+ *
1541+ * @private
1542+ */
1543+ Git._responseHandler = function (callback, type, args) {
1544+ return function (error, data) {
1545+ if (typeof callback !== 'function') {
1546+ return;
1547+ }
1548+
1549+ if (error) {
1550+ return callback(error, null);
1551+ }
1552+
1553+ if (!type) {
1554+ return callback(null, data);
1555+ }
1556+
1557+ var handler = requireResponseHandler(type);
1558+ var result = handler.parse.apply(handler, [data].concat(args === undefined ? [] : args));
1559+
1560+ callback(null, result);
1561+ };
1562+
1563+ };
1564+
1565+ /**
1566+ * Marks the git instance as having had a fatal exception by clearing the pending queue of tasks and
1567+ * logging to the console.
1568+ *
1569+ * @param git
1570+ * @param error
1571+ * @param callback
1572+ */
1573+ Git.exception = function (git, error, callback) {
1574+ git._runCache.length = 0;
1575+ if (typeof callback === 'function') {
1576+ callback(error instanceof Error ? error : new Error(error));
1577+ }
1578+
1579+ git._getLog('error', error);
1580+ };
1581+
1582+ module.exports = Git;
1583+
1584+ /**
1585+ * Requires and returns a response handler based on its named type
1586+ * @param {string} type
1587+ */
1588+ function requireResponseHandler (type) {
1589+ return responses[type];
1590+ }
1591+
1592+}());
node_modules/simple-git/src/index.js+14−0
@@ -0,0 +1,14 @@
1+
2+var Git = require('./git');
3+
4+module.exports = function (baseDir) {
5+
6+ var dependencies = require('./util/dependencies');
7+
8+ if (baseDir && !dependencies.exists(baseDir, dependencies.exists.FOLDER)) {
9+ throw new Error("Cannot use simple-git on a directory that does not exist.");
10+ }
11+
12+ return new Git(baseDir || process.cwd(), dependencies.childProcess(), dependencies.buffer());
13+};
14+
node_modules/simple-git/src/responses/BranchDeleteSummary.js+26−0
@@ -0,0 +1,26 @@
1+
2+module.exports = BranchDeletion;
3+
4+function BranchDeletion (branch, hash) {
5+ this.branch = branch;
6+ this.hash = hash;
7+ this.success = hash !== null;
8+}
9+
10+BranchDeletion.deleteSuccessRegex = /(\S+)\s+\(\S+\s([^\)]+)\)/;
11+BranchDeletion.deleteErrorRegex = /^error[^']+'([^']+)'/;
12+
13+BranchDeletion.parse = function (data, asArray) {
14+ var result;
15+ var branchDeletions = data.trim().split('\n').map(function (line) {
16+ if (result = BranchDeletion.deleteSuccessRegex.exec(line)) {
17+ return new BranchDeletion(result[1], result[2]);
18+ }
19+ else if (result = BranchDeletion.deleteErrorRegex.exec(line)) {
20+ return new BranchDeletion(result[1], null);
21+ }
22+ })
23+ .filter(Boolean);
24+
25+ return asArray ? branchDeletions : branchDeletions.pop();
26+};
node_modules/simple-git/src/responses/BranchSummary.js+52−0
@@ -0,0 +1,52 @@
1+
2+module.exports = BranchSummary;
3+
4+function BranchSummary () {
5+ this.detached = false;
6+ this.current = '';
7+ this.all = [];
8+ this.branches = {};
9+}
10+
11+BranchSummary.prototype.push = function (current, detached, name, commit, label) {
12+ if (current) {
13+ this.detached = detached;
14+ this.current = name;
15+ }
16+ this.all.push(name);
17+ this.branches[name] = {
18+ current: current,
19+ name: name,
20+ commit: commit,
21+ label: label
22+ };
23+};
24+
25+BranchSummary.detachedRegex = /^(\*?\s+)\((?:HEAD )?detached (?:from|at) (\S+)\)\s+([a-z0-9]+)\s(.*)$/;
26+BranchSummary.branchRegex = /^(\*?\s+)(\S+)\s+([a-z0-9]+)\s(.*)$/;
27+
28+BranchSummary.parse = function (commit) {
29+ var branchSummary = new BranchSummary();
30+
31+ commit.split('\n')
32+ .forEach(function (line) {
33+ var detached = true;
34+ var branch = BranchSummary.detachedRegex.exec(line);
35+ if (!branch) {
36+ detached = false;
37+ branch = BranchSummary.branchRegex.exec(line);
38+ }
39+
40+ if (branch) {
41+ branchSummary.push(
42+ branch[1].charAt(0) === '*',
43+ detached,
44+ branch[2],
45+ branch[3],
46+ branch[4]
47+ );
48+ }
49+ });
50+
51+ return branchSummary;
52+};
node_modules/simple-git/src/responses/CommitSummary.js+60−0
@@ -0,0 +1,60 @@
1+
2+module.exports = CommitSummary;
3+
4+function CommitSummary () {
5+ this.branch = '';
6+ this.commit = '';
7+ this.summary = {
8+ changes: 0,
9+ insertions: 0,
10+ deletions: 0
11+ };
12+ this.author = null;
13+}
14+
15+var COMMIT_BRANCH_MESSAGE_REGEX = /\[([^\s]+) ([^\]]+)/;
16+var COMMIT_AUTHOR_MESSAGE_REGEX = /\s*Author:\s(.+)/i;
17+
18+function setBranchFromCommit (commitSummary, commitData) {
19+ if (commitData) {
20+ commitSummary.branch = commitData[1];
21+ commitSummary.commit = commitData[2];
22+ }
23+}
24+
25+function setSummaryFromCommit (commitSummary, commitData) {
26+ if (commitSummary.branch && commitData) {
27+ commitSummary.summary.changes = commitData[1] || 0;
28+ commitSummary.summary.insertions = commitData[2] || 0;
29+ commitSummary.summary.deletions = commitData[3] || 0;
30+ }
31+}
32+
33+function setAuthorFromCommit (commitSummary, commitData) {
34+ var parts = commitData[1].split('<');
35+ var email = parts.pop();
36+
37+ if (email.indexOf('@') <= 0) {
38+ return;
39+ }
40+
41+ commitSummary.author = {
42+ email: email.substr(0, email.length - 1),
43+ name: parts.join('<').trim()
44+ };
45+}
46+
47+CommitSummary.parse = function (commit) {
48+ var lines = commit.trim().split('\n');
49+ var commitSummary = new CommitSummary();
50+
51+ setBranchFromCommit(commitSummary, COMMIT_BRANCH_MESSAGE_REGEX.exec(lines.shift()));
52+
53+ if (COMMIT_AUTHOR_MESSAGE_REGEX.test(lines[0])) {
54+ setAuthorFromCommit(commitSummary, COMMIT_AUTHOR_MESSAGE_REGEX.exec(lines.shift()));
55+ }
56+
57+ setSummaryFromCommit(commitSummary, /(\d+)[^,]*(?:,\s*(\d+)[^,]*)?(?:,\s*(\d+))?/g.exec(lines.shift()));
58+
59+ return commitSummary;
60+};
node_modules/simple-git/src/responses/DiffSummary.js+92−0
@@ -0,0 +1,92 @@
1+
2+module.exports = DiffSummary;
3+
4+/**
5+ * The DiffSummary is returned as a response to getting `git().status()`
6+ *
7+ * @constructor
8+ */
9+function DiffSummary () {
10+ this.files = [];
11+ this.insertions = 0;
12+ this.deletions = 0;
13+ this.changed = 0;
14+}
15+
16+/**
17+ * Number of lines added
18+ * @type {number}
19+ */
20+DiffSummary.prototype.insertions = 0;
21+
22+/**
23+ * Number of lines deleted
24+ * @type {number}
25+ */
26+DiffSummary.prototype.deletions = 0;
27+
28+/**
29+ * Number of files changed
30+ * @type {number}
31+ */
32+DiffSummary.prototype.changed = 0;
33+
34+DiffSummary.parse = function (text) {
35+ var line, handler;
36+
37+ var lines = text.trim().split('\n');
38+ var status = new DiffSummary();
39+
40+ var summary = lines.pop();
41+ if (summary) {
42+ summary.trim().split(', ').forEach(function (text) {
43+ var summary = /(\d+)\s([a-z]+)/.exec(text);
44+ if (!summary) {
45+ return;
46+ }
47+
48+ if (/files?/.test(summary[2])) {
49+ status.changed = parseInt(summary[1], 10);
50+ }
51+ else {
52+ status[summary[2].replace(/s$/, '') + 's'] = parseInt(summary[1], 10);
53+ }
54+ });
55+ }
56+
57+ while (line = lines.shift()) {
58+ textFileChange(line, status.files) || binaryFileChange(line, status.files);
59+ }
60+
61+ return status;
62+};
63+
64+function textFileChange (line, files) {
65+ line = line.trim().match(/^(.+)\s+\|\s+(\d+)(\s+[+\-]+)?$/);
66+
67+ if (line) {
68+ var alterations = (line[3] || '').trim();
69+ files.push({
70+ file: line[1].trim(),
71+ changes: parseInt(line[2], 10),
72+ insertions: alterations.replace(/-/g, '').length,
73+ deletions: alterations.replace(/\+/g, '').length,
74+ binary: false
75+ });
76+
77+ return true;
78+ }
79+}
80+
81+function binaryFileChange (line, files) {
82+ line = line.match(/^(.+) \|\s+Bin ([0-9.]+) -> ([0-9.]+) ([a-z]+)$/);
83+ if (line) {
84+ files.push({
85+ file: line[1].trim(),
86+ before: +line[2],
87+ after: +line[3],
88+ binary: true
89+ });
90+ return true;
91+ }
92+}
node_modules/simple-git/src/responses/FetchSummary.js+55−0
@@ -0,0 +1,55 @@
1+'use strict';
2+
3+function FetchSummary (raw) {
4+ this.raw = raw;
5+
6+ this.remote = null;
7+ this.branches = [];
8+ this.tags = [];
9+}
10+
11+FetchSummary.parsers = [
12+ [
13+ /From (.+)$/, function (fetchSummary, matches) {
14+ fetchSummary.remote = matches[0];
15+ }
16+ ],
17+ [
18+ /\* \[new branch\]\s+(\S+)\s*\-> (.+)$/, function (fetchSummary, matches) {
19+ fetchSummary.branches.push({
20+ name: matches[0],
21+ tracking: matches[1]
22+ });
23+ }
24+ ],
25+ [
26+ /\* \[new tag\]\s+(\S+)\s*\-> (.+)$/, function (fetchSummary, matches) {
27+ fetchSummary.tags.push({
28+ name: matches[0],
29+ tracking: matches[1]
30+ });
31+ }
32+ ]
33+];
34+
35+FetchSummary.parse = function (data) {
36+ var fetchSummary = new FetchSummary(data);
37+
38+ String(data)
39+ .trim()
40+ .split('\n')
41+ .forEach(function (line) {
42+ var original = line.trim();
43+ FetchSummary.parsers.some(function (parser) {
44+ var parsed = parser[0].exec(original);
45+ if (parsed) {
46+ parser[1](fetchSummary, parsed.slice(1));
47+ return true;
48+ }
49+ });
50+ });
51+
52+ return fetchSummary;
53+};
54+
55+module.exports = FetchSummary;
node_modules/simple-git/src/responses/FileStatusSummary.js+22−0
@@ -0,0 +1,22 @@
1+'use strict';
2+
3+function FileStatusSummary (path, index, working_dir) {
4+ this.path = path;
5+ this.index = index;
6+ this.working_dir = working_dir;
7+
8+ if ('R' === index + working_dir) {
9+ var detail = FileStatusSummary.fromPathRegex.exec(path) || [null, path, path];
10+ this.from = detail[1];
11+ this.path = detail[2];
12+ }
13+}
14+
15+FileStatusSummary.fromPathRegex = /^(.+) -> (.+)$/;
16+
17+FileStatusSummary.prototype = {
18+ path: '',
19+ from: ''
20+};
21+
22+module.exports = FileStatusSummary;
node_modules/simple-git/src/responses/ListLogSummary.js+72−0
@@ -0,0 +1,72 @@
1+
2+module.exports = ListLogSummary;
3+
4+var DiffSummary = require('./DiffSummary');
5+
6+/**
7+ * The ListLogSummary is returned as a response to getting `git().log()` or `git().stashList()`
8+ *
9+ * @constructor
10+ */
11+function ListLogSummary (all) {
12+ this.all = all;
13+ this.latest = all.length && all[0] || null;
14+ this.total = all.length;
15+}
16+
17+/**
18+ * Detail for each of the log lines
19+ * @type {ListLogLine[]}
20+ */
21+ListLogSummary.prototype.all = null;
22+
23+/**
24+ * Most recent entry in the log
25+ * @type {ListLogLine}
26+ */
27+ListLogSummary.prototype.latest = null;
28+
29+/**
30+ * Number of items in the log
31+ * @type {number}
32+ */
33+ListLogSummary.prototype.total = 0;
34+
35+function ListLogLine (line, fields) {
36+ for (var k = 0; k < fields.length; k++) {
37+ this[fields[k]] = line[k] || '';
38+ }
39+}
40+
41+/**
42+ * When the log was generated with a summary, the `diff` property contains as much detail
43+ * as was provided in the log (whether generated with `--stat` or `--shortstat`.
44+ * @type {DiffSummary}
45+ */
46+ListLogLine.prototype.diff = null;
47+
48+ListLogSummary.START_BOUNDARY = 'òòòòòò ';
49+
50+ListLogSummary.COMMIT_BOUNDARY = ' òò';
51+
52+ListLogSummary.SPLITTER = ' ò ';
53+
54+ListLogSummary.parse = function (text, splitter, fields) {
55+ fields = fields || ['hash', 'date', 'message', 'refs', 'author_name', 'author_email'];
56+ return new ListLogSummary(
57+ text
58+ .trim()
59+ .split(ListLogSummary.START_BOUNDARY)
60+ .filter(function(item) { return !!item.trim(); })
61+ .map(function (item) {
62+ var lineDetail = item.trim().split(ListLogSummary.COMMIT_BOUNDARY);
63+ var listLogLine = new ListLogLine(lineDetail[0].trim().split(splitter), fields);
64+
65+ if (lineDetail.length > 1 && !!lineDetail[1].trim()) {
66+ listLogLine.diff = DiffSummary.parse(lineDetail[1]);
67+ }
68+
69+ return listLogLine;
70+ })
71+ );
72+};
node_modules/simple-git/src/responses/MergeSummary.js+103−0
@@ -0,0 +1,103 @@
1+module.exports = MergeSummary;
2+module.exports.MergeConflict = MergeConflict;
3+
4+var PullSummary = require('./PullSummary');
5+
6+function MergeConflict (reason, file, meta) {
7+ this.reason = reason;
8+ this.file = file;
9+ if (meta) {
10+ this.meta = meta;
11+ }
12+}
13+
14+MergeConflict.prototype.meta = null;
15+
16+MergeConflict.prototype.toString = function () {
17+ return this.file + ':' + this.reason;
18+};
19+
20+function MergeSummary () {
21+ PullSummary.call(this);
22+
23+ this.conflicts = [];
24+ this.merges = [];
25+}
26+
27+MergeSummary.prototype = Object.create(PullSummary.prototype);
28+
29+MergeSummary.prototype.result = 'success';
30+
31+MergeSummary.prototype.toString = function () {
32+ if (this.conflicts.length) {
33+ return 'CONFLICTS: ' + this.conflicts.join(', ');
34+ }
35+ return 'OK';
36+};
37+
38+Object.defineProperty(MergeSummary.prototype, 'failed', {
39+ get: function () {
40+ return this.conflicts.length > 0;
41+ }
42+});
43+
44+MergeSummary.parsers = [
45+ {
46+ test: /^Auto-merging\s+(.+)$/,
47+ handle: function (result, mergeSummary) {
48+ mergeSummary.merges.push(result[1]);
49+ }
50+ },
51+ {
52+ // Parser for standard merge conflicts
53+ test: /^CONFLICT\s+\((.+)\): Merge conflict in (.+)$/,
54+ handle: function (result, mergeSummary) {
55+ mergeSummary.conflicts.push(new MergeConflict(result[1], result[2]));
56+ }
57+ },
58+ {
59+ // Parser for modify/delete merge conflicts (modified by us/them, deleted by them/us)
60+ test: /^CONFLICT\s+\((.+\/delete)\): (.+) deleted in (.+) and/,
61+ handle: function (result, mergeSummary) {
62+ mergeSummary.conflicts.push(
63+ new MergeConflict(result[1], result[2], {deleteRef: result[3]})
64+ );
65+ }
66+ },
67+ {
68+ // Catch-all parser for unknown/unparsed conflicts
69+ test: /^CONFLICT\s+\((.+)\):/,
70+ handle: function (result, mergeSummary) {
71+ mergeSummary.conflicts.push(new MergeConflict(result[1], null));
72+ }
73+ },
74+ {
75+ test: /^Automatic merge failed;\s+(.+)$/,
76+ handle: function (result, mergeSummary) {
77+ mergeSummary.reason = mergeSummary.result = result[1];
78+ }
79+ }
80+];
81+
82+MergeSummary.parse = function (output) {
83+ let mergeSummary = new MergeSummary();
84+
85+ output.trim().split('\n').forEach(function (line) {
86+ for (var i = 0, iMax = MergeSummary.parsers.length; i < iMax; i++) {
87+ let parser = MergeSummary.parsers[i];
88+
89+ var result = parser.test.exec(line);
90+ if (result) {
91+ parser.handle(result, mergeSummary);
92+ break;
93+ }
94+ }
95+ });
96+
97+ let pullSummary = PullSummary.parse(output);
98+ if (pullSummary.summary.changes) {
99+ Object.assign(mergeSummary, pullSummary);
100+ }
101+
102+ return mergeSummary;
103+};
node_modules/simple-git/src/responses/MoveSummary.js+32−0
@@ -0,0 +1,32 @@
1+
2+module.exports = MoveSummary;
3+
4+/**
5+ * The MoveSummary is returned as a response to getting `git().status()`
6+ *
7+ * @constructor
8+ */
9+function MoveSummary () {
10+ this.moves = [];
11+ this.sources = {};
12+}
13+
14+MoveSummary.SUMMARY_REGEX = /^Renaming (.+) to (.+)$/;
15+
16+MoveSummary.parse = function (text) {
17+ var lines = text.split('\n');
18+ var summary = new MoveSummary();
19+
20+ for (var i = 0, iMax = lines.length, line; i < iMax; i++) {
21+ line = MoveSummary.SUMMARY_REGEX.exec(lines[i].trim());
22+
23+ if (line) {
24+ summary.moves.push({
25+ from: line[1],
26+ to: line[2]
27+ });
28+ }
29+ }
30+
31+ return summary;
32+};
node_modules/simple-git/src/responses/PullSummary.js+137−0
@@ -0,0 +1,137 @@
1+
2+module.exports = PullSummary;
3+
4+/**
5+ * The PullSummary is returned as a response to getting `git().pull()`
6+ *
7+ * @constructor
8+ */
9+function PullSummary () {
10+ this.files = [];
11+ this.insertions = {};
12+ this.deletions = {};
13+
14+ this.summary = {
15+ changes: 0,
16+ insertions: 0,
17+ deletions: 0
18+ };
19+
20+ this.created = [];
21+ this.deleted = [];
22+}
23+
24+/**
25+ * Array of files that were created
26+ * @type {string[]}
27+ */
28+PullSummary.prototype.created = null;
29+
30+/**
31+ * Array of files that were deleted
32+ * @type {string[]}
33+ */
34+PullSummary.prototype.deleted = null;
35+
36+/**
37+ * The array of file paths/names that have been modified in any part of the pulled content
38+ * @type {string[]}
39+ */
40+PullSummary.prototype.files = null;
41+
42+/**
43+ * A map of file path to number to show the number of insertions per file.
44+ * @type {Object}
45+ */
46+PullSummary.prototype.insertions = null;
47+
48+/**
49+ * A map of file path to number to show the number of deletions per file.
50+ * @type {Object}
51+ */
52+PullSummary.prototype.deletions = null;
53+
54+/**
55+ * Overall summary of changes/insertions/deletions and the number associated with each
56+ * across all content that was pulled.
57+ * @type {Object}
58+ */
59+PullSummary.prototype.summary = null;
60+
61+PullSummary.FILE_UPDATE_REGEX = /^\s*(.+?)\s+\|\s+\d+\s*(\+*)(-*)/;
62+PullSummary.SUMMARY_REGEX = /(\d+)\D+((\d+)\D+\(\+\))?(\D+(\d+)\D+\(-\))?/;
63+PullSummary.ACTION_REGEX = /(create|delete) mode \d+ (.+)/;
64+
65+PullSummary.parse = function (text) {
66+ var pullSummary = new PullSummary;
67+ var lines = text.split('\n');
68+
69+ while (lines.length) {
70+ var line = lines.shift().trim();
71+ if (!line) {
72+ continue;
73+ }
74+
75+ update(pullSummary, line) || summary(pullSummary, line) || action(pullSummary, line);
76+ }
77+
78+ return pullSummary;
79+};
80+
81+function update (pullSummary, line) {
82+
83+ var update = PullSummary.FILE_UPDATE_REGEX.exec(line);
84+ if (!update) {
85+ return false;
86+ }
87+
88+ pullSummary.files.push(update[1]);
89+
90+ var insertions = update[2].length;
91+ if (insertions) {
92+ pullSummary.insertions[update[1]] = insertions;
93+ }
94+
95+ var deletions = update[3].length;
96+ if (deletions) {
97+ pullSummary.deletions[update[1]] = deletions;
98+ }
99+
100+ return true;
101+}
102+
103+function summary (pullSummary, line) {
104+ if (!pullSummary.files.length) {
105+ return false;
106+ }
107+
108+ var update = PullSummary.SUMMARY_REGEX.exec(line);
109+ if (!update || (update[3] === undefined && update[5] === undefined)) {
110+ return false;
111+ }
112+
113+ pullSummary.summary.changes = +update[1] || 0;
114+ pullSummary.summary.insertions = +update[3] || 0;
115+ pullSummary.summary.deletions = +update[5] || 0;
116+
117+ return true;
118+}
119+
120+function action (pullSummary, line) {
121+
122+ var match = PullSummary.ACTION_REGEX.exec(line);
123+ if (!match) {
124+ return false;
125+ }
126+
127+ var file = match[2];
128+
129+ if (pullSummary.files.indexOf(file) < 0) {
130+ pullSummary.files.push(file);
131+ }
132+
133+ var container = (match[1] === 'create') ? pullSummary.created : pullSummary.deleted;
134+ container.push(file);
135+
136+ return true;
137+}
node_modules/simple-git/src/responses/StatusSummary.js+188−0
@@ -0,0 +1,188 @@
1+
2+
3+
4+var FileStatusSummary = require('./FileStatusSummary');
5+
6+module.exports = StatusSummary;
7+
8+/**
9+ * The StatusSummary is returned as a response to getting `git().status()`
10+ *
11+ * @constructor
12+ */
13+function StatusSummary () {
14+ this.not_added = [];
15+ this.conflicted = [];
16+ this.created = [];
17+ this.deleted = [];
18+ this.modified = [];
19+ this.renamed = [];
20+ this.files = [];
21+ this.staged = [];
22+}
23+
24+
25+/**
26+ * Number of commits ahead of the tracked branch
27+ * @type {number}
28+ */
29+StatusSummary.prototype.ahead = 0;
30+
31+/**
32+ * Number of commits behind the tracked branch
33+ * @type {number}
34+ */
35+StatusSummary.prototype.behind = 0;
36+
37+/**
38+ * Name of the current branch
39+ * @type {null}
40+ */
41+StatusSummary.prototype.current = null;
42+
43+/**
44+ * Name of the branch being tracked
45+ * @type {string}
46+ */
47+StatusSummary.prototype.tracking = null;
48+
49+/**
50+ * All files represented as an array of objects containing the `path` and status in `index` and
51+ * in the `working_dir`.
52+ *
53+ * @type {Array}
54+ */
55+StatusSummary.prototype.files = null;
56+
57+/**
58+ * Gets whether this StatusSummary represents a clean working branch.
59+ *
60+ * @return {boolean}
61+ */
62+StatusSummary.prototype.isClean = function () {
63+ return 0 === Object.keys(this).filter(function (name) {
64+ return Array.isArray(this[name]) && this[name].length;
65+ }, this).length;
66+};
67+
68+StatusSummary.parsers = {
69+ '##': function (line, status) {
70+ var aheadReg = /ahead (\d+)/;
71+ var behindReg = /behind (\d+)/;
72+ var currentReg = /^(.+?(?=(?:\.{3}|\s|$)))/;
73+ var trackingReg = /\.{3}(\S*)/;
74+ var regexResult;
75+
76+ regexResult = aheadReg.exec(line);
77+ status.ahead = regexResult && +regexResult[1] || 0;
78+
79+ regexResult = behindReg.exec(line);
80+ status.behind = regexResult && +regexResult[1] || 0;
81+
82+ regexResult = currentReg.exec(line);
83+ status.current = regexResult && regexResult[1];
84+
85+ regexResult = trackingReg.exec(line);
86+ status.tracking = regexResult && regexResult[1];
87+ },
88+
89+ '??': function (line, status) {
90+ status.not_added.push(line);
91+ },
92+
93+ A: function (line, status) {
94+ status.created.push(line);
95+ },
96+
97+ AM: function (line, status) {
98+ status.created.push(line);
99+ },
100+
101+ D: function (line, status) {
102+ status.deleted.push(line);
103+ },
104+
105+ M: function (line, status, indexState) {
106+ status.modified.push(line);
107+
108+ if (indexState === 'M') {
109+ status.staged.push(line);
110+ }
111+ },
112+
113+ R: function (line, status) {
114+ var detail = /^(.+) -> (.+)$/.exec(line) || [null, line, line];
115+
116+ status.renamed.push({
117+ from: detail[1],
118+ to: detail[2]
119+ });
120+ },
121+
122+ UU: function (line, status) {
123+ status.conflicted.push(line);
124+ }
125+};
126+
127+StatusSummary.parsers.MM = StatusSummary.parsers.M;
128+
129+/* Map all unmerged status code combinations to UU to mark as conflicted */
130+StatusSummary.parsers.AA = StatusSummary.parsers.UU;
131+StatusSummary.parsers.UD = StatusSummary.parsers.UU;
132+StatusSummary.parsers.DU = StatusSummary.parsers.UU;
133+StatusSummary.parsers.DD = StatusSummary.parsers.UU;
134+StatusSummary.parsers.AU = StatusSummary.parsers.UU;
135+StatusSummary.parsers.UA = StatusSummary.parsers.UU;
136+
137+StatusSummary.parse = function (text) {
138+ var file;
139+ var lines = text.trim().split('\n');
140+ var status = new StatusSummary();
141+
142+ for (var i = 0, l = lines.length; i < l; i++) {
143+ file = splitLine(lines[i]);
144+
145+ if (!file) {
146+ continue;
147+ }
148+
149+ if (file.handler) {
150+ file.handler(file.path, status, file.index, file.workingDir);
151+ }
152+
153+ if (file.code !== '##') {
154+ status.files.push(new FileStatusSummary(file.path, file.index, file.workingDir));
155+ }
156+ }
157+
158+ return status;
159+};
160+
161+
162+function splitLine (lineStr) {
163+ var line = lineStr.trim().match(/(..?)(\s+)(.*)/);
164+ if (!line || !line[1].trim()) {
165+ line = lineStr.trim().match(/(..?)\s+(.*)/);
166+ }
167+
168+ if (!line) {
169+ return;
170+ }
171+
172+ var code = line[1];
173+ if (line[2].length > 1) {
174+ code += ' ';
175+ }
176+ if (code.length === 1 && line[2].length === 1) {
177+ code = ' ' + code;
178+ }
179+
180+ return {
181+ raw: code,
182+ code: code.trim(),
183+ index: code.charAt(0),
184+ workingDir: code.charAt(1),
185+ handler: StatusSummary.parsers[code.trim()],
186+ path: line[3]
187+ };
188+}
node_modules/simple-git/src/responses/TagList.js+50−0
@@ -0,0 +1,50 @@
1+
2+module.exports = TagList;
3+
4+function TagList (tagList, latest) {
5+ this.latest = latest;
6+ this.all = tagList
7+}
8+
9+TagList.parse = function (data, customSort) {
10+ var number = function (input) {
11+ if (typeof input === 'string') {
12+ return parseInt(input.replace(/^\D+/g, ''), 10) || 0;
13+ }
14+
15+ return 0;
16+ };
17+
18+ var tags = data
19+ .trim()
20+ .split('\n')
21+ .map(function (item) { return item.trim(); })
22+ .filter(Boolean);
23+
24+ if (!customSort) {
25+ tags.sort(function (tagA, tagB) {
26+ var partsA = tagA.split('.');
27+ var partsB = tagB.split('.');
28+
29+ if (partsA.length === 1 || partsB.length === 1) {
30+ return tagA - tagB > 0 ? 1 : -1;
31+ }
32+
33+ for (var i = 0, l = Math.max(partsA.length, partsB.length); i < l; i++) {
34+ var a = number(partsA[i]);
35+ var b = number(partsB[i]);
36+
37+ var diff = a - b;
38+ if (diff) {
39+ return diff > 0 ? 1 : -1;
40+ }
41+ }
42+
43+ return 0;
44+ });
45+ }
46+
47+ var latest = customSort ? tags[0] : tags.filter(function (tag) { return tag.indexOf('.') >= 0; }).pop();
48+
49+ return new TagList(tags, latest);
50+};
node_modules/simple-git/src/responses/index.js+15−0
@@ -0,0 +1,15 @@
1+
2+module.exports = {
3+ BranchDeleteSummary: require('./BranchDeleteSummary'),
4+ BranchSummary: require('./BranchSummary'),
5+ CommitSummary: require('./CommitSummary'),
6+ DiffSummary: require('./DiffSummary'),
7+ FetchSummary: require('./FetchSummary'),
8+ FileStatusSummary: require('./FileStatusSummary'),
9+ ListLogSummary: require('./ListLogSummary'),
10+ MergeSummary: require('./MergeSummary'),
11+ MoveSummary: require('./MoveSummary'),
12+ PullSummary: require('./PullSummary'),
13+ StatusSummary: require('./StatusSummary'),
14+ TagList: require('./TagList'),
15+};
node_modules/simple-git/src/util/deferred.js+10−0
@@ -0,0 +1,10 @@
1+
2+module.exports = function deferred () {
3+ var d = {};
4+ d.promise = new Promise(function (resolve, reject) {
5+ d.resolve = resolve;
6+ d.reject = reject
7+ });
8+
9+ return d;
10+};
node_modules/simple-git/src/util/dependencies.js+12−0
@@ -0,0 +1,12 @@
1+/**
2+ * Exports the utilities `simple-git` depends upon to allow for mocking during a test
3+ */
4+module.exports = {
5+
6+ buffer: function () { return require('buffer').Buffer; },
7+
8+ childProcess: function () { return require('child_process'); },
9+
10+ exists: require('./exists')
11+
12+};
node_modules/simple-git/src/util/exists.js+33−0
@@ -0,0 +1,33 @@
1+
2+var fs = require('fs');
3+
4+function exists (path, isFile, isDirectory) {
5+ try {
6+ var matches = false;
7+ var stat = fs.statSync(path);
8+
9+ matches = matches || isFile && stat.isFile();
10+ matches = matches || isDirectory && stat.isDirectory();
11+
12+ return matches;
13+ }
14+ catch (e) {
15+ if (e.code === 'ENOENT') {
16+ return false;
17+ }
18+
19+ throw e;
20+ }
21+}
22+
23+module.exports = function (path, type) {
24+ if (!type) {
25+ return exists(path, true, true);
26+ }
27+
28+ return exists(path, type & 1, type & 2);
29+};
30+
31+module.exports.FILE = 1;
32+
33+module.exports.FOLDER = 2;
node_modules/simple-git/typings/response.d.ts+220−0
@@ -0,0 +1,220 @@
1+export interface BranchDeletionSummary {
2+ branch: string;
3+ hash: any;
4+ success: boolean;
5+}
6+
7+export interface BranchSummary {
8+ detached: boolean;
9+ current: string;
10+ all: string[];
11+ branches: {
12+ [key: string]: {
13+ current: boolean;
14+ name: string;
15+ commit: string;
16+ label: string;
17+ };
18+ };
19+}
20+
21+export interface CommitSummary {
22+ author: null | {
23+ email: string;
24+ name: string;
25+ };
26+ branch: string;
27+ commit: string;
28+ summary: {
29+ changes: number;
30+ insertions: number;
31+ deletions: number;
32+ };
33+}
34+
35+export interface DiffResultTextFile {
36+ file: string;
37+ changes: number;
38+ insertions: number;
39+ deletions: number;
40+ binary: boolean;
41+}
42+
43+export interface DiffResultBinaryFile {
44+ file: string;
45+ before: number;
46+ after: number;
47+ binary: boolean;
48+}
49+
50+export interface DiffResult {
51+ /** The total number of files changed as reported in the summary line */
52+ changed: number;
53+
54+ /** When present in the diff, lists the details of each file changed */
55+ files: Array<DiffResultTextFile | DiffResultBinaryFile>;
56+
57+ /** The number of files changed with insertions */
58+ insertions: number;
59+
60+ /** The number of files changed with deletions */
61+ deletions: number;
62+}
63+
64+export interface FetchResult {
65+ raw: string;
66+ remote: string | null;
67+ branches: {
68+ name: string;
69+ tracking: string;
70+ }[];
71+ tags: {
72+ name: string;
73+ tracking: string;
74+ }[];
75+}
76+
77+export interface MoveSummary {
78+ moves: any[];
79+}
80+
81+export interface PullResult {
82+ /** Array of all files that are referenced in the pull */
83+ files: string[];
84+
85+ /** Map of file names to the number of insertions in that file */
86+ insertions: { [key: string]: number };
87+
88+ /** Map of file names to the number of deletions in that file */
89+ deletions: any;
90+
91+ summary: {
92+ changes: number;
93+ insertions: number;
94+ deletions: number;
95+ };
96+
97+ /** Array of file names that have been created */
98+ created: string[];
99+
100+ /** Array of file names that have been deleted */
101+ deleted: string[];
102+}
103+
104+export interface RemoteWithoutRefs {
105+ name: string;
106+}
107+
108+export interface RemoteWithRefs extends RemoteWithoutRefs {
109+ refs: {
110+ fetch: string;
111+ push: string;
112+ };
113+}
114+
115+export interface StatusResultRenamed {
116+ from: string;
117+ to: string;
118+}
119+
120+export interface FileStatusSumary {
121+ /* Path of the file */
122+ path: string;
123+ /* First digit of the status code of the file, e.g. 'M' = modified.
124+ Represents the status of the index if no merge conflicts, otherwise represents
125+ status of one side of the merge. */
126+ index: string;
127+ /* Second digit of the status code of the file. Represents status of the working directory
128+ if no merge conflicts, otherwise represents status of other side of a merge. */
129+ working_dir: string;
130+}
131+
132+export interface StatusResult {
133+ not_added: string[];
134+ conflicted: string[];
135+ created: string[];
136+ deleted: string[];
137+ modified: string[];
138+ renamed: StatusResultRenamed[];
139+ staged: string[];
140+ files: FileStatusSumary[];
141+ ahead: number;
142+ behind: number;
143+ current: string;
144+ tracking: string;
145+
146+ /**
147+ * Gets whether this represents a clean working branch.
148+ */
149+ isClean(): boolean;
150+}
151+
152+export interface TagResult {
153+ all: string[];
154+ latest: string;
155+}
156+
157+export interface DefaultLogFields {
158+ hash: string;
159+ date: string;
160+ message: string;
161+ refs: string;
162+ body: string;
163+ author_name: string;
164+ author_email: string;
165+}
166+
167+/**
168+ * The ListLogLine represents a single entry in the `git.log`, the properties on the object
169+ * are mixed in depending on the names used in the format (see `DefaultLogFields`), but some
170+ * properties are dependent on the command used.
171+ */
172+export interface ListLogLine {
173+ /**
174+ * When using a `--stat=4096` or `--shortstat` options in the `git.log` or `git.stashList`,
175+ * each entry in the `ListLogSummary` will also have a `diff` property representing as much
176+ * detail as was given in the response.
177+ */
178+ diff?: DiffResult;
179+}
180+
181+export interface ListLogSummary<T = DefaultLogFields> {
182+ all: ReadonlyArray<T & ListLogLine>;
183+ total: number;
184+ latest: T & ListLogLine;
185+}
186+
187+/**
188+ * Where the file was deleted, if there is a modify/delete conflict
189+ */
190+export interface MergeConflictDeletion {
191+ deleteRef: string;
192+}
193+
194+/**
195+ * Represents a single file with conflicts in the MergeSummary
196+ */
197+export interface MergeConflict {
198+
199+ /**
200+ * Type of conflict
201+ */
202+ reason: string;
203+
204+ /**
205+ * Path to file
206+ */
207+ file: string;
208+
209+ /**
210+ * Additional detail for the specific type of conflict
211+ */
212+ meta?: MergeConflictDeletion;
213+}
214+
215+export interface MergeSummary extends PullResult {
216+ conflicts: MergeConflict[];
217+ merges: string[];
218+ result: "success" | string;
219+ failed: boolean;
220+}