isomorphic-git 1.34.2 → 1.35.0

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.
@@ -5,7 +5,6 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
6
6
 
7
7
  var ignore = _interopDefault(require('ignore'));
8
- var pathBrowserify = require('path-browserify');
9
8
  var AsyncLock = _interopDefault(require('async-lock'));
10
9
  var Hash = _interopDefault(require('sha.js/sha1.js'));
11
10
  var crc32 = _interopDefault(require('crc-32'));
@@ -694,6 +693,104 @@ function dirname(path) {
694
693
  return path.slice(0, last)
695
694
  }
696
695
 
696
+ /*!
697
+ * This code for `path.join` is directly copied from @zenfs/core/path for bundle size improvements.
698
+ * SPDX-License-Identifier: LGPL-3.0-or-later
699
+ * Copyright (c) James Prevett and other ZenFS contributors.
700
+ */
701
+
702
+ function normalizeString(path, aar) {
703
+ let res = '';
704
+ let lastSegmentLength = 0;
705
+ let lastSlash = -1;
706
+ let dots = 0;
707
+ let char = '\x00';
708
+ for (let i = 0; i <= path.length; ++i) {
709
+ if (i < path.length) char = path[i];
710
+ else if (char === '/') break
711
+ else char = '/';
712
+
713
+ if (char === '/') {
714
+ if (lastSlash === i - 1 || dots === 1) {
715
+ // NOOP
716
+ } else if (dots === 2) {
717
+ if (
718
+ res.length < 2 ||
719
+ lastSegmentLength !== 2 ||
720
+ res.at(-1) !== '.' ||
721
+ res.at(-2) !== '.'
722
+ ) {
723
+ if (res.length > 2) {
724
+ const lastSlashIndex = res.lastIndexOf('/');
725
+ if (lastSlashIndex === -1) {
726
+ res = '';
727
+ lastSegmentLength = 0;
728
+ } else {
729
+ res = res.slice(0, lastSlashIndex);
730
+ lastSegmentLength = res.length - 1 - res.lastIndexOf('/');
731
+ }
732
+ lastSlash = i;
733
+ dots = 0;
734
+ continue
735
+ } else if (res.length !== 0) {
736
+ res = '';
737
+ lastSegmentLength = 0;
738
+ lastSlash = i;
739
+ dots = 0;
740
+ continue
741
+ }
742
+ }
743
+ if (aar) {
744
+ res += res.length > 0 ? '/..' : '..';
745
+ lastSegmentLength = 2;
746
+ }
747
+ } else {
748
+ if (res.length > 0) res += '/' + path.slice(lastSlash + 1, i);
749
+ else res = path.slice(lastSlash + 1, i);
750
+ lastSegmentLength = i - lastSlash - 1;
751
+ }
752
+ lastSlash = i;
753
+ dots = 0;
754
+ } else if (char === '.' && dots !== -1) {
755
+ ++dots;
756
+ } else {
757
+ dots = -1;
758
+ }
759
+ }
760
+ return res
761
+ }
762
+
763
+ function normalize(path) {
764
+ if (!path.length) return '.'
765
+
766
+ const isAbsolute = path[0] === '/';
767
+ const trailingSeparator = path.at(-1) === '/';
768
+
769
+ path = normalizeString(path, !isAbsolute);
770
+
771
+ if (!path.length) {
772
+ if (isAbsolute) return '/'
773
+ return trailingSeparator ? './' : '.'
774
+ }
775
+ if (trailingSeparator) path += '/';
776
+
777
+ return isAbsolute ? `/${path}` : path
778
+ }
779
+
780
+ function join(...args) {
781
+ if (args.length === 0) return '.'
782
+ let joined;
783
+ for (let i = 0; i < args.length; ++i) {
784
+ const arg = args[i];
785
+ if (arg.length > 0) {
786
+ if (joined === undefined) joined = arg;
787
+ else joined += '/' + arg;
788
+ }
789
+ }
790
+ if (joined === undefined) return '.'
791
+ return normalize(joined)
792
+ }
793
+
697
794
  // I'm putting this in a Manager because I reckon it could benefit
698
795
  // from a LOT of caching.
699
796
  class GitIgnoreManager {
@@ -707,21 +804,21 @@ class GitIgnoreManager {
707
804
  * @param {string} args.filepath - The path of the file to check.
708
805
  * @returns {Promise<boolean>} - `true` if the file is ignored, `false` otherwise.
709
806
  */
710
- static async isIgnored({ fs, dir, gitdir = pathBrowserify.join(dir, '.git'), filepath }) {
807
+ static async isIgnored({ fs, dir, gitdir = join(dir, '.git'), filepath }) {
711
808
  // ALWAYS ignore ".git" folders.
712
809
  if (basename(filepath) === '.git') return true
713
810
  // '.' is not a valid gitignore entry, so '.' is never ignored
714
811
  if (filepath === '.') return false
715
812
  // Check and load exclusion rules from project exclude file (.git/info/exclude)
716
813
  let excludes = '';
717
- const excludesFile = pathBrowserify.join(gitdir, 'info', 'exclude');
814
+ const excludesFile = join(gitdir, 'info', 'exclude');
718
815
  if (await fs.exists(excludesFile)) {
719
816
  excludes = await fs.read(excludesFile, 'utf8');
720
817
  }
721
818
  // Find all the .gitignore files that could affect this file
722
819
  const pairs = [
723
820
  {
724
- gitignore: pathBrowserify.join(dir, '.gitignore'),
821
+ gitignore: join(dir, '.gitignore'),
725
822
  filepath,
726
823
  },
727
824
  ];
@@ -730,7 +827,7 @@ class GitIgnoreManager {
730
827
  const folder = pieces.slice(0, i).join('/');
731
828
  const file = pieces.slice(i).join('/');
732
829
  pairs.push({
733
- gitignore: pathBrowserify.join(dir, folder, '.gitignore'),
830
+ gitignore: join(dir, folder, '.gitignore'),
734
831
  filepath: file,
735
832
  });
736
833
  }
@@ -1261,7 +1358,7 @@ class GitIndex {
1261
1358
  gid: stats.gid,
1262
1359
  size: stats.size,
1263
1360
  path: filepath,
1264
- oid: oid,
1361
+ oid,
1265
1362
  flags: {
1266
1363
  assumeValid: false,
1267
1364
  extended: false,
@@ -1582,13 +1679,8 @@ class GitRefSpec {
1582
1679
  }
1583
1680
 
1584
1681
  static from(refspec) {
1585
- const [
1586
- forceMatch,
1587
- remotePath,
1588
- remoteGlobMatch,
1589
- localPath,
1590
- localGlobMatch,
1591
- ] = refspec.match(/^(\+?)(.*?)(\*?):(.*?)(\*?)$/).slice(1);
1682
+ const [forceMatch, remotePath, remoteGlobMatch, localPath, localGlobMatch] =
1683
+ refspec.match(/^(\+?)(.*?)(\*?):(.*?)(\*?)$/).slice(1);
1592
1684
  const force = forceMatch === '+';
1593
1685
  const remoteIsGlob = remoteGlobMatch === '*';
1594
1686
  const localIsGlob = localGlobMatch === '*';
@@ -1834,7 +1926,7 @@ class GitRefManager {
1834
1926
  // and .git/refs/remotes/origin/refs/merge-requests
1835
1927
  for (const [key, value] of actualRefsToWrite) {
1836
1928
  await acquireLock(key, async () =>
1837
- fs.write(pathBrowserify.join(gitdir, key), `${value.trim()}\n`, 'utf8')
1929
+ fs.write(join(gitdir, key), `${value.trim()}\n`, 'utf8')
1838
1930
  );
1839
1931
  }
1840
1932
  return { pruned }
@@ -1857,7 +1949,7 @@ class GitRefManager {
1857
1949
  throw new InvalidOidError(value)
1858
1950
  }
1859
1951
  await acquireLock(ref, async () =>
1860
- fs.write(pathBrowserify.join(gitdir, ref), `${value.trim()}\n`, 'utf8')
1952
+ fs.write(join(gitdir, ref), `${value.trim()}\n`, 'utf8')
1861
1953
  );
1862
1954
  }
1863
1955
 
@@ -1873,7 +1965,7 @@ class GitRefManager {
1873
1965
  */
1874
1966
  static async writeSymbolicRef({ fs, gitdir, ref, value }) {
1875
1967
  await acquireLock(ref, async () =>
1876
- fs.write(pathBrowserify.join(gitdir, ref), 'ref: ' + `${value.trim()}\n`, 'utf8')
1968
+ fs.write(join(gitdir, ref), 'ref: ' + `${value.trim()}\n`, 'utf8')
1877
1969
  );
1878
1970
  }
1879
1971
 
@@ -1901,7 +1993,7 @@ class GitRefManager {
1901
1993
  */
1902
1994
  static async deleteRefs({ fs, gitdir, refs }) {
1903
1995
  // Delete regular ref
1904
- await Promise.all(refs.map(ref => fs.rm(pathBrowserify.join(gitdir, ref))));
1996
+ await Promise.all(refs.map(ref => fs.rm(join(gitdir, ref))));
1905
1997
  // Delete any packed ref
1906
1998
  let text = await acquireLock('packed-refs', async () =>
1907
1999
  fs.read(`${gitdir}/packed-refs`, { encoding: 'utf8' })
@@ -2981,9 +3073,9 @@ class GitShallowManager {
2981
3073
  */
2982
3074
  static async read({ fs, gitdir }) {
2983
3075
  if (lock$2 === null) lock$2 = new AsyncLock();
2984
- const filepath = pathBrowserify.join(gitdir, 'shallow');
3076
+ const filepath = join(gitdir, 'shallow');
2985
3077
  const oids = new Set();
2986
- await lock$2.acquire(filepath, async function() {
3078
+ await lock$2.acquire(filepath, async function () {
2987
3079
  const text = await fs.read(filepath, { encoding: 'utf8' });
2988
3080
  if (text === null) return oids // no file
2989
3081
  if (text.trim() === '') return oids // empty file
@@ -3007,17 +3099,17 @@ class GitShallowManager {
3007
3099
  */
3008
3100
  static async write({ fs, gitdir, oids }) {
3009
3101
  if (lock$2 === null) lock$2 = new AsyncLock();
3010
- const filepath = pathBrowserify.join(gitdir, 'shallow');
3102
+ const filepath = join(gitdir, 'shallow');
3011
3103
  if (oids.size > 0) {
3012
3104
  const text = [...oids].join('\n') + '\n';
3013
- await lock$2.acquire(filepath, async function() {
3105
+ await lock$2.acquire(filepath, async function () {
3014
3106
  await fs.write(filepath, text, {
3015
3107
  encoding: 'utf8',
3016
3108
  });
3017
3109
  });
3018
3110
  } else {
3019
3111
  // No shallows
3020
- await lock$2.acquire(filepath, async function() {
3112
+ await lock$2.acquire(filepath, async function () {
3021
3113
  await fs.rm(filepath);
3022
3114
  });
3023
3115
  }
@@ -3088,8 +3180,8 @@ function parseAuthor(author) {
3088
3180
  /^(.*) <(.*)> (.*) (.*)$/
3089
3181
  );
3090
3182
  return {
3091
- name: name,
3092
- email: email,
3183
+ name,
3184
+ email,
3093
3185
  timestamp: Number(timestamp),
3094
3186
  timezoneOffset: parseTimezoneOffset(offset),
3095
3187
  }
@@ -4049,7 +4141,7 @@ async function readObjectPacked({
4049
4141
  }) {
4050
4142
  // Check to see if it's in a packfile.
4051
4143
  // Iterate through all the .idx files
4052
- let list = await fs.readdir(pathBrowserify.join(gitdir, 'objects/pack'));
4144
+ let list = await fs.readdir(join(gitdir, 'objects/pack'));
4053
4145
  list = list.filter(x => x.endsWith('.idx'));
4054
4146
  for (const filename of list) {
4055
4147
  const indexFile = `${gitdir}/objects/pack/${filename}`;
@@ -4456,7 +4548,7 @@ type Node = {
4456
4548
 
4457
4549
  function flatFileListToDirectoryStructure(files) {
4458
4550
  const inodes = new Map();
4459
- const mkdir = function(name) {
4551
+ const mkdir = function (name) {
4460
4552
  if (!inodes.has(name)) {
4461
4553
  const dir = {
4462
4554
  type: 'tree',
@@ -4475,13 +4567,13 @@ function flatFileListToDirectoryStructure(files) {
4475
4567
  return inodes.get(name)
4476
4568
  };
4477
4569
 
4478
- const mkfile = function(name, metadata) {
4570
+ const mkfile = function (name, metadata) {
4479
4571
  if (!inodes.has(name)) {
4480
4572
  const file = {
4481
4573
  type: 'blob',
4482
4574
  fullpath: name,
4483
4575
  basename: basename(name),
4484
- metadata: metadata,
4576
+ metadata,
4485
4577
  // This recursively generates any missing parent folders.
4486
4578
  parent: mkdir(dirname(name)),
4487
4579
  children: [],
@@ -4519,7 +4611,7 @@ class GitWalkerIndex {
4519
4611
  constructor({ fs, gitdir, cache }) {
4520
4612
  this.treePromise = GitIndexManager.acquire(
4521
4613
  { fs, gitdir, cache },
4522
- async function(index) {
4614
+ async function (index) {
4523
4615
  return flatFileListToDirectoryStructure(index.entries)
4524
4616
  }
4525
4617
  );
@@ -4633,7 +4725,7 @@ const GitWalkSymbol = Symbol('GitWalkSymbol');
4633
4725
  function STAGE() {
4634
4726
  const o = Object.create(null);
4635
4727
  Object.defineProperty(o, GitWalkSymbol, {
4636
- value: function({ fs, gitdir, cache }) {
4728
+ value: function ({ fs, gitdir, cache }) {
4637
4729
  return new GitWalkerIndex({ fs, gitdir, cache })
4638
4730
  },
4639
4731
  });
@@ -5132,9 +5224,9 @@ class GitWalkerRepo {
5132
5224
  const tree = GitTree.from(object);
5133
5225
  // cache all entries
5134
5226
  for (const entry of tree) {
5135
- map.set(pathBrowserify.join(filepath, entry.path), entry);
5227
+ map.set(join(filepath, entry.path), entry);
5136
5228
  }
5137
- return tree.entries().map(entry => pathBrowserify.join(filepath, entry.path))
5229
+ return tree.entries().map(entry => join(filepath, entry.path))
5138
5230
  }
5139
5231
 
5140
5232
  async type(entry) {
@@ -5193,7 +5285,7 @@ class GitWalkerRepo {
5193
5285
  function TREE({ ref = 'HEAD' } = {}) {
5194
5286
  const o = Object.create(null);
5195
5287
  Object.defineProperty(o, GitWalkSymbol, {
5196
- value: function({ fs, gitdir, cache }) {
5288
+ value: function ({ fs, gitdir, cache }) {
5197
5289
  return new GitWalkerRepo({ fs, gitdir, ref, cache })
5198
5290
  },
5199
5291
  });
@@ -5245,9 +5337,9 @@ class GitWalkerFs {
5245
5337
  async readdir(entry) {
5246
5338
  const filepath = entry._fullpath;
5247
5339
  const { fs, dir } = this;
5248
- const names = await fs.readdir(pathBrowserify.join(dir, filepath));
5340
+ const names = await fs.readdir(join(dir, filepath));
5249
5341
  if (names === null) return null
5250
- return names.map(name => pathBrowserify.join(filepath, name))
5342
+ return names.map(name => join(filepath, name))
5251
5343
  }
5252
5344
 
5253
5345
  async type(entry) {
@@ -5315,46 +5407,47 @@ class GitWalkerFs {
5315
5407
  const { fs, gitdir, cache } = this;
5316
5408
  let oid;
5317
5409
  // See if we can use the SHA1 hash in the index.
5318
- await GitIndexManager.acquire({ fs, gitdir, cache }, async function(
5319
- index
5320
- ) {
5321
- const stage = index.entriesMap.get(entry._fullpath);
5322
- const stats = await entry.stat();
5323
- const config = await self._getGitConfig(fs, gitdir);
5324
- const filemode = await config.get('core.filemode');
5325
- const trustino =
5326
- typeof process !== 'undefined'
5327
- ? !(process.platform === 'win32')
5328
- : true;
5329
- if (!stage || compareStats(stats, stage, filemode, trustino)) {
5330
- const content = await entry.content();
5331
- if (content === undefined) {
5332
- oid = undefined;
5333
- } else {
5334
- oid = await shasum(
5335
- GitObject.wrap({ type: 'blob', object: content })
5336
- );
5337
- // Update the stats in the index so we will get a "cache hit" next time
5338
- // 1) if we can (because the oid and mode are the same)
5339
- // 2) and only if we need to (because other stats differ)
5340
- if (
5341
- stage &&
5342
- oid === stage.oid &&
5343
- (!filemode || stats.mode === stage.mode) &&
5344
- compareStats(stats, stage, filemode, trustino)
5345
- ) {
5346
- index.insert({
5347
- filepath: entry._fullpath,
5348
- stats,
5349
- oid: oid,
5350
- });
5410
+ await GitIndexManager.acquire(
5411
+ { fs, gitdir, cache },
5412
+ async function (index) {
5413
+ const stage = index.entriesMap.get(entry._fullpath);
5414
+ const stats = await entry.stat();
5415
+ const config = await self._getGitConfig(fs, gitdir);
5416
+ const filemode = await config.get('core.filemode');
5417
+ const trustino =
5418
+ typeof process !== 'undefined'
5419
+ ? !(process.platform === 'win32')
5420
+ : true;
5421
+ if (!stage || compareStats(stats, stage, filemode, trustino)) {
5422
+ const content = await entry.content();
5423
+ if (content === undefined) {
5424
+ oid = undefined;
5425
+ } else {
5426
+ oid = await shasum(
5427
+ GitObject.wrap({ type: 'blob', object: content })
5428
+ );
5429
+ // Update the stats in the index so we will get a "cache hit" next time
5430
+ // 1) if we can (because the oid and mode are the same)
5431
+ // 2) and only if we need to (because other stats differ)
5432
+ if (
5433
+ stage &&
5434
+ oid === stage.oid &&
5435
+ (!filemode || stats.mode === stage.mode) &&
5436
+ compareStats(stats, stage, filemode, trustino)
5437
+ ) {
5438
+ index.insert({
5439
+ filepath: entry._fullpath,
5440
+ stats,
5441
+ oid,
5442
+ });
5443
+ }
5351
5444
  }
5445
+ } else {
5446
+ // Use the index SHA1 rather than compute it
5447
+ oid = stage.oid;
5352
5448
  }
5353
- } else {
5354
- // Use the index SHA1 rather than compute it
5355
- oid = stage.oid;
5356
5449
  }
5357
- });
5450
+ );
5358
5451
  entry._oid = oid;
5359
5452
  }
5360
5453
  return entry._oid
@@ -5377,7 +5470,7 @@ class GitWalkerFs {
5377
5470
  function WORKDIR() {
5378
5471
  const o = Object.create(null);
5379
5472
  Object.defineProperty(o, GitWalkSymbol, {
5380
- value: function({ fs, dir, gitdir, cache }) {
5473
+ value: function ({ fs, dir, gitdir, cache }) {
5381
5474
  return new GitWalkerFs({ fs, dir, gitdir, cache })
5382
5475
  },
5383
5476
  });
@@ -5520,7 +5613,7 @@ async function _walk({
5520
5613
  const root = new Array(walkers.length).fill('.');
5521
5614
  const range = arrayRange(0, walkers.length);
5522
5615
  const unionWalkerFromReaddir = async entries => {
5523
- range.map(i => {
5616
+ range.forEach(i => {
5524
5617
  const entry = entries[i];
5525
5618
  entries[i] = entry && new walkers[i].ConstructEntry(entry);
5526
5619
  });
@@ -5596,7 +5689,7 @@ async function acquireLock$1(ref, callback) {
5596
5689
 
5597
5690
  // make sure filepath, blob type and blob object (from loose objects) plus oid are in sync and valid
5598
5691
  async function checkAndWriteBlob(fs, gitdir, dir, filepath, oid = null) {
5599
- const currentFilepath = pathBrowserify.join(dir, filepath);
5692
+ const currentFilepath = join(dir, filepath);
5600
5693
  const stats = await fs.lstat(currentFilepath);
5601
5694
  if (!stats) throw new NotFoundError(currentFilepath)
5602
5695
  if (stats.isDirectory())
@@ -5812,7 +5905,7 @@ async function applyTreeChanges({
5812
5905
  stageUpdated.push({
5813
5906
  filepath,
5814
5907
  oid,
5815
- stats: await fs.lstat(pathBrowserify.join(dir, filepath)),
5908
+ stats: await fs.lstat(join(dir, filepath)),
5816
5909
  });
5817
5910
  return {
5818
5911
  method: 'write',
@@ -5827,7 +5920,7 @@ async function applyTreeChanges({
5827
5920
  // apply the changes to work dir
5828
5921
  await acquireLock$1({ fs, gitdir, dirRemoved, ops }, async () => {
5829
5922
  for (const op of ops) {
5830
- const currentFilepath = pathBrowserify.join(dir, op.filepath);
5923
+ const currentFilepath = join(dir, op.filepath);
5831
5924
  switch (op.method) {
5832
5925
  case 'rmdir':
5833
5926
  await fs.rmdir(currentFilepath);
@@ -5879,7 +5972,7 @@ class GitStashManager {
5879
5972
  * @param {string} args.dir - The working directory.
5880
5973
  * @param {string}[args.gitdir=join(dir, '.git')] - [required] The [git directory](dir-vs-gitdir.md) path
5881
5974
  */
5882
- constructor({ fs, dir, gitdir = pathBrowserify.join(dir, '.git') }) {
5975
+ constructor({ fs, dir, gitdir = join(dir, '.git') }) {
5883
5976
  Object.assign(this, {
5884
5977
  fs,
5885
5978
  dir,
@@ -5912,7 +6005,7 @@ class GitStashManager {
5912
6005
  * @returns {string} - The file path for the stash reference.
5913
6006
  */
5914
6007
  get refStashPath() {
5915
- return pathBrowserify.join(this.gitdir, GitStashManager.refStash)
6008
+ return join(this.gitdir, GitStashManager.refStash)
5916
6009
  }
5917
6010
 
5918
6011
  /**
@@ -5921,7 +6014,7 @@ class GitStashManager {
5921
6014
  * @returns {string} - The file path for the stash reflogs.
5922
6015
  */
5923
6016
  get refLogsStashPath() {
5924
- return pathBrowserify.join(this.gitdir, GitStashManager.refLogsStash)
6017
+ return join(this.gitdir, GitStashManager.refLogsStash)
5925
6018
  }
5926
6019
 
5927
6020
  /**