isomorphic-git 1.41.1 → 1.41.2

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/index.cjs CHANGED
@@ -4,8 +4,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
6
6
 
7
- var AsyncLock = _interopDefault(require('async-lock'));
8
7
  var Hash = _interopDefault(require('sha.js/sha1.js'));
8
+ var AsyncLock = _interopDefault(require('async-lock'));
9
9
  var crc32 = _interopDefault(require('crc-32'));
10
10
  var pako = _interopDefault(require('pako'));
11
11
  var crypto$1 = require('crypto');
@@ -964,10 +964,43 @@ function compareStats(entry, stats, filemode = true, trustino = true) {
964
964
  return staleness
965
965
  }
966
966
 
967
- // import Lock from '../utils.js'
967
+ // A single process-wide lock shared by everything that serializes file
968
+ // operations (the index, refs, the shallow file, blob writes). It is keyed by
969
+ // path, so unrelated resources never contend. Centralizing it here also means
970
+ // there is exactly one place to reset it (see `_resetLock`).
971
+ //
972
+ // Created lazily (not at module load) so this module has no top-level side
973
+ // effect and stays tree-shakeable.
974
+ let lock;
975
+
976
+ function getLock() {
977
+ if (lock === undefined) lock = new AsyncLock({ maxPending: Infinity });
978
+ return lock
979
+ }
980
+
981
+ /**
982
+ * Run `callback` while holding the shared lock for `key`, then release it.
983
+ *
984
+ * @template T
985
+ * @param {string | string[]} key - Resource key(s) to lock (usually a filepath).
986
+ * @param {() => (Promise<T> | T)} callback
987
+ * @returns {Promise<T>}
988
+ */
989
+ function acquireLock(key, callback) {
990
+ return getLock().acquire(key, callback)
991
+ }
968
992
 
969
- // const lm = new LockManager()
970
- let lock = null;
993
+ /**
994
+ * Discard the shared lock so the next `acquireLock` starts a fresh one. Intended
995
+ * for test harnesses that run many independent scenarios inside one long-lived
996
+ * module instance: if a scenario leaves an operation stalled (e.g. a filesystem
997
+ * that hangs), its still-held lock would otherwise block every later scenario
998
+ * that touches the same path. Resetting abandons that stalled queue so the next
999
+ * scenario starts clean. It is a no-op for normal library use.
1000
+ */
1001
+ function _resetLock() {
1002
+ lock = undefined;
1003
+ }
971
1004
 
972
1005
  const IndexCache = Symbol('IndexCache');
973
1006
 
@@ -1038,10 +1071,9 @@ class GitIndexManager {
1038
1071
  }
1039
1072
 
1040
1073
  const filepath = `${gitdir}/index`;
1041
- if (lock === null) lock = new AsyncLock({ maxPending: Infinity });
1042
1074
  let result;
1043
1075
  let unmergedPaths = [];
1044
- await lock.acquire(filepath, async () => {
1076
+ await acquireLock(filepath, async () => {
1045
1077
  // Acquire a file lock while we're reading the index
1046
1078
  // to make sure other processes aren't writing to it
1047
1079
  // simultaneously, which could result in a corrupted index.
@@ -2031,13 +2063,6 @@ function assertWritableRef(ref) {
2031
2063
  }
2032
2064
  }
2033
2065
 
2034
- let lock$1;
2035
-
2036
- async function acquireLock(ref, callback) {
2037
- if (lock$1 === undefined) lock$1 = new AsyncLock();
2038
- return lock$1.acquire(ref, callback)
2039
- }
2040
-
2041
2066
  /**
2042
2067
  * A class for managing Git references, including reading, writing, deleting, and resolving refs.
2043
2068
  */
@@ -8348,12 +8373,6 @@ const _TreeMap = {
8348
8373
  workdir: WORKDIR,
8349
8374
  };
8350
8375
 
8351
- let lock$2;
8352
- async function acquireLock$1(ref, callback) {
8353
- if (lock$2 === undefined) lock$2 = new AsyncLock();
8354
- return lock$2.acquire(ref, callback)
8355
- }
8356
-
8357
8376
  // make sure filepath, blob type and blob object (from loose objects) plus oid are in sync and valid
8358
8377
  async function checkAndWriteBlob(fs, gitdir, dir, filepath, oid = null) {
8359
8378
  const currentFilepath = join(dir, filepath);
@@ -8370,7 +8389,7 @@ async function checkAndWriteBlob(fs, gitdir, dir, filepath, oid = null) {
8370
8389
  : undefined;
8371
8390
  let retOid = objContent ? oid : undefined;
8372
8391
  if (!objContent) {
8373
- await acquireLock$1(currentFilepath, async () => {
8392
+ await acquireLock(currentFilepath, async () => {
8374
8393
  const object = stats.isSymbolicLink()
8375
8394
  ? await fs.readlink(currentFilepath).then(posixifyPathBuffer)
8376
8395
  : await fs.read(currentFilepath);
@@ -8585,7 +8604,7 @@ async function applyTreeChanges({
8585
8604
  });
8586
8605
 
8587
8606
  // apply the changes to work dir
8588
- await acquireLock$1(gitdir, async () => {
8607
+ await acquireLock(gitdir, async () => {
8589
8608
  for (const op of ops) {
8590
8609
  const currentFilepath = join(dir, op.filepath);
8591
8610
  switch (op.method) {
@@ -9539,8 +9558,6 @@ function parseRemoteUrl({ url }) {
9539
9558
  }
9540
9559
  }
9541
9560
 
9542
- let lock$3 = null;
9543
-
9544
9561
  class GitShallowManager {
9545
9562
  /**
9546
9563
  * Reads the `shallow` file in the Git repository and returns a set of object IDs (OIDs).
@@ -9551,10 +9568,9 @@ class GitShallowManager {
9551
9568
  * @returns {Promise<Set<string>>} - A set of shallow object IDs.
9552
9569
  */
9553
9570
  static async read({ fs, gitdir }) {
9554
- if (lock$3 === null) lock$3 = new AsyncLock();
9555
9571
  const filepath = join(gitdir, 'shallow');
9556
9572
  const oids = new Set();
9557
- await lock$3.acquire(filepath, async function () {
9573
+ await acquireLock(filepath, async function () {
9558
9574
  const text = await fs.read(filepath, { encoding: 'utf8' });
9559
9575
  if (text === null) return oids // no file
9560
9576
  if (text.trim() === '') return oids // empty file
@@ -9577,18 +9593,17 @@ class GitShallowManager {
9577
9593
  * @returns {Promise<void>}
9578
9594
  */
9579
9595
  static async write({ fs, gitdir, oids }) {
9580
- if (lock$3 === null) lock$3 = new AsyncLock();
9581
9596
  const filepath = join(gitdir, 'shallow');
9582
9597
  if (oids.size > 0) {
9583
9598
  const text = [...oids].join('\n') + '\n';
9584
- await lock$3.acquire(filepath, async function () {
9599
+ await acquireLock(filepath, async function () {
9585
9600
  await fs.write(filepath, text, {
9586
9601
  encoding: 'utf8',
9587
9602
  });
9588
9603
  });
9589
9604
  } else {
9590
9605
  // No shallows
9591
- await lock$3.acquire(filepath, async function () {
9606
+ await acquireLock(filepath, async function () {
9592
9607
  await fs.rm(filepath);
9593
9608
  });
9594
9609
  }
@@ -9685,8 +9700,8 @@ function filterCapabilities(server, client) {
9685
9700
 
9686
9701
  const pkg = {
9687
9702
  name: 'isomorphic-git',
9688
- version: '1.41.1',
9689
- agent: 'git/isomorphic-git@1.41.1',
9703
+ version: '1.41.2',
9704
+ agent: 'git/isomorphic-git@1.41.2',
9690
9705
  };
9691
9706
 
9692
9707
  class FIFO {
@@ -16043,7 +16058,7 @@ class GitStashManager {
16043
16058
  );
16044
16059
  const filepath = this.refLogsStashPath;
16045
16060
 
16046
- await acquireLock$1(filepath, async () => {
16061
+ await acquireLock(filepath, async () => {
16047
16062
  const appendTo = (await this.fs.exists(filepath))
16048
16063
  ? await this.fs.read(filepath, 'utf8')
16049
16064
  : '';
@@ -16237,7 +16252,7 @@ async function _stashDrop({ fs, dir, gitdir, refIdx = 0 }) {
16237
16252
  }
16238
16253
  // remove stash ref first
16239
16254
  const stashRefPath = stashMgr.refStashPath;
16240
- await acquireLock$1(stashRefPath, async () => {
16255
+ await acquireLock(stashRefPath, async () => {
16241
16256
  if (await fs.exists(stashRefPath)) {
16242
16257
  await fs.rm(stashRefPath);
16243
16258
  }
@@ -16253,7 +16268,7 @@ async function _stashDrop({ fs, dir, gitdir, refIdx = 0 }) {
16253
16268
  reflogEntries.splice(refIdx, 1);
16254
16269
 
16255
16270
  const stashReflogPath = stashMgr.refLogsStashPath;
16256
- await acquireLock$1(stashReflogPath, async () => {
16271
+ await acquireLock(stashReflogPath, async () => {
16257
16272
  if (reflogEntries.length) {
16258
16273
  await fs.write(
16259
16274
  stashReflogPath,
@@ -16279,7 +16294,7 @@ async function _stashClear({ fs, dir, gitdir }) {
16279
16294
  const stashMgr = new GitStashManager({ fs, dir, gitdir });
16280
16295
  const stashRefPath = [stashMgr.refStashPath, stashMgr.refLogsStashPath];
16281
16296
 
16282
- await acquireLock$1(stashRefPath, async () => {
16297
+ await acquireLock(stashRefPath, async () => {
16283
16298
  await Promise.all(
16284
16299
  stashRefPath.map(async path => {
16285
16300
  if (await fs.exists(path)) {
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import AsyncLock from 'async-lock';
2
1
  import Hash from 'sha.js/sha1.js';
2
+ import AsyncLock from 'async-lock';
3
3
  import crc32 from 'crc-32';
4
4
  import pako from 'pako';
5
5
  import pify from 'pify';
@@ -957,10 +957,43 @@ function compareStats(entry, stats, filemode = true, trustino = true) {
957
957
  return staleness
958
958
  }
959
959
 
960
- // import Lock from '../utils.js'
960
+ // A single process-wide lock shared by everything that serializes file
961
+ // operations (the index, refs, the shallow file, blob writes). It is keyed by
962
+ // path, so unrelated resources never contend. Centralizing it here also means
963
+ // there is exactly one place to reset it (see `_resetLock`).
964
+ //
965
+ // Created lazily (not at module load) so this module has no top-level side
966
+ // effect and stays tree-shakeable.
967
+ let lock;
968
+
969
+ function getLock() {
970
+ if (lock === undefined) lock = new AsyncLock({ maxPending: Infinity });
971
+ return lock
972
+ }
973
+
974
+ /**
975
+ * Run `callback` while holding the shared lock for `key`, then release it.
976
+ *
977
+ * @template T
978
+ * @param {string | string[]} key - Resource key(s) to lock (usually a filepath).
979
+ * @param {() => (Promise<T> | T)} callback
980
+ * @returns {Promise<T>}
981
+ */
982
+ function acquireLock(key, callback) {
983
+ return getLock().acquire(key, callback)
984
+ }
961
985
 
962
- // const lm = new LockManager()
963
- let lock = null;
986
+ /**
987
+ * Discard the shared lock so the next `acquireLock` starts a fresh one. Intended
988
+ * for test harnesses that run many independent scenarios inside one long-lived
989
+ * module instance: if a scenario leaves an operation stalled (e.g. a filesystem
990
+ * that hangs), its still-held lock would otherwise block every later scenario
991
+ * that touches the same path. Resetting abandons that stalled queue so the next
992
+ * scenario starts clean. It is a no-op for normal library use.
993
+ */
994
+ function _resetLock() {
995
+ lock = undefined;
996
+ }
964
997
 
965
998
  const IndexCache = Symbol('IndexCache');
966
999
 
@@ -1031,10 +1064,9 @@ class GitIndexManager {
1031
1064
  }
1032
1065
 
1033
1066
  const filepath = `${gitdir}/index`;
1034
- if (lock === null) lock = new AsyncLock({ maxPending: Infinity });
1035
1067
  let result;
1036
1068
  let unmergedPaths = [];
1037
- await lock.acquire(filepath, async () => {
1069
+ await acquireLock(filepath, async () => {
1038
1070
  // Acquire a file lock while we're reading the index
1039
1071
  // to make sure other processes aren't writing to it
1040
1072
  // simultaneously, which could result in a corrupted index.
@@ -2024,13 +2056,6 @@ function assertWritableRef(ref) {
2024
2056
  }
2025
2057
  }
2026
2058
 
2027
- let lock$1;
2028
-
2029
- async function acquireLock(ref, callback) {
2030
- if (lock$1 === undefined) lock$1 = new AsyncLock();
2031
- return lock$1.acquire(ref, callback)
2032
- }
2033
-
2034
2059
  /**
2035
2060
  * A class for managing Git references, including reading, writing, deleting, and resolving refs.
2036
2061
  */
@@ -8335,12 +8360,6 @@ const _TreeMap = {
8335
8360
  workdir: WORKDIR,
8336
8361
  };
8337
8362
 
8338
- let lock$2;
8339
- async function acquireLock$1(ref, callback) {
8340
- if (lock$2 === undefined) lock$2 = new AsyncLock();
8341
- return lock$2.acquire(ref, callback)
8342
- }
8343
-
8344
8363
  // make sure filepath, blob type and blob object (from loose objects) plus oid are in sync and valid
8345
8364
  async function checkAndWriteBlob(fs, gitdir, dir, filepath, oid = null) {
8346
8365
  const currentFilepath = join(dir, filepath);
@@ -8357,7 +8376,7 @@ async function checkAndWriteBlob(fs, gitdir, dir, filepath, oid = null) {
8357
8376
  : undefined;
8358
8377
  let retOid = objContent ? oid : undefined;
8359
8378
  if (!objContent) {
8360
- await acquireLock$1(currentFilepath, async () => {
8379
+ await acquireLock(currentFilepath, async () => {
8361
8380
  const object = stats.isSymbolicLink()
8362
8381
  ? await fs.readlink(currentFilepath).then(posixifyPathBuffer)
8363
8382
  : await fs.read(currentFilepath);
@@ -8572,7 +8591,7 @@ async function applyTreeChanges({
8572
8591
  });
8573
8592
 
8574
8593
  // apply the changes to work dir
8575
- await acquireLock$1(gitdir, async () => {
8594
+ await acquireLock(gitdir, async () => {
8576
8595
  for (const op of ops) {
8577
8596
  const currentFilepath = join(dir, op.filepath);
8578
8597
  switch (op.method) {
@@ -9526,8 +9545,6 @@ function parseRemoteUrl({ url }) {
9526
9545
  }
9527
9546
  }
9528
9547
 
9529
- let lock$3 = null;
9530
-
9531
9548
  class GitShallowManager {
9532
9549
  /**
9533
9550
  * Reads the `shallow` file in the Git repository and returns a set of object IDs (OIDs).
@@ -9538,10 +9555,9 @@ class GitShallowManager {
9538
9555
  * @returns {Promise<Set<string>>} - A set of shallow object IDs.
9539
9556
  */
9540
9557
  static async read({ fs, gitdir }) {
9541
- if (lock$3 === null) lock$3 = new AsyncLock();
9542
9558
  const filepath = join(gitdir, 'shallow');
9543
9559
  const oids = new Set();
9544
- await lock$3.acquire(filepath, async function () {
9560
+ await acquireLock(filepath, async function () {
9545
9561
  const text = await fs.read(filepath, { encoding: 'utf8' });
9546
9562
  if (text === null) return oids // no file
9547
9563
  if (text.trim() === '') return oids // empty file
@@ -9564,18 +9580,17 @@ class GitShallowManager {
9564
9580
  * @returns {Promise<void>}
9565
9581
  */
9566
9582
  static async write({ fs, gitdir, oids }) {
9567
- if (lock$3 === null) lock$3 = new AsyncLock();
9568
9583
  const filepath = join(gitdir, 'shallow');
9569
9584
  if (oids.size > 0) {
9570
9585
  const text = [...oids].join('\n') + '\n';
9571
- await lock$3.acquire(filepath, async function () {
9586
+ await acquireLock(filepath, async function () {
9572
9587
  await fs.write(filepath, text, {
9573
9588
  encoding: 'utf8',
9574
9589
  });
9575
9590
  });
9576
9591
  } else {
9577
9592
  // No shallows
9578
- await lock$3.acquire(filepath, async function () {
9593
+ await acquireLock(filepath, async function () {
9579
9594
  await fs.rm(filepath);
9580
9595
  });
9581
9596
  }
@@ -9672,8 +9687,8 @@ function filterCapabilities(server, client) {
9672
9687
 
9673
9688
  const pkg = {
9674
9689
  name: 'isomorphic-git',
9675
- version: '1.41.1',
9676
- agent: 'git/isomorphic-git@1.41.1',
9690
+ version: '1.41.2',
9691
+ agent: 'git/isomorphic-git@1.41.2',
9677
9692
  };
9678
9693
 
9679
9694
  class FIFO {
@@ -16030,7 +16045,7 @@ class GitStashManager {
16030
16045
  );
16031
16046
  const filepath = this.refLogsStashPath;
16032
16047
 
16033
- await acquireLock$1(filepath, async () => {
16048
+ await acquireLock(filepath, async () => {
16034
16049
  const appendTo = (await this.fs.exists(filepath))
16035
16050
  ? await this.fs.read(filepath, 'utf8')
16036
16051
  : '';
@@ -16224,7 +16239,7 @@ async function _stashDrop({ fs, dir, gitdir, refIdx = 0 }) {
16224
16239
  }
16225
16240
  // remove stash ref first
16226
16241
  const stashRefPath = stashMgr.refStashPath;
16227
- await acquireLock$1(stashRefPath, async () => {
16242
+ await acquireLock(stashRefPath, async () => {
16228
16243
  if (await fs.exists(stashRefPath)) {
16229
16244
  await fs.rm(stashRefPath);
16230
16245
  }
@@ -16240,7 +16255,7 @@ async function _stashDrop({ fs, dir, gitdir, refIdx = 0 }) {
16240
16255
  reflogEntries.splice(refIdx, 1);
16241
16256
 
16242
16257
  const stashReflogPath = stashMgr.refLogsStashPath;
16243
- await acquireLock$1(stashReflogPath, async () => {
16258
+ await acquireLock(stashReflogPath, async () => {
16244
16259
  if (reflogEntries.length) {
16245
16260
  await fs.write(
16246
16261
  stashReflogPath,
@@ -16266,7 +16281,7 @@ async function _stashClear({ fs, dir, gitdir }) {
16266
16281
  const stashMgr = new GitStashManager({ fs, dir, gitdir });
16267
16282
  const stashRefPath = [stashMgr.refStashPath, stashMgr.refLogsStashPath];
16268
16283
 
16269
- await acquireLock$1(stashRefPath, async () => {
16284
+ await acquireLock(stashRefPath, async () => {
16270
16285
  await Promise.all(
16271
16286
  stashRefPath.map(async path => {
16272
16287
  if (await fs.exists(path)) {