isomorphic-git 1.41.0 → 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;
968
975
 
969
- // const lm = new LockManager()
970
- let lock = null;
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
+ }
992
+
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) {
@@ -8974,21 +8993,76 @@ async function collect(iterable) {
8974
8993
  return result
8975
8994
  }
8976
8995
 
8996
+ // The `@` that ends the credentials is the last one in the authority, and the
8997
+ // scheme is matched case-insensitively: `HTTPS://user:pass@host/x` is a URL
8998
+ // like any other, and leaving the credentials in it is what `fetch` rejects.
8999
+ // The authority ends at the first `/`, `?` or `#`, so an `@` that lives in a
9000
+ // query or a fragment is left where it is.
9001
+ const CREDENTIALS = /^(https?:\/\/)([^/?#]+)@/i;
9002
+
8977
9003
  function extractAuthFromUrl(url) {
8978
9004
  // For whatever reason, the `fetch` API does not convert credentials embedded in the URL
8979
9005
  // into Basic Authentication headers automatically. Instead it throws an error!
8980
9006
  // So we must manually parse the URL, rip out the user:password portion if it is present
8981
9007
  // and compute the Authorization header.
8982
- // Note: I tried using new URL(url) but that throws a security exception in Edge. :rolleyes:
8983
- let userpass = url.match(/^https?:\/\/([^/]+)@/);
9008
+ const credentials = url.match(CREDENTIALS);
8984
9009
  // No credentials, return the url unmodified and an empty auth object
8985
- if (userpass == null) return { url, auth: {} }
8986
- userpass = userpass[1];
8987
- const [username, password] = userpass.split(':');
8988
- // Remove credentials from URL
8989
- url = url.replace(`${userpass}@`, '');
8990
- // Has credentials, return the fetch-safe URL and the parsed credentials
8991
- return { url, auth: { username, password } }
9010
+ if (credentials == null) return { url, auth: {} }
9011
+ // Has credentials, return the fetch-safe URL and the parsed credentials.
9012
+ // The credentials are cut out of the original string rather than read back
9013
+ // off the parsed URL: serializing that one would also drop an explicit
9014
+ // `:443` and append a slash to a URL that has no path, and this return value
9015
+ // is what the request goes out against.
9016
+ return {
9017
+ url: url.replace(CREDENTIALS, '$1'),
9018
+ auth: parseUserinfo(url, credentials[2]),
9019
+ }
9020
+ }
9021
+
9022
+ function parseUserinfo(url, userpass) {
9023
+ // `URL` splits the two halves the way the platform does, so the first colon
9024
+ // separates them and any later one stays in the password. Only the split is
9025
+ // taken from it, for the reason above.
9026
+ const parsed = parseUrl(url);
9027
+ // A password is absent, not empty, when no colon was written at all. `URL`
9028
+ // reports `''` for both, and the difference is worth keeping.
9029
+ const hasPassword = userpass.indexOf(':') !== -1;
9030
+
9031
+ if (parsed !== null) {
9032
+ return {
9033
+ username: decodeUserinfo(parsed.username),
9034
+ password: hasPassword ? decodeUserinfo(parsed.password) : undefined,
9035
+ }
9036
+ }
9037
+
9038
+ // No `URL` to parse with, or it rejected a string the expression above
9039
+ // accepted. Split on the first colon by hand, without the percent-decoding.
9040
+ const separatorIndex = userpass.indexOf(':');
9041
+ return {
9042
+ username: hasPassword ? userpass.slice(0, separatorIndex) : userpass,
9043
+ password: hasPassword ? userpass.slice(separatorIndex + 1) : undefined,
9044
+ }
9045
+ }
9046
+
9047
+ function parseUrl(url) {
9048
+ if (typeof URL !== 'function') return null
9049
+ try {
9050
+ return new URL(url)
9051
+ } catch (_) {
9052
+ return null
9053
+ }
9054
+ }
9055
+
9056
+ // `URL` hands back the userinfo still percent-encoded, so `p:ss` arrives as
9057
+ // `p%3Ass` and has to be decoded before it reaches the Authorization header. A
9058
+ // lone `%` is not something the parser encodes, and it makes the decode throw,
9059
+ // so the raw value stands in whenever the decode fails.
9060
+ function decodeUserinfo(value) {
9061
+ try {
9062
+ return decodeURIComponent(value)
9063
+ } catch (_) {
9064
+ return value
9065
+ }
8992
9066
  }
8993
9067
 
8994
9068
  function padHex(b, n) {
@@ -9484,8 +9558,6 @@ function parseRemoteUrl({ url }) {
9484
9558
  }
9485
9559
  }
9486
9560
 
9487
- let lock$3 = null;
9488
-
9489
9561
  class GitShallowManager {
9490
9562
  /**
9491
9563
  * Reads the `shallow` file in the Git repository and returns a set of object IDs (OIDs).
@@ -9496,10 +9568,9 @@ class GitShallowManager {
9496
9568
  * @returns {Promise<Set<string>>} - A set of shallow object IDs.
9497
9569
  */
9498
9570
  static async read({ fs, gitdir }) {
9499
- if (lock$3 === null) lock$3 = new AsyncLock();
9500
9571
  const filepath = join(gitdir, 'shallow');
9501
9572
  const oids = new Set();
9502
- await lock$3.acquire(filepath, async function () {
9573
+ await acquireLock(filepath, async function () {
9503
9574
  const text = await fs.read(filepath, { encoding: 'utf8' });
9504
9575
  if (text === null) return oids // no file
9505
9576
  if (text.trim() === '') return oids // empty file
@@ -9522,18 +9593,17 @@ class GitShallowManager {
9522
9593
  * @returns {Promise<void>}
9523
9594
  */
9524
9595
  static async write({ fs, gitdir, oids }) {
9525
- if (lock$3 === null) lock$3 = new AsyncLock();
9526
9596
  const filepath = join(gitdir, 'shallow');
9527
9597
  if (oids.size > 0) {
9528
9598
  const text = [...oids].join('\n') + '\n';
9529
- await lock$3.acquire(filepath, async function () {
9599
+ await acquireLock(filepath, async function () {
9530
9600
  await fs.write(filepath, text, {
9531
9601
  encoding: 'utf8',
9532
9602
  });
9533
9603
  });
9534
9604
  } else {
9535
9605
  // No shallows
9536
- await lock$3.acquire(filepath, async function () {
9606
+ await acquireLock(filepath, async function () {
9537
9607
  await fs.rm(filepath);
9538
9608
  });
9539
9609
  }
@@ -9630,8 +9700,8 @@ function filterCapabilities(server, client) {
9630
9700
 
9631
9701
  const pkg = {
9632
9702
  name: 'isomorphic-git',
9633
- version: '1.41.0',
9634
- agent: 'git/isomorphic-git@1.41.0',
9703
+ version: '1.41.2',
9704
+ agent: 'git/isomorphic-git@1.41.2',
9635
9705
  };
9636
9706
 
9637
9707
  class FIFO {
@@ -15988,7 +16058,7 @@ class GitStashManager {
15988
16058
  );
15989
16059
  const filepath = this.refLogsStashPath;
15990
16060
 
15991
- await acquireLock$1(filepath, async () => {
16061
+ await acquireLock(filepath, async () => {
15992
16062
  const appendTo = (await this.fs.exists(filepath))
15993
16063
  ? await this.fs.read(filepath, 'utf8')
15994
16064
  : '';
@@ -16182,7 +16252,7 @@ async function _stashDrop({ fs, dir, gitdir, refIdx = 0 }) {
16182
16252
  }
16183
16253
  // remove stash ref first
16184
16254
  const stashRefPath = stashMgr.refStashPath;
16185
- await acquireLock$1(stashRefPath, async () => {
16255
+ await acquireLock(stashRefPath, async () => {
16186
16256
  if (await fs.exists(stashRefPath)) {
16187
16257
  await fs.rm(stashRefPath);
16188
16258
  }
@@ -16198,7 +16268,7 @@ async function _stashDrop({ fs, dir, gitdir, refIdx = 0 }) {
16198
16268
  reflogEntries.splice(refIdx, 1);
16199
16269
 
16200
16270
  const stashReflogPath = stashMgr.refLogsStashPath;
16201
- await acquireLock$1(stashReflogPath, async () => {
16271
+ await acquireLock(stashReflogPath, async () => {
16202
16272
  if (reflogEntries.length) {
16203
16273
  await fs.write(
16204
16274
  stashReflogPath,
@@ -16224,7 +16294,7 @@ async function _stashClear({ fs, dir, gitdir }) {
16224
16294
  const stashMgr = new GitStashManager({ fs, dir, gitdir });
16225
16295
  const stashRefPath = [stashMgr.refStashPath, stashMgr.refLogsStashPath];
16226
16296
 
16227
- await acquireLock$1(stashRefPath, async () => {
16297
+ await acquireLock(stashRefPath, async () => {
16228
16298
  await Promise.all(
16229
16299
  stashRefPath.map(async path => {
16230
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;
961
968
 
962
- // const lm = new LockManager()
963
- let lock = null;
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
+ }
985
+
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) {
@@ -8961,21 +8980,76 @@ async function collect(iterable) {
8961
8980
  return result
8962
8981
  }
8963
8982
 
8983
+ // The `@` that ends the credentials is the last one in the authority, and the
8984
+ // scheme is matched case-insensitively: `HTTPS://user:pass@host/x` is a URL
8985
+ // like any other, and leaving the credentials in it is what `fetch` rejects.
8986
+ // The authority ends at the first `/`, `?` or `#`, so an `@` that lives in a
8987
+ // query or a fragment is left where it is.
8988
+ const CREDENTIALS = /^(https?:\/\/)([^/?#]+)@/i;
8989
+
8964
8990
  function extractAuthFromUrl(url) {
8965
8991
  // For whatever reason, the `fetch` API does not convert credentials embedded in the URL
8966
8992
  // into Basic Authentication headers automatically. Instead it throws an error!
8967
8993
  // So we must manually parse the URL, rip out the user:password portion if it is present
8968
8994
  // and compute the Authorization header.
8969
- // Note: I tried using new URL(url) but that throws a security exception in Edge. :rolleyes:
8970
- let userpass = url.match(/^https?:\/\/([^/]+)@/);
8995
+ const credentials = url.match(CREDENTIALS);
8971
8996
  // No credentials, return the url unmodified and an empty auth object
8972
- if (userpass == null) return { url, auth: {} }
8973
- userpass = userpass[1];
8974
- const [username, password] = userpass.split(':');
8975
- // Remove credentials from URL
8976
- url = url.replace(`${userpass}@`, '');
8977
- // Has credentials, return the fetch-safe URL and the parsed credentials
8978
- return { url, auth: { username, password } }
8997
+ if (credentials == null) return { url, auth: {} }
8998
+ // Has credentials, return the fetch-safe URL and the parsed credentials.
8999
+ // The credentials are cut out of the original string rather than read back
9000
+ // off the parsed URL: serializing that one would also drop an explicit
9001
+ // `:443` and append a slash to a URL that has no path, and this return value
9002
+ // is what the request goes out against.
9003
+ return {
9004
+ url: url.replace(CREDENTIALS, '$1'),
9005
+ auth: parseUserinfo(url, credentials[2]),
9006
+ }
9007
+ }
9008
+
9009
+ function parseUserinfo(url, userpass) {
9010
+ // `URL` splits the two halves the way the platform does, so the first colon
9011
+ // separates them and any later one stays in the password. Only the split is
9012
+ // taken from it, for the reason above.
9013
+ const parsed = parseUrl(url);
9014
+ // A password is absent, not empty, when no colon was written at all. `URL`
9015
+ // reports `''` for both, and the difference is worth keeping.
9016
+ const hasPassword = userpass.indexOf(':') !== -1;
9017
+
9018
+ if (parsed !== null) {
9019
+ return {
9020
+ username: decodeUserinfo(parsed.username),
9021
+ password: hasPassword ? decodeUserinfo(parsed.password) : undefined,
9022
+ }
9023
+ }
9024
+
9025
+ // No `URL` to parse with, or it rejected a string the expression above
9026
+ // accepted. Split on the first colon by hand, without the percent-decoding.
9027
+ const separatorIndex = userpass.indexOf(':');
9028
+ return {
9029
+ username: hasPassword ? userpass.slice(0, separatorIndex) : userpass,
9030
+ password: hasPassword ? userpass.slice(separatorIndex + 1) : undefined,
9031
+ }
9032
+ }
9033
+
9034
+ function parseUrl(url) {
9035
+ if (typeof URL !== 'function') return null
9036
+ try {
9037
+ return new URL(url)
9038
+ } catch (_) {
9039
+ return null
9040
+ }
9041
+ }
9042
+
9043
+ // `URL` hands back the userinfo still percent-encoded, so `p:ss` arrives as
9044
+ // `p%3Ass` and has to be decoded before it reaches the Authorization header. A
9045
+ // lone `%` is not something the parser encodes, and it makes the decode throw,
9046
+ // so the raw value stands in whenever the decode fails.
9047
+ function decodeUserinfo(value) {
9048
+ try {
9049
+ return decodeURIComponent(value)
9050
+ } catch (_) {
9051
+ return value
9052
+ }
8979
9053
  }
8980
9054
 
8981
9055
  function padHex(b, n) {
@@ -9471,8 +9545,6 @@ function parseRemoteUrl({ url }) {
9471
9545
  }
9472
9546
  }
9473
9547
 
9474
- let lock$3 = null;
9475
-
9476
9548
  class GitShallowManager {
9477
9549
  /**
9478
9550
  * Reads the `shallow` file in the Git repository and returns a set of object IDs (OIDs).
@@ -9483,10 +9555,9 @@ class GitShallowManager {
9483
9555
  * @returns {Promise<Set<string>>} - A set of shallow object IDs.
9484
9556
  */
9485
9557
  static async read({ fs, gitdir }) {
9486
- if (lock$3 === null) lock$3 = new AsyncLock();
9487
9558
  const filepath = join(gitdir, 'shallow');
9488
9559
  const oids = new Set();
9489
- await lock$3.acquire(filepath, async function () {
9560
+ await acquireLock(filepath, async function () {
9490
9561
  const text = await fs.read(filepath, { encoding: 'utf8' });
9491
9562
  if (text === null) return oids // no file
9492
9563
  if (text.trim() === '') return oids // empty file
@@ -9509,18 +9580,17 @@ class GitShallowManager {
9509
9580
  * @returns {Promise<void>}
9510
9581
  */
9511
9582
  static async write({ fs, gitdir, oids }) {
9512
- if (lock$3 === null) lock$3 = new AsyncLock();
9513
9583
  const filepath = join(gitdir, 'shallow');
9514
9584
  if (oids.size > 0) {
9515
9585
  const text = [...oids].join('\n') + '\n';
9516
- await lock$3.acquire(filepath, async function () {
9586
+ await acquireLock(filepath, async function () {
9517
9587
  await fs.write(filepath, text, {
9518
9588
  encoding: 'utf8',
9519
9589
  });
9520
9590
  });
9521
9591
  } else {
9522
9592
  // No shallows
9523
- await lock$3.acquire(filepath, async function () {
9593
+ await acquireLock(filepath, async function () {
9524
9594
  await fs.rm(filepath);
9525
9595
  });
9526
9596
  }
@@ -9617,8 +9687,8 @@ function filterCapabilities(server, client) {
9617
9687
 
9618
9688
  const pkg = {
9619
9689
  name: 'isomorphic-git',
9620
- version: '1.41.0',
9621
- agent: 'git/isomorphic-git@1.41.0',
9690
+ version: '1.41.2',
9691
+ agent: 'git/isomorphic-git@1.41.2',
9622
9692
  };
9623
9693
 
9624
9694
  class FIFO {
@@ -15975,7 +16045,7 @@ class GitStashManager {
15975
16045
  );
15976
16046
  const filepath = this.refLogsStashPath;
15977
16047
 
15978
- await acquireLock$1(filepath, async () => {
16048
+ await acquireLock(filepath, async () => {
15979
16049
  const appendTo = (await this.fs.exists(filepath))
15980
16050
  ? await this.fs.read(filepath, 'utf8')
15981
16051
  : '';
@@ -16169,7 +16239,7 @@ async function _stashDrop({ fs, dir, gitdir, refIdx = 0 }) {
16169
16239
  }
16170
16240
  // remove stash ref first
16171
16241
  const stashRefPath = stashMgr.refStashPath;
16172
- await acquireLock$1(stashRefPath, async () => {
16242
+ await acquireLock(stashRefPath, async () => {
16173
16243
  if (await fs.exists(stashRefPath)) {
16174
16244
  await fs.rm(stashRefPath);
16175
16245
  }
@@ -16185,7 +16255,7 @@ async function _stashDrop({ fs, dir, gitdir, refIdx = 0 }) {
16185
16255
  reflogEntries.splice(refIdx, 1);
16186
16256
 
16187
16257
  const stashReflogPath = stashMgr.refLogsStashPath;
16188
- await acquireLock$1(stashReflogPath, async () => {
16258
+ await acquireLock(stashReflogPath, async () => {
16189
16259
  if (reflogEntries.length) {
16190
16260
  await fs.write(
16191
16261
  stashReflogPath,
@@ -16211,7 +16281,7 @@ async function _stashClear({ fs, dir, gitdir }) {
16211
16281
  const stashMgr = new GitStashManager({ fs, dir, gitdir });
16212
16282
  const stashRefPath = [stashMgr.refStashPath, stashMgr.refLogsStashPath];
16213
16283
 
16214
- await acquireLock$1(stashRefPath, async () => {
16284
+ await acquireLock(stashRefPath, async () => {
16215
16285
  await Promise.all(
16216
16286
  stashRefPath.map(async path => {
16217
16287
  if (await fs.exists(path)) {