isomorphic-git 1.23.0 โ†’ 1.24.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE.md CHANGED
@@ -1,7 +1,7 @@
1
- Copyright 2017-2018 the 'isomorphic-git' authors
1
+ Copyright 2017-2023 the 'isomorphic-git' authors
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
4
 
5
5
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
6
 
7
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md CHANGED
@@ -359,6 +359,8 @@ Thanks goes to these wonderful people ([emoji key](https://github.com/kentcdodds
359
359
  <td align="center"><a href="https://github.com/araknast"><img src="https://avatars.githubusercontent.com/u/84164531?v=4?s=60" width="60px;" alt=""/><br /><sub><b>araknast</b></sub></a><br /><a href="https://github.com/isomorphic-git/isomorphic-git/commits?author=araknast" title="Code">๐Ÿ’ป</a> <a href="https://github.com/isomorphic-git/isomorphic-git/commits?author=araknast" title="Tests">โš ๏ธ</a> <a href="https://github.com/isomorphic-git/isomorphic-git/commits?author=araknast" title="Documentation">๐Ÿ“–</a></td>
360
360
  <td align="center"><a href="https://github.com/rraab-dev"><img src="https://avatars.githubusercontent.com/u/53948988?v=4?s=60" width="60px;" alt=""/><br /><sub><b>Rafael Raab</b></sub></a><br /><a href="https://github.com/isomorphic-git/isomorphic-git/commits?author=rraab-dev" title="Code">๐Ÿ’ป</a> <a href="https://github.com/isomorphic-git/isomorphic-git/commits?author=rraab-dev" title="Documentation">๐Ÿ“–</a></td>
361
361
  <td align="center"><a href="https://gitlab.com/CoalZombik/"><img src="https://avatars.githubusercontent.com/u/49895741?v=4?s=60" width="60px;" alt=""/><br /><sub><b>Lukรกลก Cezner</b></sub></a><br /><a href="https://github.com/isomorphic-git/isomorphic-git/issues?q=author%3ACoalZombik" title="Bug reports">๐Ÿ›</a></td>
362
+ <td align="center"><a href="https://github.com/dead-end"><img src="https://avatars.githubusercontent.com/u/30635084?v=4?s=60" width="60px;" alt=""/><br /><sub><b>dead-end</b></sub></a><br /><a href="https://github.com/isomorphic-git/isomorphic-git/commits?author=dead-end" title="Code">๐Ÿ’ป</a> <a href="https://github.com/isomorphic-git/isomorphic-git/commits?author=dead-end" title="Documentation">๐Ÿ“–</a> <a href="https://github.com/isomorphic-git/isomorphic-git/commits?author=dead-end" title="Tests">โš ๏ธ</a></td>
363
+ <td align="center"><a href="https://github.com/barry963"><img src="https://avatars.githubusercontent.com/u/5289896?v=4?s=60" width="60px;" alt=""/><br /><sub><b>Barry</b></sub></a><br /><a href="https://github.com/isomorphic-git/isomorphic-git/commits?author=barry963" title="Code">๐Ÿ’ป</a> <a href="https://github.com/isomorphic-git/isomorphic-git/commits?author=barry963" title="Documentation">๐Ÿ“–</a> <a href="https://github.com/isomorphic-git/isomorphic-git/commits?author=barry963" title="Tests">โš ๏ธ</a></td>
362
364
  </tr>
363
365
  </table>
364
366
 
@@ -1,8 +1,10 @@
1
1
  [
2
2
  "Chrome Headless 79.0.3945.0 (Linux x86_64)",
3
- "Firefox 111.0 (Ubuntu 0.0.0)",
4
- "Chrome 108.0.0.0 (Android 10)",
3
+ "Firefox 114.0 (Ubuntu 0.0.0)",
4
+ "X Chrome 111.0.0.0 (Android 10)",
5
5
  "Edge 79.0.309.65 (Windows 10)",
6
+ "Safari 13.1 (Mac OS 10.15.4)",
6
7
  "Mobile Safari 13.0 (iOS 13.0)",
7
- "Safari 13.1 (Mac OS 10.15.4)"
8
+ "Chrome Headless 79.0.3945.0 (Linux x86_64)",
9
+ "Chrome 111.0.0.0 (Android 10)"
8
10
  ]
package/index.cjs CHANGED
@@ -675,7 +675,18 @@ class GitIndex {
675
675
  }
676
676
 
677
677
  static async fromBuffer(buffer) {
678
- // Verify shasum
678
+ if (buffer.length === 0) {
679
+ throw new InternalError('Index file is empty (.git/index)')
680
+ }
681
+
682
+ const index = new GitIndex();
683
+ const reader = new BufferCursor(buffer);
684
+ const magic = reader.toString('utf8', 4);
685
+ if (magic !== 'DIRC') {
686
+ throw new InternalError(`Invalid dircache magic file number: ${magic}`)
687
+ }
688
+
689
+ // Verify shasum after we ensured that the file has a magic number
679
690
  const shaComputed = await shasum(buffer.slice(0, -20));
680
691
  const shaClaimed = buffer.slice(-20).toString('hex');
681
692
  if (shaClaimed !== shaComputed) {
@@ -683,12 +694,7 @@ class GitIndex {
683
694
  `Invalid checksum in GitIndex buffer: expected ${shaClaimed} but saw ${shaComputed}`
684
695
  )
685
696
  }
686
- const index = new GitIndex();
687
- const reader = new BufferCursor(buffer);
688
- const magic = reader.toString('utf8', 4);
689
- if (magic !== 'DIRC') {
690
- throw new InternalError(`Inavlid dircache magic file number: ${magic}`)
691
- }
697
+
692
698
  const version = reader.readUInt32BE();
693
699
  if (version !== 2) {
694
700
  throw new InternalError(`Unsupported dircache version: ${version}`)
@@ -4394,6 +4400,57 @@ async function rmRecursive(fs, filepath) {
4394
4400
  }
4395
4401
  }
4396
4402
 
4403
+ function isPromiseFs(fs) {
4404
+ const test = targetFs => {
4405
+ try {
4406
+ // If readFile returns a promise then we can probably assume the other
4407
+ // commands do as well
4408
+ return targetFs.readFile().catch(e => e)
4409
+ } catch (e) {
4410
+ return e
4411
+ }
4412
+ };
4413
+ return test(fs).constructor.name === 'Promise'
4414
+ }
4415
+
4416
+ // List of commands all filesystems are expected to provide. `rm` is not
4417
+ // included since it may not exist and must be handled as a special case
4418
+ const commands = [
4419
+ 'readFile',
4420
+ 'writeFile',
4421
+ 'mkdir',
4422
+ 'rmdir',
4423
+ 'unlink',
4424
+ 'stat',
4425
+ 'lstat',
4426
+ 'readdir',
4427
+ 'readlink',
4428
+ 'symlink',
4429
+ ];
4430
+
4431
+ function bindFs(target, fs) {
4432
+ if (isPromiseFs(fs)) {
4433
+ for (const command of commands) {
4434
+ target[`_${command}`] = fs[command].bind(fs);
4435
+ }
4436
+ } else {
4437
+ for (const command of commands) {
4438
+ target[`_${command}`] = pify(fs[command].bind(fs));
4439
+ }
4440
+ }
4441
+
4442
+ // Handle the special case of `rm`
4443
+ if (isPromiseFs(fs)) {
4444
+ if (fs.rm) target._rm = fs.rm.bind(fs);
4445
+ else if (fs.rmdir.length > 1) target._rm = fs.rmdir.bind(fs);
4446
+ else target._rm = rmRecursive.bind(null, target);
4447
+ } else {
4448
+ if (fs.rm) target._rm = pify(fs.rm.bind(fs));
4449
+ else if (fs.rmdir.length > 2) target._rm = pify(fs.rmdir.bind(fs));
4450
+ else target._rm = rmRecursive.bind(null, target);
4451
+ }
4452
+ }
4453
+
4397
4454
  /**
4398
4455
  * This is just a collection of helper functions really. At least that's how it started.
4399
4456
  */
@@ -4403,41 +4460,9 @@ class FileSystem {
4403
4460
 
4404
4461
  const promises = Object.getOwnPropertyDescriptor(fs, 'promises');
4405
4462
  if (promises && promises.enumerable) {
4406
- this._readFile = fs.promises.readFile.bind(fs.promises);
4407
- this._writeFile = fs.promises.writeFile.bind(fs.promises);
4408
- this._mkdir = fs.promises.mkdir.bind(fs.promises);
4409
- if (fs.promises.rm) {
4410
- this._rm = fs.promises.rm.bind(fs.promises);
4411
- } else if (fs.promises.rmdir.length > 1) {
4412
- this._rm = fs.promises.rmdir.bind(fs.promises);
4413
- } else {
4414
- this._rm = rmRecursive.bind(null, this);
4415
- }
4416
- this._rmdir = fs.promises.rmdir.bind(fs.promises);
4417
- this._unlink = fs.promises.unlink.bind(fs.promises);
4418
- this._stat = fs.promises.stat.bind(fs.promises);
4419
- this._lstat = fs.promises.lstat.bind(fs.promises);
4420
- this._readdir = fs.promises.readdir.bind(fs.promises);
4421
- this._readlink = fs.promises.readlink.bind(fs.promises);
4422
- this._symlink = fs.promises.symlink.bind(fs.promises);
4463
+ bindFs(this, fs.promises);
4423
4464
  } else {
4424
- this._readFile = pify(fs.readFile.bind(fs));
4425
- this._writeFile = pify(fs.writeFile.bind(fs));
4426
- this._mkdir = pify(fs.mkdir.bind(fs));
4427
- if (fs.rm) {
4428
- this._rm = pify(fs.rm.bind(fs));
4429
- } else if (fs.rmdir.length > 2) {
4430
- this._rm = pify(fs.rmdir.bind(fs));
4431
- } else {
4432
- this._rm = rmRecursive.bind(null, this);
4433
- }
4434
- this._rmdir = pify(fs.rmdir.bind(fs));
4435
- this._unlink = pify(fs.unlink.bind(fs));
4436
- this._stat = pify(fs.stat.bind(fs));
4437
- this._lstat = pify(fs.lstat.bind(fs));
4438
- this._readdir = pify(fs.readdir.bind(fs));
4439
- this._readlink = pify(fs.readlink.bind(fs));
4440
- this._symlink = pify(fs.symlink.bind(fs));
4465
+ bindFs(this, fs);
4441
4466
  }
4442
4467
  this._original_unwrapped_fs = fs;
4443
4468
  }
@@ -4904,6 +4929,7 @@ function posixifyPathBuffer(buffer) {
4904
4929
  * @param {string|string[]} args.filepath - The path to the file to add to the index
4905
4930
  * @param {object} [args.cache] - a [cache](cache.md) object
4906
4931
  * @param {boolean} [args.force=false] - add to index even if matches gitignore. Think `git add --force`
4932
+ * @param {boolean} [args.parallel=false] - process each input file in parallel. Parallel processing will result in more memory consumption but less process time
4907
4933
  *
4908
4934
  * @returns {Promise<void>} Resolves successfully once the git index has been updated
4909
4935
  *
@@ -4920,6 +4946,7 @@ async function add({
4920
4946
  filepath,
4921
4947
  cache = {},
4922
4948
  force = false,
4949
+ parallel = true,
4923
4950
  }) {
4924
4951
  try {
4925
4952
  assertParameter('fs', _fs);
@@ -4929,7 +4956,15 @@ async function add({
4929
4956
 
4930
4957
  const fs = new FileSystem(_fs);
4931
4958
  await GitIndexManager.acquire({ fs, gitdir, cache }, async index => {
4932
- return addToIndex({ dir, gitdir, fs, filepath, index, force })
4959
+ return addToIndex({
4960
+ dir,
4961
+ gitdir,
4962
+ fs,
4963
+ filepath,
4964
+ index,
4965
+ force,
4966
+ parallel,
4967
+ })
4933
4968
  });
4934
4969
  } catch (err) {
4935
4970
  err.caller = 'git.add';
@@ -4937,7 +4972,15 @@ async function add({
4937
4972
  }
4938
4973
  }
4939
4974
 
4940
- async function addToIndex({ dir, gitdir, fs, filepath, index, force }) {
4975
+ async function addToIndex({
4976
+ dir,
4977
+ gitdir,
4978
+ fs,
4979
+ filepath,
4980
+ index,
4981
+ force,
4982
+ parallel,
4983
+ }) {
4941
4984
  // TODO: Should ignore UNLESS it's already in the index.
4942
4985
  filepath = Array.isArray(filepath) ? filepath : [filepath];
4943
4986
  const promises = filepath.map(async currentFilepath => {
@@ -4955,17 +4998,32 @@ async function addToIndex({ dir, gitdir, fs, filepath, index, force }) {
4955
4998
 
4956
4999
  if (stats.isDirectory()) {
4957
5000
  const children = await fs.readdir(join(dir, currentFilepath));
4958
- const promises = children.map(child =>
4959
- addToIndex({
4960
- dir,
4961
- gitdir,
4962
- fs,
4963
- filepath: [join(currentFilepath, child)],
4964
- index,
4965
- force,
4966
- })
4967
- );
4968
- await Promise.all(promises);
5001
+ if (parallel) {
5002
+ const promises = children.map(child =>
5003
+ addToIndex({
5004
+ dir,
5005
+ gitdir,
5006
+ fs,
5007
+ filepath: [join(currentFilepath, child)],
5008
+ index,
5009
+ force,
5010
+ parallel,
5011
+ })
5012
+ );
5013
+ await Promise.all(promises);
5014
+ } else {
5015
+ for (const child of children) {
5016
+ await addToIndex({
5017
+ dir,
5018
+ gitdir,
5019
+ fs,
5020
+ filepath: [join(currentFilepath, child)],
5021
+ index,
5022
+ force,
5023
+ parallel,
5024
+ });
5025
+ }
5026
+ }
4969
5027
  } else {
4970
5028
  const object = stats.isSymbolicLink()
4971
5029
  ? await fs.readlink(join(dir, currentFilepath)).then(posixifyPathBuffer)
@@ -7243,8 +7301,8 @@ function filterCapabilities(server, client) {
7243
7301
 
7244
7302
  const pkg = {
7245
7303
  name: 'isomorphic-git',
7246
- version: '1.23.0',
7247
- agent: 'git/isomorphic-git@1.23.0',
7304
+ version: '1.24.1',
7305
+ agent: 'git/isomorphic-git@1.24.1',
7248
7306
  };
7249
7307
 
7250
7308
  class FIFO {
@@ -10383,6 +10441,9 @@ async function isIgnored({
10383
10441
  * If you want an up-to-date list, first do a `fetch` to that remote.
10384
10442
  * (Which branch you fetch doesn't matter - the list of branches available on the remote is updated during the fetch handshake.)
10385
10443
  *
10444
+ * Also note, that a branch is a reference to a commit. If you initialize a new repository it has no commits, so the
10445
+ * `listBranches` function will return an empty list, until you create the first commit.
10446
+ *
10386
10447
  * @param {object} args
10387
10448
  * @param {FsClient} args.fs - a file system client
10388
10449
  * @param {string} [args.dir] - The [working tree](dir-vs-gitdir.md) directory path
package/index.d.ts CHANGED
@@ -803,6 +803,7 @@ export function abortMerge({ fs: _fs, dir, gitdir, commit, cache, }: {
803
803
  * @param {string|string[]} args.filepath - The path to the file to add to the index
804
804
  * @param {object} [args.cache] - a [cache](cache.md) object
805
805
  * @param {boolean} [args.force=false] - add to index even if matches gitignore. Think `git add --force`
806
+ * @param {boolean} [args.parallel=false] - process each input file in parallel. Parallel processing will result in more memory consumption but less process time
806
807
  *
807
808
  * @returns {Promise<void>} Resolves successfully once the git index has been updated
808
809
  *
@@ -812,13 +813,14 @@ export function abortMerge({ fs: _fs, dir, gitdir, commit, cache, }: {
812
813
  * console.log('done')
813
814
  *
814
815
  */
815
- export function add({ fs: _fs, dir, gitdir, filepath, cache, force, }: {
816
+ export function add({ fs: _fs, dir, gitdir, filepath, cache, force, parallel, }: {
816
817
  fs: CallbackFsClient | PromiseFsClient;
817
818
  dir: string;
818
819
  gitdir?: string;
819
820
  filepath: string | string[];
820
821
  cache?: any;
821
822
  force?: boolean;
823
+ parallel?: boolean;
822
824
  }): Promise<void>;
823
825
  /**
824
826
  * Add or update an object note
@@ -1854,6 +1856,9 @@ export function isIgnored({ fs, dir, gitdir, filepath, }: {
1854
1856
  * If you want an up-to-date list, first do a `fetch` to that remote.
1855
1857
  * (Which branch you fetch doesn't matter - the list of branches available on the remote is updated during the fetch handshake.)
1856
1858
  *
1859
+ * Also note, that a branch is a reference to a commit. If you initialize a new repository it has no commits, so the
1860
+ * `listBranches` function will return an empty list, until you create the first commit.
1861
+ *
1857
1862
  * @param {object} args
1858
1863
  * @param {FsClient} args.fs - a file system client
1859
1864
  * @param {string} [args.dir] - The [working tree](dir-vs-gitdir.md) directory path
package/index.js CHANGED
@@ -669,7 +669,18 @@ class GitIndex {
669
669
  }
670
670
 
671
671
  static async fromBuffer(buffer) {
672
- // Verify shasum
672
+ if (buffer.length === 0) {
673
+ throw new InternalError('Index file is empty (.git/index)')
674
+ }
675
+
676
+ const index = new GitIndex();
677
+ const reader = new BufferCursor(buffer);
678
+ const magic = reader.toString('utf8', 4);
679
+ if (magic !== 'DIRC') {
680
+ throw new InternalError(`Invalid dircache magic file number: ${magic}`)
681
+ }
682
+
683
+ // Verify shasum after we ensured that the file has a magic number
673
684
  const shaComputed = await shasum(buffer.slice(0, -20));
674
685
  const shaClaimed = buffer.slice(-20).toString('hex');
675
686
  if (shaClaimed !== shaComputed) {
@@ -677,12 +688,7 @@ class GitIndex {
677
688
  `Invalid checksum in GitIndex buffer: expected ${shaClaimed} but saw ${shaComputed}`
678
689
  )
679
690
  }
680
- const index = new GitIndex();
681
- const reader = new BufferCursor(buffer);
682
- const magic = reader.toString('utf8', 4);
683
- if (magic !== 'DIRC') {
684
- throw new InternalError(`Inavlid dircache magic file number: ${magic}`)
685
- }
691
+
686
692
  const version = reader.readUInt32BE();
687
693
  if (version !== 2) {
688
694
  throw new InternalError(`Unsupported dircache version: ${version}`)
@@ -4388,6 +4394,57 @@ async function rmRecursive(fs, filepath) {
4388
4394
  }
4389
4395
  }
4390
4396
 
4397
+ function isPromiseFs(fs) {
4398
+ const test = targetFs => {
4399
+ try {
4400
+ // If readFile returns a promise then we can probably assume the other
4401
+ // commands do as well
4402
+ return targetFs.readFile().catch(e => e)
4403
+ } catch (e) {
4404
+ return e
4405
+ }
4406
+ };
4407
+ return test(fs).constructor.name === 'Promise'
4408
+ }
4409
+
4410
+ // List of commands all filesystems are expected to provide. `rm` is not
4411
+ // included since it may not exist and must be handled as a special case
4412
+ const commands = [
4413
+ 'readFile',
4414
+ 'writeFile',
4415
+ 'mkdir',
4416
+ 'rmdir',
4417
+ 'unlink',
4418
+ 'stat',
4419
+ 'lstat',
4420
+ 'readdir',
4421
+ 'readlink',
4422
+ 'symlink',
4423
+ ];
4424
+
4425
+ function bindFs(target, fs) {
4426
+ if (isPromiseFs(fs)) {
4427
+ for (const command of commands) {
4428
+ target[`_${command}`] = fs[command].bind(fs);
4429
+ }
4430
+ } else {
4431
+ for (const command of commands) {
4432
+ target[`_${command}`] = pify(fs[command].bind(fs));
4433
+ }
4434
+ }
4435
+
4436
+ // Handle the special case of `rm`
4437
+ if (isPromiseFs(fs)) {
4438
+ if (fs.rm) target._rm = fs.rm.bind(fs);
4439
+ else if (fs.rmdir.length > 1) target._rm = fs.rmdir.bind(fs);
4440
+ else target._rm = rmRecursive.bind(null, target);
4441
+ } else {
4442
+ if (fs.rm) target._rm = pify(fs.rm.bind(fs));
4443
+ else if (fs.rmdir.length > 2) target._rm = pify(fs.rmdir.bind(fs));
4444
+ else target._rm = rmRecursive.bind(null, target);
4445
+ }
4446
+ }
4447
+
4391
4448
  /**
4392
4449
  * This is just a collection of helper functions really. At least that's how it started.
4393
4450
  */
@@ -4397,41 +4454,9 @@ class FileSystem {
4397
4454
 
4398
4455
  const promises = Object.getOwnPropertyDescriptor(fs, 'promises');
4399
4456
  if (promises && promises.enumerable) {
4400
- this._readFile = fs.promises.readFile.bind(fs.promises);
4401
- this._writeFile = fs.promises.writeFile.bind(fs.promises);
4402
- this._mkdir = fs.promises.mkdir.bind(fs.promises);
4403
- if (fs.promises.rm) {
4404
- this._rm = fs.promises.rm.bind(fs.promises);
4405
- } else if (fs.promises.rmdir.length > 1) {
4406
- this._rm = fs.promises.rmdir.bind(fs.promises);
4407
- } else {
4408
- this._rm = rmRecursive.bind(null, this);
4409
- }
4410
- this._rmdir = fs.promises.rmdir.bind(fs.promises);
4411
- this._unlink = fs.promises.unlink.bind(fs.promises);
4412
- this._stat = fs.promises.stat.bind(fs.promises);
4413
- this._lstat = fs.promises.lstat.bind(fs.promises);
4414
- this._readdir = fs.promises.readdir.bind(fs.promises);
4415
- this._readlink = fs.promises.readlink.bind(fs.promises);
4416
- this._symlink = fs.promises.symlink.bind(fs.promises);
4457
+ bindFs(this, fs.promises);
4417
4458
  } else {
4418
- this._readFile = pify(fs.readFile.bind(fs));
4419
- this._writeFile = pify(fs.writeFile.bind(fs));
4420
- this._mkdir = pify(fs.mkdir.bind(fs));
4421
- if (fs.rm) {
4422
- this._rm = pify(fs.rm.bind(fs));
4423
- } else if (fs.rmdir.length > 2) {
4424
- this._rm = pify(fs.rmdir.bind(fs));
4425
- } else {
4426
- this._rm = rmRecursive.bind(null, this);
4427
- }
4428
- this._rmdir = pify(fs.rmdir.bind(fs));
4429
- this._unlink = pify(fs.unlink.bind(fs));
4430
- this._stat = pify(fs.stat.bind(fs));
4431
- this._lstat = pify(fs.lstat.bind(fs));
4432
- this._readdir = pify(fs.readdir.bind(fs));
4433
- this._readlink = pify(fs.readlink.bind(fs));
4434
- this._symlink = pify(fs.symlink.bind(fs));
4459
+ bindFs(this, fs);
4435
4460
  }
4436
4461
  this._original_unwrapped_fs = fs;
4437
4462
  }
@@ -4898,6 +4923,7 @@ function posixifyPathBuffer(buffer) {
4898
4923
  * @param {string|string[]} args.filepath - The path to the file to add to the index
4899
4924
  * @param {object} [args.cache] - a [cache](cache.md) object
4900
4925
  * @param {boolean} [args.force=false] - add to index even if matches gitignore. Think `git add --force`
4926
+ * @param {boolean} [args.parallel=false] - process each input file in parallel. Parallel processing will result in more memory consumption but less process time
4901
4927
  *
4902
4928
  * @returns {Promise<void>} Resolves successfully once the git index has been updated
4903
4929
  *
@@ -4914,6 +4940,7 @@ async function add({
4914
4940
  filepath,
4915
4941
  cache = {},
4916
4942
  force = false,
4943
+ parallel = true,
4917
4944
  }) {
4918
4945
  try {
4919
4946
  assertParameter('fs', _fs);
@@ -4923,7 +4950,15 @@ async function add({
4923
4950
 
4924
4951
  const fs = new FileSystem(_fs);
4925
4952
  await GitIndexManager.acquire({ fs, gitdir, cache }, async index => {
4926
- return addToIndex({ dir, gitdir, fs, filepath, index, force })
4953
+ return addToIndex({
4954
+ dir,
4955
+ gitdir,
4956
+ fs,
4957
+ filepath,
4958
+ index,
4959
+ force,
4960
+ parallel,
4961
+ })
4927
4962
  });
4928
4963
  } catch (err) {
4929
4964
  err.caller = 'git.add';
@@ -4931,7 +4966,15 @@ async function add({
4931
4966
  }
4932
4967
  }
4933
4968
 
4934
- async function addToIndex({ dir, gitdir, fs, filepath, index, force }) {
4969
+ async function addToIndex({
4970
+ dir,
4971
+ gitdir,
4972
+ fs,
4973
+ filepath,
4974
+ index,
4975
+ force,
4976
+ parallel,
4977
+ }) {
4935
4978
  // TODO: Should ignore UNLESS it's already in the index.
4936
4979
  filepath = Array.isArray(filepath) ? filepath : [filepath];
4937
4980
  const promises = filepath.map(async currentFilepath => {
@@ -4949,17 +4992,32 @@ async function addToIndex({ dir, gitdir, fs, filepath, index, force }) {
4949
4992
 
4950
4993
  if (stats.isDirectory()) {
4951
4994
  const children = await fs.readdir(join(dir, currentFilepath));
4952
- const promises = children.map(child =>
4953
- addToIndex({
4954
- dir,
4955
- gitdir,
4956
- fs,
4957
- filepath: [join(currentFilepath, child)],
4958
- index,
4959
- force,
4960
- })
4961
- );
4962
- await Promise.all(promises);
4995
+ if (parallel) {
4996
+ const promises = children.map(child =>
4997
+ addToIndex({
4998
+ dir,
4999
+ gitdir,
5000
+ fs,
5001
+ filepath: [join(currentFilepath, child)],
5002
+ index,
5003
+ force,
5004
+ parallel,
5005
+ })
5006
+ );
5007
+ await Promise.all(promises);
5008
+ } else {
5009
+ for (const child of children) {
5010
+ await addToIndex({
5011
+ dir,
5012
+ gitdir,
5013
+ fs,
5014
+ filepath: [join(currentFilepath, child)],
5015
+ index,
5016
+ force,
5017
+ parallel,
5018
+ });
5019
+ }
5020
+ }
4963
5021
  } else {
4964
5022
  const object = stats.isSymbolicLink()
4965
5023
  ? await fs.readlink(join(dir, currentFilepath)).then(posixifyPathBuffer)
@@ -7237,8 +7295,8 @@ function filterCapabilities(server, client) {
7237
7295
 
7238
7296
  const pkg = {
7239
7297
  name: 'isomorphic-git',
7240
- version: '1.23.0',
7241
- agent: 'git/isomorphic-git@1.23.0',
7298
+ version: '1.24.1',
7299
+ agent: 'git/isomorphic-git@1.24.1',
7242
7300
  };
7243
7301
 
7244
7302
  class FIFO {
@@ -10377,6 +10435,9 @@ async function isIgnored({
10377
10435
  * If you want an up-to-date list, first do a `fetch` to that remote.
10378
10436
  * (Which branch you fetch doesn't matter - the list of branches available on the remote is updated during the fetch handshake.)
10379
10437
  *
10438
+ * Also note, that a branch is a reference to a commit. If you initialize a new repository it has no commits, so the
10439
+ * `listBranches` function will return an empty list, until you create the first commit.
10440
+ *
10380
10441
  * @param {object} args
10381
10442
  * @param {FsClient} args.fs - a file system client
10382
10443
  * @param {string} [args.dir] - The [working tree](dir-vs-gitdir.md) directory path
@@ -803,6 +803,7 @@ export function abortMerge({ fs: _fs, dir, gitdir, commit, cache, }: {
803
803
  * @param {string|string[]} args.filepath - The path to the file to add to the index
804
804
  * @param {object} [args.cache] - a [cache](cache.md) object
805
805
  * @param {boolean} [args.force=false] - add to index even if matches gitignore. Think `git add --force`
806
+ * @param {boolean} [args.parallel=false] - process each input file in parallel. Parallel processing will result in more memory consumption but less process time
806
807
  *
807
808
  * @returns {Promise<void>} Resolves successfully once the git index has been updated
808
809
  *
@@ -812,13 +813,14 @@ export function abortMerge({ fs: _fs, dir, gitdir, commit, cache, }: {
812
813
  * console.log('done')
813
814
  *
814
815
  */
815
- export function add({ fs: _fs, dir, gitdir, filepath, cache, force, }: {
816
+ export function add({ fs: _fs, dir, gitdir, filepath, cache, force, parallel, }: {
816
817
  fs: CallbackFsClient | PromiseFsClient;
817
818
  dir: string;
818
819
  gitdir?: string;
819
820
  filepath: string | string[];
820
821
  cache?: any;
821
822
  force?: boolean;
823
+ parallel?: boolean;
822
824
  }): Promise<void>;
823
825
  /**
824
826
  * Add or update an object note
@@ -1854,6 +1856,9 @@ export function isIgnored({ fs, dir, gitdir, filepath, }: {
1854
1856
  * If you want an up-to-date list, first do a `fetch` to that remote.
1855
1857
  * (Which branch you fetch doesn't matter - the list of branches available on the remote is updated during the fetch handshake.)
1856
1858
  *
1859
+ * Also note, that a branch is a reference to a commit. If you initialize a new repository it has no commits, so the
1860
+ * `listBranches` function will return an empty list, until you create the first commit.
1861
+ *
1857
1862
  * @param {object} args
1858
1863
  * @param {FsClient} args.fs - a file system client
1859
1864
  * @param {string} [args.dir] - The [working tree](dir-vs-gitdir.md) directory path