isomorphic-git 1.40.7 → 1.41.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.
@@ -28,6 +28,7 @@ var get = _interopDefault(require('simple-get'));
28
28
  * @property {AsyncIterableIterator<Uint8Array>} [body] - An async iterator of Uint8Arrays that make up the body of POST requests
29
29
  * @property {ProgressCallback} [onProgress] - Reserved for future use (emitting `GitProgressEvent`s)
30
30
  * @property {object} [signal] - Reserved for future use (canceling a request)
31
+ * @property {Object} [fetchOptions={}] - Additional options to pass to fetch (Web) or simple-get (Node)
31
32
  */
32
33
 
33
34
  /**
@@ -94,6 +95,7 @@ async function forAwait(iterable, cb) {
94
95
  }
95
96
 
96
97
  function asyncIteratorToStream(iter) {
98
+ // @ts-expect-error: readable-stream has PassThrough at runtime, types mismatch
97
99
  const { PassThrough } = require('readable-stream');
98
100
  const stream = new PassThrough();
99
101
  setTimeout(async () => {
@@ -194,10 +196,12 @@ async function request({
194
196
  method = 'GET',
195
197
  headers = {},
196
198
  agent,
199
+ fetchOptions = {},
197
200
  body,
198
201
  }) {
199
202
  // If we can, we should send it as a single buffer so it sets a Content-Length header.
200
203
  if (body && Array.isArray(body)) {
204
+ // @ts-expect-error
201
205
  body = Buffer.from(await collect(body));
202
206
  } else if (body) {
203
207
  body = asyncIteratorToStream(body);
@@ -205,6 +209,7 @@ async function request({
205
209
  return new Promise((resolve, reject) => {
206
210
  get(
207
211
  {
212
+ ...fetchOptions,
208
213
  url,
209
214
  method,
210
215
  headers,
@@ -37,6 +37,10 @@ export type GitHttpRequest = {
37
37
  * - Reserved for future use (canceling a request)
38
38
  */
39
39
  signal?: object;
40
+ /**
41
+ * - Additional options to pass to fetch (Web) or simple-get (Node)
42
+ */
43
+ fetchOptions?: any;
40
44
  };
41
45
  export type GitHttpResponse = {
42
46
  /**
@@ -79,4 +83,4 @@ declare namespace index {
79
83
  * @param {GitHttpRequest} request
80
84
  * @returns {Promise<GitHttpResponse>}
81
85
  */
82
- export function request({ onProgress, url, method, headers, agent, body, }: GitHttpRequest): Promise<GitHttpResponse>;
86
+ export function request({ onProgress, url, method, headers, agent, fetchOptions, body, }: GitHttpRequest): Promise<GitHttpResponse>;
@@ -36,6 +36,10 @@ export type GitHttpRequest = {
36
36
  * - Reserved for future use (canceling a request)
37
37
  */
38
38
  signal?: object;
39
+ /**
40
+ * - Additional options to pass to fetch (Web) or simple-get (Node)
41
+ */
42
+ fetchOptions?: any;
39
43
  };
40
44
  export type GitHttpResponse = {
41
45
  /**
@@ -78,4 +82,4 @@ declare namespace index {
78
82
  * @param {GitHttpRequest} request
79
83
  * @returns {Promise<GitHttpResponse>}
80
84
  */
81
- export function request({ onProgress, url, method, headers, agent, body, }: GitHttpRequest): Promise<GitHttpResponse>;
85
+ export function request({ onProgress, url, method, headers, agent, fetchOptions, body, }: GitHttpRequest): Promise<GitHttpResponse>;
@@ -22,6 +22,7 @@ import get from 'simple-get';
22
22
  * @property {AsyncIterableIterator<Uint8Array>} [body] - An async iterator of Uint8Arrays that make up the body of POST requests
23
23
  * @property {ProgressCallback} [onProgress] - Reserved for future use (emitting `GitProgressEvent`s)
24
24
  * @property {object} [signal] - Reserved for future use (canceling a request)
25
+ * @property {Object} [fetchOptions={}] - Additional options to pass to fetch (Web) or simple-get (Node)
25
26
  */
26
27
 
27
28
  /**
@@ -88,6 +89,7 @@ async function forAwait(iterable, cb) {
88
89
  }
89
90
 
90
91
  function asyncIteratorToStream(iter) {
92
+ // @ts-expect-error: readable-stream has PassThrough at runtime, types mismatch
91
93
  const { PassThrough } = require('readable-stream');
92
94
  const stream = new PassThrough();
93
95
  setTimeout(async () => {
@@ -188,10 +190,12 @@ async function request({
188
190
  method = 'GET',
189
191
  headers = {},
190
192
  agent,
193
+ fetchOptions = {},
191
194
  body,
192
195
  }) {
193
196
  // If we can, we should send it as a single buffer so it sets a Content-Length header.
194
197
  if (body && Array.isArray(body)) {
198
+ // @ts-expect-error
195
199
  body = Buffer.from(await collect(body));
196
200
  } else if (body) {
197
201
  body = asyncIteratorToStream(body);
@@ -199,6 +203,7 @@ async function request({
199
203
  return new Promise((resolve, reject) => {
200
204
  get(
201
205
  {
206
+ ...fetchOptions,
202
207
  url,
203
208
  method,
204
209
  headers,
@@ -24,6 +24,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
24
24
  * @property {AsyncIterableIterator<Uint8Array>} [body] - An async iterator of Uint8Arrays that make up the body of POST requests
25
25
  * @property {ProgressCallback} [onProgress] - Reserved for future use (emitting `GitProgressEvent`s)
26
26
  * @property {object} [signal] - Reserved for future use (canceling a request)
27
+ * @property {Object} [fetchOptions={}] - Additional options to pass to fetch (Web) or simple-get (Node)
27
28
  */
28
29
 
29
30
  /**
@@ -139,24 +140,29 @@ async function request({
139
140
  url,
140
141
  method = 'GET',
141
142
  headers = {},
143
+ fetchOptions = {},
142
144
  body,
143
145
  }) {
144
146
  // streaming uploads aren't possible yet in the browser
145
147
  if (body) {
148
+ // @ts-expect-error
146
149
  body = await collect(body);
147
150
  }
148
- const res = await fetch(url, { method, headers, body });
151
+ const res = await fetch(url, { ...fetchOptions, method, headers, body });
149
152
  const iter =
153
+ // @ts-expect-error
150
154
  res.body && res.body.getReader
151
155
  ? fromStream(res.body)
152
156
  : [new Uint8Array(await res.arrayBuffer())];
153
157
  // convert Header object to ordinary JSON
154
158
  headers = {};
159
+ // @ts-expect-error
155
160
  for (const [key, value] of res.headers.entries()) {
156
161
  headers[key] = value;
157
162
  }
158
163
  return {
159
164
  url: res.url,
165
+ // @ts-expect-error
160
166
  method: res.method,
161
167
  statusCode: res.status,
162
168
  statusMessage: res.statusText,
@@ -37,6 +37,10 @@ export type GitHttpRequest = {
37
37
  * - Reserved for future use (canceling a request)
38
38
  */
39
39
  signal?: object;
40
+ /**
41
+ * - Additional options to pass to fetch (Web) or simple-get (Node)
42
+ */
43
+ fetchOptions?: any;
40
44
  };
41
45
  export type GitHttpResponse = {
42
46
  /**
@@ -79,4 +83,4 @@ declare namespace index {
79
83
  * @param {GitHttpRequest} request
80
84
  * @returns {Promise<GitHttpResponse>}
81
85
  */
82
- export function request({ onProgress, url, method, headers, body, }: GitHttpRequest): Promise<GitHttpResponse>;
86
+ export function request({ onProgress, url, method, headers, fetchOptions, body, }: GitHttpRequest): Promise<GitHttpResponse>;
@@ -36,6 +36,10 @@ export type GitHttpRequest = {
36
36
  * - Reserved for future use (canceling a request)
37
37
  */
38
38
  signal?: object;
39
+ /**
40
+ * - Additional options to pass to fetch (Web) or simple-get (Node)
41
+ */
42
+ fetchOptions?: any;
39
43
  };
40
44
  export type GitHttpResponse = {
41
45
  /**
@@ -78,4 +82,4 @@ declare namespace index {
78
82
  * @param {GitHttpRequest} request
79
83
  * @returns {Promise<GitHttpResponse>}
80
84
  */
81
- export function request({ onProgress, url, method, headers, body, }: GitHttpRequest): Promise<GitHttpResponse>;
85
+ export function request({ onProgress, url, method, headers, fetchOptions, body, }: GitHttpRequest): Promise<GitHttpResponse>;
package/http/web/index.js CHANGED
@@ -20,6 +20,7 @@
20
20
  * @property {AsyncIterableIterator<Uint8Array>} [body] - An async iterator of Uint8Arrays that make up the body of POST requests
21
21
  * @property {ProgressCallback} [onProgress] - Reserved for future use (emitting `GitProgressEvent`s)
22
22
  * @property {object} [signal] - Reserved for future use (canceling a request)
23
+ * @property {Object} [fetchOptions={}] - Additional options to pass to fetch (Web) or simple-get (Node)
23
24
  */
24
25
 
25
26
  /**
@@ -135,24 +136,29 @@ async function request({
135
136
  url,
136
137
  method = 'GET',
137
138
  headers = {},
139
+ fetchOptions = {},
138
140
  body,
139
141
  }) {
140
142
  // streaming uploads aren't possible yet in the browser
141
143
  if (body) {
144
+ // @ts-expect-error
142
145
  body = await collect(body);
143
146
  }
144
- const res = await fetch(url, { method, headers, body });
147
+ const res = await fetch(url, { ...fetchOptions, method, headers, body });
145
148
  const iter =
149
+ // @ts-expect-error
146
150
  res.body && res.body.getReader
147
151
  ? fromStream(res.body)
148
152
  : [new Uint8Array(await res.arrayBuffer())];
149
153
  // convert Header object to ordinary JSON
150
154
  headers = {};
155
+ // @ts-expect-error
151
156
  for (const [key, value] of res.headers.entries()) {
152
157
  headers[key] = value;
153
158
  }
154
159
  return {
155
160
  url: res.url,
161
+ // @ts-expect-error
156
162
  method: res.method,
157
163
  statusCode: res.status,
158
164
  statusMessage: res.statusText,
@@ -26,6 +26,7 @@
26
26
  * @property {AsyncIterableIterator<Uint8Array>} [body] - An async iterator of Uint8Arrays that make up the body of POST requests
27
27
  * @property {ProgressCallback} [onProgress] - Reserved for future use (emitting `GitProgressEvent`s)
28
28
  * @property {object} [signal] - Reserved for future use (canceling a request)
29
+ * @property {Object} [fetchOptions={}] - Additional options to pass to fetch (Web) or simple-get (Node)
29
30
  */
30
31
 
31
32
  /**
@@ -141,24 +142,29 @@
141
142
  url,
142
143
  method = 'GET',
143
144
  headers = {},
145
+ fetchOptions = {},
144
146
  body,
145
147
  }) {
146
148
  // streaming uploads aren't possible yet in the browser
147
149
  if (body) {
150
+ // @ts-expect-error
148
151
  body = await collect(body);
149
152
  }
150
- const res = await fetch(url, { method, headers, body });
153
+ const res = await fetch(url, { ...fetchOptions, method, headers, body });
151
154
  const iter =
155
+ // @ts-expect-error
152
156
  res.body && res.body.getReader
153
157
  ? fromStream(res.body)
154
158
  : [new Uint8Array(await res.arrayBuffer())];
155
159
  // convert Header object to ordinary JSON
156
160
  headers = {};
161
+ // @ts-expect-error
157
162
  for (const [key, value] of res.headers.entries()) {
158
163
  headers[key] = value;
159
164
  }
160
165
  return {
161
166
  url: res.url,
167
+ // @ts-expect-error
162
168
  method: res.method,
163
169
  statusCode: res.status,
164
170
  statusMessage: res.statusText,
package/index.cjs CHANGED
@@ -36,6 +36,7 @@ var diff3Merge = _interopDefault(require('diff3'));
36
36
  * @property {AsyncIterableIterator<Uint8Array>} [body] - An async iterator of Uint8Arrays that make up the body of POST requests
37
37
  * @property {ProgressCallback} [onProgress] - Reserved for future use (emitting `GitProgressEvent`s)
38
38
  * @property {object} [signal] - Reserved for future use (canceling a request)
39
+ * @property {Object} [fetchOptions={}] - Additional options to pass to fetch (Web) or simple-get (Node)
39
40
  */
40
41
 
41
42
  /**
@@ -5021,6 +5022,67 @@ async function _walk({
5021
5022
  return walk(root)
5022
5023
  }
5023
5024
 
5025
+ /**
5026
+ * Recursively creates the directory at `filepath`, creating any missing parent
5027
+ * directories along the way. This is a portable replacement for
5028
+ * `fs.mkdir(path, { recursive: true })`: recursive `mkdir` is NOT part of
5029
+ * isomorphic-git's required `fs` contract (see docs/fs.md — `mkdir` is only
5030
+ * `mkdir(path[, mode])`) and is unimplemented by some backends such as
5031
+ * lightning-fs, so we build it here on top of a single-level `mkdir(path)`
5032
+ * primitive only — mirroring how `rmRecursive` provides `rm({ recursive: true })`.
5033
+ *
5034
+ * It takes the raw single-level `mkdir` *function* (typically `fs._mkdir`)
5035
+ * rather than the FileSystem wrapper, to stay decoupled from that type.
5036
+ *
5037
+ * `EEXIST` is treated as success, so two callers concurrently creating the same
5038
+ * directory (e.g. several reflog writes into `.git/logs/refs/*` during a stash)
5039
+ * don't fail each other. On backends whose layers are only eventually
5040
+ * consistent — e.g. an async copy-on-write overlay — a just-created parent may
5041
+ * not yet be visible when its child is created, so `mkdir` can throw a
5042
+ * transient `ENOENT`; those are retried a bounded number of times rather than
5043
+ * surfaced as a spurious failure.
5044
+ *
5045
+ * @param {(filepath: string) => Promise<unknown>} mkdir - Creates a single directory (non-recursive).
5046
+ * @param {string} filepath - The directory to create.
5047
+ * @param {number} [retries=10] - Max transient-ENOENT retries after the parent exists.
5048
+ * @returns {Promise<void>}
5049
+ */
5050
+ async function mkdirp(mkdir, filepath, retries = 10) {
5051
+ try {
5052
+ await mkdir(filepath);
5053
+ } catch (err) {
5054
+ // Some fs implementations signal success by yielding a null error.
5055
+ if (err === null) return
5056
+ // The directory already exists — that's fine.
5057
+ if (err.code === 'EEXIST') return
5058
+ // Anything other than a missing parent is a real error.
5059
+ if (err.code !== 'ENOENT') throw err
5060
+ const parent = dirname(filepath);
5061
+ // Stop if we've walked past the filesystem root.
5062
+ if (parent === '.' || parent === '/' || parent === filepath) throw err
5063
+ // Create the missing parent(s) first, honoring the same retry budget.
5064
+ await mkdirp(mkdir, parent, retries);
5065
+ // Then (re)create this directory. On an eventually-consistent backend the
5066
+ // parent may not be visible immediately after its mkdir resolves, so a
5067
+ // repeated ENOENT here is transient — retry a bounded number of times,
5068
+ // yielding between attempts so the pending write can settle.
5069
+ for (let attempt = 0; ; attempt++) {
5070
+ try {
5071
+ await mkdir(filepath);
5072
+ return
5073
+ } catch (err2) {
5074
+ if (err2 === null || err2.code === 'EEXIST') return
5075
+ if (err2.code === 'ENOENT' && attempt < retries) {
5076
+ // Give the backend a turn of the event loop to become consistent.
5077
+ await new Promise(resolve => setTimeout(resolve, 0));
5078
+ continue
5079
+ }
5080
+ throw err2
5081
+ }
5082
+ }
5083
+ }
5084
+ }
5085
+
5024
5086
  /**
5025
5087
  * Removes the directory at the specified filepath recursively. Used internally to replicate the behavior of
5026
5088
  * fs.promises.rm({ recursive: true, force: true }) from Node.js 14 and above when not available. If the provided
@@ -5213,29 +5275,17 @@ class FileSystem {
5213
5275
  * Make a directory (or series of nested directories) without throwing an error if it already exists.
5214
5276
  *
5215
5277
  * @param {string} filepath - The path to the directory.
5216
- * @param {boolean} [_selfCall=false] - Internal flag to prevent infinite recursion.
5217
5278
  * @returns {Promise<void>}
5218
5279
  */
5219
- async mkdir(filepath, _selfCall = false) {
5220
- try {
5221
- await this._mkdir(filepath);
5222
- } catch (err) {
5223
- // If err is null then operation succeeded!
5224
- if (err === null) return
5225
- // If the directory already exists, that's OK!
5226
- if (err.code === 'EEXIST') return
5227
- // Avoid infinite loops of failure
5228
- if (_selfCall) throw err
5229
- // If we got a "no such file or directory error" backup and try again.
5230
- if (err.code === 'ENOENT') {
5231
- const parent = dirname(filepath);
5232
- // Check to see if we've gone too far
5233
- if (parent === '.' || parent === '/' || parent === filepath) throw err
5234
- // Infinite recursion, what could go wrong?
5235
- await this.mkdir(parent);
5236
- await this.mkdir(filepath, true);
5237
- }
5238
- }
5280
+ async mkdir(filepath) {
5281
+ // Recursively create the directory, using only single-level `_mkdir` so we
5282
+ // don't depend on `{ recursive: true }` (which isn't part of the required
5283
+ // `fs` contract — see docs/fs.md — and is unimplemented by some backends
5284
+ // e.g. lightning-fs). The helper tolerates EEXIST and the transient ENOENT
5285
+ // that eventually-consistent backends throw when a freshly created parent
5286
+ // isn't visible yet, which is what made concurrent reflog writes into
5287
+ // `.git/logs/refs/*` fail intermittently.
5288
+ await mkdirp(this._mkdir, filepath);
5239
5289
  }
5240
5290
 
5241
5291
  /**
@@ -9580,8 +9630,8 @@ function filterCapabilities(server, client) {
9580
9630
 
9581
9631
  const pkg = {
9582
9632
  name: 'isomorphic-git',
9583
- version: '1.40.7',
9584
- agent: 'git/isomorphic-git@1.40.7',
9633
+ version: '1.41.0',
9634
+ agent: 'git/isomorphic-git@1.41.0',
9585
9635
  };
9586
9636
 
9587
9637
  class FIFO {
package/index.d.cts CHANGED
@@ -305,6 +305,10 @@ export type GitHttpRequest = {
305
305
  * - Reserved for future use (canceling a request)
306
306
  */
307
307
  signal?: object;
308
+ /**
309
+ * - Additional options to pass to fetch (Web) or simple-get (Node)
310
+ */
311
+ fetchOptions?: any;
308
312
  };
309
313
  export type GitHttpResponse = {
310
314
  /**
@@ -4501,6 +4505,7 @@ declare namespace NoCommitError {
4501
4505
  * @property {AsyncIterableIterator<Uint8Array>} [body] - An async iterator of Uint8Arrays that make up the body of POST requests
4502
4506
  * @property {ProgressCallback} [onProgress] - Reserved for future use (emitting `GitProgressEvent`s)
4503
4507
  * @property {object} [signal] - Reserved for future use (canceling a request)
4508
+ * @property {Object} [fetchOptions={}] - Additional options to pass to fetch (Web) or simple-get (Node)
4504
4509
  */
4505
4510
  /**
4506
4511
  * @typedef {Object} GitHttpResponse
package/index.d.ts CHANGED
@@ -304,6 +304,10 @@ export type GitHttpRequest = {
304
304
  * - Reserved for future use (canceling a request)
305
305
  */
306
306
  signal?: object;
307
+ /**
308
+ * - Additional options to pass to fetch (Web) or simple-get (Node)
309
+ */
310
+ fetchOptions?: any;
307
311
  };
308
312
  export type GitHttpResponse = {
309
313
  /**
@@ -4500,6 +4504,7 @@ declare namespace NoCommitError {
4500
4504
  * @property {AsyncIterableIterator<Uint8Array>} [body] - An async iterator of Uint8Arrays that make up the body of POST requests
4501
4505
  * @property {ProgressCallback} [onProgress] - Reserved for future use (emitting `GitProgressEvent`s)
4502
4506
  * @property {object} [signal] - Reserved for future use (canceling a request)
4507
+ * @property {Object} [fetchOptions={}] - Additional options to pass to fetch (Web) or simple-get (Node)
4503
4508
  */
4504
4509
  /**
4505
4510
  * @typedef {Object} GitHttpResponse
package/index.js CHANGED
@@ -29,6 +29,7 @@ import diff3Merge from 'diff3';
29
29
  * @property {AsyncIterableIterator<Uint8Array>} [body] - An async iterator of Uint8Arrays that make up the body of POST requests
30
30
  * @property {ProgressCallback} [onProgress] - Reserved for future use (emitting `GitProgressEvent`s)
31
31
  * @property {object} [signal] - Reserved for future use (canceling a request)
32
+ * @property {Object} [fetchOptions={}] - Additional options to pass to fetch (Web) or simple-get (Node)
32
33
  */
33
34
 
34
35
  /**
@@ -5008,6 +5009,67 @@ async function _walk({
5008
5009
  return walk(root)
5009
5010
  }
5010
5011
 
5012
+ /**
5013
+ * Recursively creates the directory at `filepath`, creating any missing parent
5014
+ * directories along the way. This is a portable replacement for
5015
+ * `fs.mkdir(path, { recursive: true })`: recursive `mkdir` is NOT part of
5016
+ * isomorphic-git's required `fs` contract (see docs/fs.md — `mkdir` is only
5017
+ * `mkdir(path[, mode])`) and is unimplemented by some backends such as
5018
+ * lightning-fs, so we build it here on top of a single-level `mkdir(path)`
5019
+ * primitive only — mirroring how `rmRecursive` provides `rm({ recursive: true })`.
5020
+ *
5021
+ * It takes the raw single-level `mkdir` *function* (typically `fs._mkdir`)
5022
+ * rather than the FileSystem wrapper, to stay decoupled from that type.
5023
+ *
5024
+ * `EEXIST` is treated as success, so two callers concurrently creating the same
5025
+ * directory (e.g. several reflog writes into `.git/logs/refs/*` during a stash)
5026
+ * don't fail each other. On backends whose layers are only eventually
5027
+ * consistent — e.g. an async copy-on-write overlay — a just-created parent may
5028
+ * not yet be visible when its child is created, so `mkdir` can throw a
5029
+ * transient `ENOENT`; those are retried a bounded number of times rather than
5030
+ * surfaced as a spurious failure.
5031
+ *
5032
+ * @param {(filepath: string) => Promise<unknown>} mkdir - Creates a single directory (non-recursive).
5033
+ * @param {string} filepath - The directory to create.
5034
+ * @param {number} [retries=10] - Max transient-ENOENT retries after the parent exists.
5035
+ * @returns {Promise<void>}
5036
+ */
5037
+ async function mkdirp(mkdir, filepath, retries = 10) {
5038
+ try {
5039
+ await mkdir(filepath);
5040
+ } catch (err) {
5041
+ // Some fs implementations signal success by yielding a null error.
5042
+ if (err === null) return
5043
+ // The directory already exists — that's fine.
5044
+ if (err.code === 'EEXIST') return
5045
+ // Anything other than a missing parent is a real error.
5046
+ if (err.code !== 'ENOENT') throw err
5047
+ const parent = dirname(filepath);
5048
+ // Stop if we've walked past the filesystem root.
5049
+ if (parent === '.' || parent === '/' || parent === filepath) throw err
5050
+ // Create the missing parent(s) first, honoring the same retry budget.
5051
+ await mkdirp(mkdir, parent, retries);
5052
+ // Then (re)create this directory. On an eventually-consistent backend the
5053
+ // parent may not be visible immediately after its mkdir resolves, so a
5054
+ // repeated ENOENT here is transient — retry a bounded number of times,
5055
+ // yielding between attempts so the pending write can settle.
5056
+ for (let attempt = 0; ; attempt++) {
5057
+ try {
5058
+ await mkdir(filepath);
5059
+ return
5060
+ } catch (err2) {
5061
+ if (err2 === null || err2.code === 'EEXIST') return
5062
+ if (err2.code === 'ENOENT' && attempt < retries) {
5063
+ // Give the backend a turn of the event loop to become consistent.
5064
+ await new Promise(resolve => setTimeout(resolve, 0));
5065
+ continue
5066
+ }
5067
+ throw err2
5068
+ }
5069
+ }
5070
+ }
5071
+ }
5072
+
5011
5073
  /**
5012
5074
  * Removes the directory at the specified filepath recursively. Used internally to replicate the behavior of
5013
5075
  * fs.promises.rm({ recursive: true, force: true }) from Node.js 14 and above when not available. If the provided
@@ -5200,29 +5262,17 @@ class FileSystem {
5200
5262
  * Make a directory (or series of nested directories) without throwing an error if it already exists.
5201
5263
  *
5202
5264
  * @param {string} filepath - The path to the directory.
5203
- * @param {boolean} [_selfCall=false] - Internal flag to prevent infinite recursion.
5204
5265
  * @returns {Promise<void>}
5205
5266
  */
5206
- async mkdir(filepath, _selfCall = false) {
5207
- try {
5208
- await this._mkdir(filepath);
5209
- } catch (err) {
5210
- // If err is null then operation succeeded!
5211
- if (err === null) return
5212
- // If the directory already exists, that's OK!
5213
- if (err.code === 'EEXIST') return
5214
- // Avoid infinite loops of failure
5215
- if (_selfCall) throw err
5216
- // If we got a "no such file or directory error" backup and try again.
5217
- if (err.code === 'ENOENT') {
5218
- const parent = dirname(filepath);
5219
- // Check to see if we've gone too far
5220
- if (parent === '.' || parent === '/' || parent === filepath) throw err
5221
- // Infinite recursion, what could go wrong?
5222
- await this.mkdir(parent);
5223
- await this.mkdir(filepath, true);
5224
- }
5225
- }
5267
+ async mkdir(filepath) {
5268
+ // Recursively create the directory, using only single-level `_mkdir` so we
5269
+ // don't depend on `{ recursive: true }` (which isn't part of the required
5270
+ // `fs` contract — see docs/fs.md — and is unimplemented by some backends
5271
+ // e.g. lightning-fs). The helper tolerates EEXIST and the transient ENOENT
5272
+ // that eventually-consistent backends throw when a freshly created parent
5273
+ // isn't visible yet, which is what made concurrent reflog writes into
5274
+ // `.git/logs/refs/*` fail intermittently.
5275
+ await mkdirp(this._mkdir, filepath);
5226
5276
  }
5227
5277
 
5228
5278
  /**
@@ -9567,8 +9617,8 @@ function filterCapabilities(server, client) {
9567
9617
 
9568
9618
  const pkg = {
9569
9619
  name: 'isomorphic-git',
9570
- version: '1.40.7',
9571
- agent: 'git/isomorphic-git@1.40.7',
9620
+ version: '1.41.0',
9621
+ agent: 'git/isomorphic-git@1.41.0',
9572
9622
  };
9573
9623
 
9574
9624
  class FIFO {
@@ -304,6 +304,10 @@ export type GitHttpRequest = {
304
304
  * - Reserved for future use (canceling a request)
305
305
  */
306
306
  signal?: object;
307
+ /**
308
+ * - Additional options to pass to fetch (Web) or simple-get (Node)
309
+ */
310
+ fetchOptions?: any;
307
311
  };
308
312
  export type GitHttpResponse = {
309
313
  /**
@@ -4500,6 +4504,7 @@ declare namespace NoCommitError {
4500
4504
  * @property {AsyncIterableIterator<Uint8Array>} [body] - An async iterator of Uint8Arrays that make up the body of POST requests
4501
4505
  * @property {ProgressCallback} [onProgress] - Reserved for future use (emitting `GitProgressEvent`s)
4502
4506
  * @property {object} [signal] - Reserved for future use (canceling a request)
4507
+ * @property {Object} [fetchOptions={}] - Additional options to pass to fetch (Web) or simple-get (Node)
4503
4508
  */
4504
4509
  /**
4505
4510
  * @typedef {Object} GitHttpResponse