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 +49 -34
- package/index.js +49 -34
- package/index.umd.min.js +1 -1
- package/index.umd.min.js.map +1 -1
- package/managers/index.cjs +44 -29
- package/managers/index.js +44 -29
- package/managers/index.umd.min.js +1 -1
- package/managers/index.umd.min.js.map +1 -1
- package/package.json +1 -1
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
|
-
//
|
|
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
|
-
|
|
970
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
9689
|
-
agent: 'git/isomorphic-git@1.41.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
//
|
|
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
|
-
|
|
963
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
9676
|
-
agent: 'git/isomorphic-git@1.41.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
16284
|
+
await acquireLock(stashRefPath, async () => {
|
|
16270
16285
|
await Promise.all(
|
|
16271
16286
|
stashRefPath.map(async path => {
|
|
16272
16287
|
if (await fs.exists(path)) {
|