@kubohiroya/turbowarp-plus-editor-git 0.14.1 → 0.16.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.
@@ -11822,6 +11822,132 @@ async function _writeObject({ fs, gitdir, type, object, format = "content", oid
11822
11822
  });
11823
11823
  return oid;
11824
11824
  }
11825
+ function posixifyPathBuffer(buffer) {
11826
+ let idx;
11827
+ while (~(idx = buffer.indexOf(92))) buffer[idx] = 47;
11828
+ return buffer;
11829
+ }
11830
+ /**
11831
+ * Add a file to the git index (aka staging area)
11832
+ *
11833
+ * @param {object} args
11834
+ * @param {FsClient} args.fs - a file system implementation
11835
+ * @param {string} args.dir - The [working tree](dir-vs-gitdir.md) directory path
11836
+ * @param {string} [args.gitdir=join(dir, '.git')] - [required] The [git directory](dir-vs-gitdir.md) path
11837
+ * @param {string|string[]} args.filepath - The path to the file to add to the index
11838
+ * @param {object} [args.cache] - a [cache](cache.md) object
11839
+ * @param {boolean} [args.force=false] - add to index even if matches gitignore. Think `git add --force`
11840
+ * @param {boolean} [args.parallel=false] - process each input file in parallel. Parallel processing will result in more memory consumption but less process time
11841
+ *
11842
+ * @returns {Promise<void>} Resolves successfully once the git index has been updated
11843
+ *
11844
+ * @example
11845
+ * await fs.promises.writeFile('/tutorial/README.md', `# TEST`)
11846
+ * await git.add({ fs, dir: '/tutorial', filepath: 'README.md' })
11847
+ * console.log('done')
11848
+ *
11849
+ */
11850
+ async function add({ fs: _fs, dir, gitdir = join(dir, ".git"), filepath, cache = {}, force = false, parallel = true }) {
11851
+ try {
11852
+ assertParameter("fs", _fs);
11853
+ assertParameter("dir", dir);
11854
+ assertParameter("gitdir", gitdir);
11855
+ assertParameter("filepath", filepath);
11856
+ const fs = new FileSystem(_fs);
11857
+ const updatedGitdir = await discoverGitdir({
11858
+ fsp: fs,
11859
+ dotgit: gitdir
11860
+ });
11861
+ await GitIndexManager.acquire({
11862
+ fs,
11863
+ gitdir: updatedGitdir,
11864
+ cache
11865
+ }, async (index) => {
11866
+ const autocrlf = await (await GitConfigManager.get({
11867
+ fs,
11868
+ gitdir: updatedGitdir
11869
+ })).get("core.autocrlf");
11870
+ return addToIndex({
11871
+ dir,
11872
+ gitdir: updatedGitdir,
11873
+ fs,
11874
+ filepath,
11875
+ index,
11876
+ force,
11877
+ parallel,
11878
+ autocrlf
11879
+ });
11880
+ });
11881
+ } catch (err) {
11882
+ err.caller = "git.add";
11883
+ throw err;
11884
+ }
11885
+ }
11886
+ function isTracked(index, filepath) {
11887
+ if (index.has({ filepath })) return true;
11888
+ const prefix = `${filepath}/`;
11889
+ for (const entry of index.entriesMap.keys()) if (entry.startsWith(prefix)) return true;
11890
+ return false;
11891
+ }
11892
+ async function addToIndex({ dir, gitdir, fs, filepath, index, force, parallel, autocrlf }) {
11893
+ filepath = Array.isArray(filepath) ? filepath : [filepath];
11894
+ const promises = filepath.map(async (currentFilepath) => {
11895
+ if (!force && !isTracked(index, currentFilepath)) {
11896
+ if (await GitIgnoreManager.isIgnored({
11897
+ fs,
11898
+ dir,
11899
+ gitdir,
11900
+ filepath: currentFilepath
11901
+ })) return;
11902
+ }
11903
+ const stats = await fs.lstat(join(dir, currentFilepath));
11904
+ if (!stats) throw new NotFoundError(currentFilepath);
11905
+ if (stats.isDirectory()) {
11906
+ const children = await fs.readdir(join(dir, currentFilepath));
11907
+ if (parallel) {
11908
+ const promises = children.map((child) => addToIndex({
11909
+ dir,
11910
+ gitdir,
11911
+ fs,
11912
+ filepath: [join(currentFilepath, child)],
11913
+ index,
11914
+ force,
11915
+ parallel,
11916
+ autocrlf
11917
+ }));
11918
+ await Promise.all(promises);
11919
+ } else for (const child of children) await addToIndex({
11920
+ dir,
11921
+ gitdir,
11922
+ fs,
11923
+ filepath: [join(currentFilepath, child)],
11924
+ index,
11925
+ force,
11926
+ parallel,
11927
+ autocrlf
11928
+ });
11929
+ } else {
11930
+ const object = stats.isSymbolicLink() ? await fs.readlink(join(dir, currentFilepath)).then(posixifyPathBuffer) : await fs.read(join(dir, currentFilepath), { autocrlf });
11931
+ if (object === null) throw new NotFoundError(currentFilepath);
11932
+ const oid = await _writeObject({
11933
+ fs,
11934
+ gitdir,
11935
+ type: "blob",
11936
+ object
11937
+ });
11938
+ index.insert({
11939
+ filepath: currentFilepath,
11940
+ stats,
11941
+ oid
11942
+ });
11943
+ }
11944
+ });
11945
+ const settledPromises = await Promise.allSettled(promises);
11946
+ const rejectedPromises = settledPromises.filter((settle) => settle.status === "rejected").map((settle) => settle.reason);
11947
+ if (rejectedPromises.length > 1) throw new MultipleGitError(rejectedPromises);
11948
+ if (rejectedPromises.length === 1) throw rejectedPromises[0];
11949
+ return settledPromises.filter((settle) => settle.status === "fulfilled" && settle.value).map((settle) => settle.value);
11950
+ }
11825
11951
  async function hasObjectLoose({ fs, gitdir, oid }) {
11826
11952
  const source = `objects/${oid.slice(0, 2)}/${oid.slice(2)}`;
11827
11953
  return fs.exists(`${gitdir}/${source}`);
@@ -12248,6 +12374,141 @@ async function _resolveFilepath({ fs, cache, gitdir, tree, pathArray, oid, filep
12248
12374
  throw new NotFoundError(`file or directory found at "${oid}:${filepath}"`);
12249
12375
  }
12250
12376
  /**
12377
+ *
12378
+ * @typedef {Object} ReadTreeResult - The object returned has the following schema:
12379
+ * @property {string} oid - SHA-1 object id of this tree
12380
+ * @property {TreeObject} tree - the parsed tree object
12381
+ */
12382
+ /**
12383
+ * @param {object} args
12384
+ * @param {import('../models/FileSystem.js').FileSystem} args.fs
12385
+ * @param {any} args.cache
12386
+ * @param {string} args.gitdir
12387
+ * @param {string} args.oid
12388
+ * @param {string} [args.filepath]
12389
+ *
12390
+ * @returns {Promise<ReadTreeResult>}
12391
+ */
12392
+ async function _readTree({ fs, cache, gitdir, oid, filepath = void 0 }) {
12393
+ if (filepath !== void 0) oid = await resolveFilepath({
12394
+ fs,
12395
+ cache,
12396
+ gitdir,
12397
+ oid,
12398
+ filepath
12399
+ });
12400
+ const { tree, oid: treeOid } = await resolveTree({
12401
+ fs,
12402
+ cache,
12403
+ gitdir,
12404
+ oid
12405
+ });
12406
+ return {
12407
+ oid: treeOid,
12408
+ tree: tree.entries()
12409
+ };
12410
+ }
12411
+ /**
12412
+ * Create a branch
12413
+ *
12414
+ * @param {object} args
12415
+ * @param {import('../models/FileSystem.js').FileSystem} args.fs
12416
+ * @param {string} args.gitdir
12417
+ * @param {string} args.ref
12418
+ * @param {string} [args.object = 'HEAD']
12419
+ * @param {boolean} [args.checkout = false]
12420
+ * @param {boolean} [args.force = false]
12421
+ *
12422
+ * @returns {Promise<void>} Resolves successfully when filesystem operations are complete
12423
+ *
12424
+ * @example
12425
+ * await git.branch({ dir: '$input((/))', ref: '$input((develop))' })
12426
+ * console.log('done')
12427
+ *
12428
+ */
12429
+ async function _branch({ fs, gitdir, ref, object, checkout = false, force = false }) {
12430
+ if (!isValidRef(ref, true)) throw new InvalidRefNameError(ref, import_lib.default.clean(ref));
12431
+ const fullref = `refs/heads/${ref}`;
12432
+ if (!force) {
12433
+ if (await GitRefManager.exists({
12434
+ fs,
12435
+ gitdir,
12436
+ ref: fullref
12437
+ })) throw new AlreadyExistsError("branch", ref, false);
12438
+ }
12439
+ let oid;
12440
+ try {
12441
+ oid = await GitRefManager.resolve({
12442
+ fs,
12443
+ gitdir,
12444
+ ref: object || "HEAD"
12445
+ });
12446
+ } catch (e) {
12447
+ if (!(e instanceof NotFoundError)) throw e;
12448
+ }
12449
+ if (oid) {
12450
+ oid = (await resolveCommit({
12451
+ fs,
12452
+ cache: {},
12453
+ gitdir,
12454
+ oid
12455
+ })).oid;
12456
+ await GitRefManager.writeRef({
12457
+ fs,
12458
+ gitdir,
12459
+ ref: fullref,
12460
+ value: oid
12461
+ });
12462
+ }
12463
+ if (checkout) await GitRefManager.writeSymbolicRef({
12464
+ fs,
12465
+ gitdir,
12466
+ ref: "HEAD",
12467
+ value: fullref
12468
+ });
12469
+ }
12470
+ /**
12471
+ * Create a branch
12472
+ *
12473
+ * @param {object} args
12474
+ * @param {FsClient} args.fs - a file system implementation
12475
+ * @param {string} [args.dir] - The [working tree](dir-vs-gitdir.md) directory path
12476
+ * @param {string} [args.gitdir=join(dir,'.git')] - [required] The [git directory](dir-vs-gitdir.md) path
12477
+ * @param {string} args.ref - What to name the branch
12478
+ * @param {string} [args.object = 'HEAD'] - What oid to use as the start point. Accepts a symbolic ref.
12479
+ * @param {boolean} [args.checkout = false] - Update `HEAD` to point at the newly created branch
12480
+ * @param {boolean} [args.force = false] - Instead of throwing an error if a branched named `ref` already exists, overwrite the existing branch.
12481
+ *
12482
+ * @returns {Promise<void>} Resolves successfully when filesystem operations are complete
12483
+ *
12484
+ * @example
12485
+ * await git.branch({ fs, dir: '/tutorial', ref: 'develop' })
12486
+ * console.log('done')
12487
+ *
12488
+ */
12489
+ async function branch({ fs, dir, gitdir = join(dir, ".git"), ref, object, checkout = false, force = false }) {
12490
+ try {
12491
+ assertParameter("fs", fs);
12492
+ assertParameter("gitdir", gitdir);
12493
+ assertParameter("ref", ref);
12494
+ const fsp = new FileSystem(fs);
12495
+ return await _branch({
12496
+ fs: fsp,
12497
+ gitdir: await discoverGitdir({
12498
+ fsp,
12499
+ dotgit: gitdir
12500
+ }),
12501
+ ref,
12502
+ object,
12503
+ checkout,
12504
+ force
12505
+ });
12506
+ } catch (err) {
12507
+ err.caller = "git.branch";
12508
+ throw err;
12509
+ }
12510
+ }
12511
+ /**
12251
12512
  * Refuse to materialize a working-tree entry whose parent path traverses a
12252
12513
  * symbolic link. A leading component that is a symlink could otherwise redirect
12253
12514
  * a write or mkdir outside the working tree. git applies the same check: it does
@@ -12741,6 +13002,97 @@ async function batchAllSettled(operationName, tasks, onProgress, batchSize) {
12741
13002
  if (rejections.length > 0) throw new MultipleGitError(rejections);
12742
13003
  return results;
12743
13004
  }
13005
+ /**
13006
+ * Checkout a branch
13007
+ *
13008
+ * If the branch already exists it will check out that branch. Otherwise, it will create a new remote tracking branch set to track the remote branch of that name.
13009
+ *
13010
+ * @param {object} args
13011
+ * @param {FsClient} args.fs - a file system implementation
13012
+ * @param {ProgressCallback} [args.onProgress] - optional progress event callback
13013
+ * @param {PostCheckoutCallback} [args.onPostCheckout] - optional post-checkout hook callback
13014
+ * @param {string} args.dir - The [working tree](dir-vs-gitdir.md) directory path
13015
+ * @param {string} [args.gitdir=join(dir,'.git')] - [required] The [git directory](dir-vs-gitdir.md) path
13016
+ * @param {string} [args.ref = 'HEAD'] - Source to checkout files from
13017
+ * @param {string[]} [args.filepaths] - Limit the checkout to the given files and directories. If `ref` is not provided, restore them from the index.
13018
+ * @param {string} [args.remote = 'origin'] - Which remote repository to use
13019
+ * @param {boolean} [args.noCheckout = false] - If true, will update HEAD but won't update the working directory
13020
+ * @param {boolean} [args.noUpdateHead] - If true, will update the working directory but won't update HEAD. Defaults to `false` when `ref` is provided, and `true` if `ref` is not provided.
13021
+ * @param {boolean} [args.dryRun = false] - If true, simulates a checkout so you can test whether it would succeed.
13022
+ * @param {boolean} [args.force = false] - If true, conflicts will be ignored and files will be overwritten regardless of local changes.
13023
+ * @param {boolean} [args.track = true] - If false, will not set the remote branch tracking information. Defaults to true.
13024
+ * @param {object} [args.cache] - a [cache](cache.md) object
13025
+ * @param {boolean} [args.nonBlocking = false] - If true, will use non-blocking file system operations to allow for better performance in certain environments (For example, in Browsers)
13026
+ * @param {number} [args.batchSize = 100] - If args.nonBlocking is true, batchSize is the number of files to process at a time avoid blocking the executing thread. The default value of 100 is a good starting point.
13027
+ *
13028
+ * @returns {Promise<void>} Resolves successfully when filesystem operations are complete
13029
+ *
13030
+ * @example
13031
+ * // switch to the main branch
13032
+ * await git.checkout({
13033
+ * fs,
13034
+ * dir: '/tutorial',
13035
+ * ref: 'main'
13036
+ * })
13037
+ * console.log('done')
13038
+ *
13039
+ * @example
13040
+ * // restore the 'docs' and 'src/docs' folders from the index, overwriting any unstaged changes
13041
+ * await git.checkout({
13042
+ * fs,
13043
+ * dir: '/tutorial',
13044
+ * force: true,
13045
+ * filepaths: ['docs', 'src/docs']
13046
+ * })
13047
+ * console.log('done')
13048
+ *
13049
+ * @example
13050
+ * // restore the 'docs' and 'src/docs' folders to the way they are in the 'develop' branch, overwriting any changes
13051
+ * await git.checkout({
13052
+ * fs,
13053
+ * dir: '/tutorial',
13054
+ * ref: 'develop',
13055
+ * noUpdateHead: true,
13056
+ * force: true,
13057
+ * filepaths: ['docs', 'src/docs']
13058
+ * })
13059
+ * console.log('done')
13060
+ */
13061
+ async function checkout({ fs, onProgress, onPostCheckout, dir, gitdir = join(dir, ".git"), remote = "origin", ref: _ref, filepaths, noCheckout = false, noUpdateHead = _ref === void 0, dryRun = false, force = false, track = true, cache = {}, nonBlocking = false, batchSize = 100 }) {
13062
+ try {
13063
+ assertParameter("fs", fs);
13064
+ assertParameter("dir", dir);
13065
+ assertParameter("gitdir", gitdir);
13066
+ const ref = _ref || "HEAD";
13067
+ const restoreFromIndex = _ref === void 0 && filepaths != null && filepaths.length > 0;
13068
+ const fsp = new FileSystem(fs);
13069
+ return await _checkout({
13070
+ fs: fsp,
13071
+ cache,
13072
+ onProgress,
13073
+ onPostCheckout,
13074
+ dir,
13075
+ gitdir: await discoverGitdir({
13076
+ fsp,
13077
+ dotgit: gitdir
13078
+ }),
13079
+ remote,
13080
+ ref,
13081
+ filepaths,
13082
+ noCheckout,
13083
+ noUpdateHead,
13084
+ dryRun,
13085
+ force,
13086
+ track,
13087
+ restoreFromIndex,
13088
+ nonBlocking,
13089
+ batchSize
13090
+ });
13091
+ } catch (err) {
13092
+ err.caller = "git.checkout";
13093
+ throw err;
13094
+ }
13095
+ }
12744
13096
  var LINEBREAKS = /^.*(\r?\n|$)/gm;
12745
13097
  function mergeFile({ branches, contents }) {
12746
13098
  const ourName = branches[1];
@@ -14037,6 +14389,81 @@ async function _fetch({ fs, cache, http, onProgress, onMessage, onAuth, onAuthSu
14037
14389
  return res;
14038
14390
  }
14039
14391
  /**
14392
+ * Create a new commit
14393
+ *
14394
+ * @param {Object} args
14395
+ * @param {FsClient} args.fs - a file system implementation
14396
+ * @param {SignCallback} [args.onSign] - a PGP signing implementation
14397
+ * @param {string} [args.dir] - The [working tree](dir-vs-gitdir.md) directory path
14398
+ * @param {string} [args.gitdir=join(dir,'.git')] - [required] The [git directory](dir-vs-gitdir.md) path
14399
+ * @param {string} [args.message] - The commit message to use. Required, unless `amend === true`
14400
+ * @param {Object} [args.author] - The details about the author.
14401
+ * @param {string} [args.author.name] - Default is `user.name` config.
14402
+ * @param {string} [args.author.email] - Default is `user.email` config.
14403
+ * @param {number} [args.author.timestamp=Math.floor(Date.now()/1000)] - Set the author timestamp field. This is the integer number of seconds since the Unix epoch (1970-01-01 00:00:00).
14404
+ * @param {number} [args.author.timezoneOffset] - Set the author timezone offset field. This is the difference, in minutes, from the current timezone to UTC. Default is `(new Date()).getTimezoneOffset()`.
14405
+ * @param {Object} [args.committer = author] - The details about the commit committer, in the same format as the author parameter. If not specified, the author details are used.
14406
+ * @param {string} [args.committer.name] - Default is `user.name` config.
14407
+ * @param {string} [args.committer.email] - Default is `user.email` config.
14408
+ * @param {number} [args.committer.timestamp=Math.floor(Date.now()/1000)] - Set the committer timestamp field. This is the integer number of seconds since the Unix epoch (1970-01-01 00:00:00).
14409
+ * @param {number} [args.committer.timezoneOffset] - Set the committer timezone offset field. This is the difference, in minutes, from the current timezone to UTC. Default is `(new Date()).getTimezoneOffset()`.
14410
+ * @param {string} [args.signingKey] - Sign the tag object using this private PGP key.
14411
+ * @param {boolean} [args.amend = false] - If true, replaces the last commit pointed to by `ref` with a new commit.
14412
+ * @param {boolean} [args.dryRun = false] - If true, simulates making a commit so you can test whether it would succeed. Implies `noUpdateBranch`.
14413
+ * @param {boolean} [args.noUpdateBranch = false] - If true, does not update the branch pointer after creating the commit.
14414
+ * @param {boolean} [args.disallowEmpty = false] - If true, throws an error instead of creating a commit with no staged changes.
14415
+ * @param {string} [args.ref] - The fully expanded name of the branch to commit to. Default is the current branch pointed to by HEAD. (TODO: fix it so it can expand branch names without throwing if the branch doesn't exist yet.)
14416
+ * @param {string[]} [args.parent] - The SHA-1 object ids of the commits to use as parents. If not specified, the commit pointed to by `ref` is used.
14417
+ * @param {string} [args.tree] - The SHA-1 object id of the tree to use. If not specified, a new tree object is created from the current git index.
14418
+ * @param {object} [args.cache] - a [cache](cache.md) object
14419
+ *
14420
+ * @returns {Promise<string>} Resolves successfully with the SHA-1 object id of the newly created commit.
14421
+ *
14422
+ * @example
14423
+ * let sha = await git.commit({
14424
+ * fs,
14425
+ * dir: '/tutorial',
14426
+ * author: {
14427
+ * name: 'Mr. Test',
14428
+ * email: 'mrtest@example.com',
14429
+ * },
14430
+ * message: 'Added the a.txt file'
14431
+ * })
14432
+ * console.log(sha)
14433
+ *
14434
+ */
14435
+ async function commit({ fs: _fs, onSign, dir, gitdir = join(dir, ".git"), message, author, committer, signingKey, amend = false, dryRun = false, noUpdateBranch = false, disallowEmpty = false, ref, parent, tree, cache = {} }) {
14436
+ try {
14437
+ assertParameter("fs", _fs);
14438
+ if (!amend) assertParameter("message", message);
14439
+ if (signingKey) assertParameter("onSign", onSign);
14440
+ const fs = new FileSystem(_fs);
14441
+ return await _commit({
14442
+ fs,
14443
+ cache,
14444
+ onSign,
14445
+ gitdir: await discoverGitdir({
14446
+ fsp: fs,
14447
+ dotgit: gitdir
14448
+ }),
14449
+ message,
14450
+ author,
14451
+ committer,
14452
+ signingKey,
14453
+ amend,
14454
+ dryRun,
14455
+ noUpdateBranch,
14456
+ disallowEmpty,
14457
+ ref,
14458
+ parent,
14459
+ tree
14460
+ });
14461
+ } catch (err) {
14462
+ err.caller = "git.commit";
14463
+ throw err;
14464
+ }
14465
+ }
14466
+ /**
14040
14467
  * Get the name of the branch currently pointed to by .git/HEAD
14041
14468
  *
14042
14469
  * @param {Object} args
@@ -15795,6 +16222,192 @@ async function readCommit({ fs, dir, gitdir = join(dir, ".git"), oid, cache = {}
15795
16222
  }
15796
16223
  }
15797
16224
  /**
16225
+ *
16226
+ * @typedef {Object} ReadTreeResult - The object returned has the following schema:
16227
+ * @property {string} oid - SHA-1 object id of this tree
16228
+ * @property {TreeObject} tree - the parsed tree object
16229
+ */
16230
+ /**
16231
+ * Read a tree object directly
16232
+ *
16233
+ * @param {object} args
16234
+ * @param {FsClient} args.fs - a file system client
16235
+ * @param {string} [args.dir] - The [working tree](dir-vs-gitdir.md) directory path
16236
+ * @param {string} [args.gitdir=join(dir,'.git')] - [required] The [git directory](dir-vs-gitdir.md) path
16237
+ * @param {string} args.oid - The SHA-1 object id to get. Annotated tags and commits are peeled.
16238
+ * @param {string} [args.filepath] - Don't return the object with `oid` itself, but resolve `oid` to a tree and then return the tree object at that filepath.
16239
+ * @param {object} [args.cache] - a [cache](cache.md) object
16240
+ *
16241
+ * @returns {Promise<ReadTreeResult>} Resolves successfully with a git tree object
16242
+ * @see ReadTreeResult
16243
+ * @see TreeObject
16244
+ * @see TreeEntry
16245
+ *
16246
+ */
16247
+ async function readTree({ fs, dir, gitdir = join(dir, ".git"), oid, filepath = void 0, cache = {} }) {
16248
+ try {
16249
+ assertParameter("fs", fs);
16250
+ assertParameter("gitdir", gitdir);
16251
+ assertParameter("oid", oid);
16252
+ const fsp = new FileSystem(fs);
16253
+ return await _readTree({
16254
+ fs: fsp,
16255
+ cache,
16256
+ gitdir: await discoverGitdir({
16257
+ fsp,
16258
+ dotgit: gitdir
16259
+ }),
16260
+ oid,
16261
+ filepath
16262
+ });
16263
+ } catch (err) {
16264
+ err.caller = "git.readTree";
16265
+ throw err;
16266
+ }
16267
+ }
16268
+ /**
16269
+ * Remove a file from the git index (aka staging area)
16270
+ *
16271
+ * Note that this does NOT delete the file in the working directory.
16272
+ *
16273
+ * @param {object} args
16274
+ * @param {FsClient} args.fs - a file system client
16275
+ * @param {string} [args.dir] - The [working tree](dir-vs-gitdir.md) directory path
16276
+ * @param {string} [args.gitdir=join(dir, '.git')] - [required] The [git directory](dir-vs-gitdir.md) path
16277
+ * @param {string|string[]} args.filepath - The path to the file to remove from the index, or an array of paths
16278
+ * @param {object} [args.cache] - a [cache](cache.md) object
16279
+ *
16280
+ * @returns {Promise<void>} Resolves successfully once the git index has been updated
16281
+ *
16282
+ * @example
16283
+ * await git.remove({ fs, dir: '/tutorial', filepath: 'README.md' })
16284
+ * console.log('done')
16285
+ *
16286
+ * @example
16287
+ * // remove several files from the index with a single write of the index
16288
+ * await git.remove({ fs, dir: '/tutorial', filepath: ['README.md', 'docs/old.md'] })
16289
+ * console.log('done')
16290
+ *
16291
+ */
16292
+ async function remove({ fs: _fs, dir, gitdir = join(dir, ".git"), filepath, cache = {} }) {
16293
+ try {
16294
+ assertParameter("fs", _fs);
16295
+ assertParameter("gitdir", gitdir);
16296
+ assertParameter("filepath", filepath);
16297
+ const fsp = new FileSystem(_fs);
16298
+ const updatedGitdir = await discoverGitdir({
16299
+ fsp,
16300
+ dotgit: gitdir
16301
+ });
16302
+ await GitIndexManager.acquire({
16303
+ fs: fsp,
16304
+ gitdir: updatedGitdir,
16305
+ cache
16306
+ }, async function(index) {
16307
+ const filepaths = Array.isArray(filepath) ? filepath : [filepath];
16308
+ for (const currentFilepath of filepaths) index.delete({ filepath: currentFilepath });
16309
+ });
16310
+ } catch (err) {
16311
+ err.caller = "git.remove";
16312
+ throw err;
16313
+ }
16314
+ }
16315
+ async function hashObject$1({ gitdir, type, object }) {
16316
+ return shasum(GitObject.wrap({
16317
+ type,
16318
+ object
16319
+ }));
16320
+ }
16321
+ /**
16322
+ * Reset a file in the git index (aka staging area)
16323
+ *
16324
+ * Note that this does NOT modify the file in the working directory.
16325
+ *
16326
+ * @param {object} args
16327
+ * @param {FsClient} args.fs - a file system client
16328
+ * @param {string} [args.dir] - The [working tree](dir-vs-gitdir.md) directory path
16329
+ * @param {string} [args.gitdir=join(dir, '.git')] - [required] The [git directory](dir-vs-gitdir.md) path
16330
+ * @param {string} args.filepath - The path to the file to reset in the index
16331
+ * @param {string} [args.ref = 'HEAD'] - A ref to the commit to use
16332
+ * @param {object} [args.cache] - a [cache](cache.md) object
16333
+ *
16334
+ * @returns {Promise<void>} Resolves successfully once the git index has been updated
16335
+ *
16336
+ * @example
16337
+ * await git.resetIndex({ fs, dir: '/tutorial', filepath: 'README.md' })
16338
+ * console.log('done')
16339
+ *
16340
+ */
16341
+ async function resetIndex({ fs: _fs, dir, gitdir = join(dir, ".git"), filepath, ref, cache = {} }) {
16342
+ try {
16343
+ assertParameter("fs", _fs);
16344
+ assertParameter("gitdir", gitdir);
16345
+ assertParameter("filepath", filepath);
16346
+ const fs = new FileSystem(_fs);
16347
+ const updatedGitdir = await discoverGitdir({
16348
+ fsp: fs,
16349
+ dotgit: gitdir
16350
+ });
16351
+ let oid;
16352
+ let workdirOid;
16353
+ try {
16354
+ oid = await GitRefManager.resolve({
16355
+ fs,
16356
+ gitdir: updatedGitdir,
16357
+ ref: ref || "HEAD"
16358
+ });
16359
+ } catch (e) {
16360
+ if (ref || !(e instanceof NotFoundError)) throw e;
16361
+ }
16362
+ if (oid) try {
16363
+ oid = await resolveFilepath({
16364
+ fs,
16365
+ cache,
16366
+ gitdir: updatedGitdir,
16367
+ oid,
16368
+ filepath
16369
+ });
16370
+ } catch (e) {
16371
+ if (!(e instanceof NotFoundError) && !(e instanceof InvalidFilepathError) && !(e instanceof ObjectTypeError && e.data.filepath)) throw e;
16372
+ oid = null;
16373
+ }
16374
+ let stats = {
16375
+ ctime: /* @__PURE__ */ new Date(0),
16376
+ mtime: /* @__PURE__ */ new Date(0),
16377
+ dev: 0,
16378
+ ino: 0,
16379
+ mode: 0,
16380
+ uid: 0,
16381
+ gid: 0,
16382
+ size: 0
16383
+ };
16384
+ const object = dir && await fs.read(join(dir, filepath));
16385
+ if (object) {
16386
+ workdirOid = await hashObject$1({
16387
+ gitdir: updatedGitdir,
16388
+ type: "blob",
16389
+ object
16390
+ });
16391
+ if (oid === workdirOid) stats = await fs.lstat(join(dir, filepath));
16392
+ }
16393
+ await GitIndexManager.acquire({
16394
+ fs,
16395
+ gitdir: updatedGitdir,
16396
+ cache
16397
+ }, async function(index) {
16398
+ index.delete({ filepath });
16399
+ if (oid) index.insert({
16400
+ filepath,
16401
+ stats,
16402
+ oid
16403
+ });
16404
+ });
16405
+ } catch (err) {
16406
+ err.caller = "git.reset";
16407
+ throw err;
16408
+ }
16409
+ }
16410
+ /**
15798
16411
  * Get the value of a symbolic ref or resolve a ref to its SHA-1 object id
15799
16412
  *
15800
16413
  * @param {object} args
@@ -16494,7 +17107,7 @@ async function readOptional(fs, path) {
16494
17107
  }
16495
17108
  var sameBytes = (left, right) => left === right || Boolean(left && right && left.length === right.length && left.every((byte, i) => byte === right[i]));
16496
17109
  // src/mutation-fs.ts
16497
- var missing = (error) => {
17110
+ var missing$1 = (error) => {
16498
17111
  var _errorCode;
16499
17112
  return ["ENOENT", "ENOTDIR"].includes((_errorCode = errorCode(error)) !== null && _errorCode !== void 0 ? _errorCode : "");
16500
17113
  };
@@ -16538,7 +17151,7 @@ function createMutationFs(root, worktree) {
16538
17151
  time: stat.mtimeMs
16539
17152
  };
16540
17153
  } catch (error) {
16541
- if (missing(error)) return null;
17154
+ if (missing$1(error)) return null;
16542
17155
  throw error;
16543
17156
  }
16544
17157
  }
@@ -16549,7 +17162,7 @@ function createMutationFs(root, worktree) {
16549
17162
  try {
16550
17163
  return (await base.promises.stat(path)).isDirectory() ? "directory" : "file";
16551
17164
  } catch (error) {
16552
- if (!missing(error)) throw error;
17165
+ if (!missing$1(error)) throw error;
16553
17166
  }
16554
17167
  }
16555
17168
  async function stage(path, after) {
@@ -16570,7 +17183,7 @@ function createMutationFs(root, worktree) {
16570
17183
  try {
16571
17184
  for (const entry of await base.promises.readdir(path)) names.add(entry);
16572
17185
  } catch (error) {
16573
- if (!missing(error)) throw error;
17186
+ if (!missing$1(error)) throw error;
16574
17187
  }
16575
17188
  for (const change of changes.values()) {
16576
17189
  if (parent(change.path) !== path) continue;
@@ -16824,8 +17437,150 @@ async function runRemoteOperation(root, operation, getSession, guard, signal) {
16824
17437
  };
16825
17438
  return ((_globalThis$navigator = globalThis.navigator) === null || _globalThis$navigator === void 0 ? void 0 : _globalThis$navigator.locks) ? navigator.locks.request("tw-plus-git-mutation", execute) : execute();
16826
17439
  }
17440
+ // src/local-operations.ts
17441
+ init_objectSpread2();
17442
+ var missing = (error) => {
17443
+ var _errorCode;
17444
+ return [
17445
+ "ENOENT",
17446
+ "ENOTDIR",
17447
+ "NotFoundError"
17448
+ ].includes((_errorCode = errorCode(error)) !== null && _errorCode !== void 0 ? _errorCode : "");
17449
+ };
17450
+ /**
17451
+ * Stages, unstages or commits in the granted repository. Like pull, Git's writes are collected first and applied
17452
+ * after the files they replace are checked again; a failure part way puts back what was applied. Only `.git/index`,
17453
+ * objects and the current branch ref are written. The work tree and `.git/config` are never written.
17454
+ */
17455
+ async function runLocalOperation(root, operation, guard) {
17456
+ var _globalThis$navigator;
17457
+ const execute = async () => {
17458
+ guard();
17459
+ const switching = operation.kind === "switchBranch" || operation.kind === "createBranch" && operation.checkout;
17460
+ const transaction = createMutationFs(root, switching);
17461
+ const options = {
17462
+ fs: transaction.fs,
17463
+ dir: "/",
17464
+ gitdir: "/.git",
17465
+ cache: {}
17466
+ };
17467
+ const read = createReadOnlyFs(root).promises;
17468
+ const exists = async (path) => {
17469
+ try {
17470
+ await read.stat(path);
17471
+ return true;
17472
+ } catch (error) {
17473
+ if (missing(error)) return false;
17474
+ throw error;
17475
+ }
17476
+ };
17477
+ for (const path of [
17478
+ "/.git/index.lock",
17479
+ "/.git/MERGE_HEAD",
17480
+ "/.git/CHERRY_PICK_HEAD",
17481
+ "/.git/REVERT_HEAD",
17482
+ "/.git/rebase-merge",
17483
+ "/.git/rebase-apply"
17484
+ ]) if (await exists(path)) throw new GitPanelError("locked");
17485
+ if (operation.kind === "createBranch" || operation.kind === "switchBranch") {
17486
+ const name = operation.name.trim();
17487
+ const local = `refs/heads/${name}`;
17488
+ if (switching) {
17489
+ if ((await statusMatrix(_objectSpread2(_objectSpread2({}, options), {}, { refresh: false }))).some(([, head, worktree, stage]) => head !== worktree || head !== stage)) throw new GitPanelError("switchUnsafe");
17490
+ }
17491
+ if (operation.kind === "createBranch") {
17492
+ let object;
17493
+ if (operation.at !== void 0) {
17494
+ if (operation.fromRemote || !/^[0-9a-f]{40}$/.test(operation.at)) throw new GitPanelError("invalid");
17495
+ object = await readCommit(_objectSpread2(_objectSpread2({}, options), {}, { oid: operation.at })).then(() => operation.at, () => {
17496
+ throw new GitPanelError("invalid");
17497
+ });
17498
+ } else if (operation.fromRemote) try {
17499
+ object = await resolveRef(_objectSpread2(_objectSpread2({}, options), {}, { ref: `refs/remotes/origin/${name}` }));
17500
+ } catch (_unused) {
17501
+ throw new GitPanelError("invalid");
17502
+ }
17503
+ else object = await resolveRef(_objectSpread2(_objectSpread2({}, options), {}, { ref: "HEAD" })).catch(() => {
17504
+ throw new GitPanelError("unsupported");
17505
+ });
17506
+ try {
17507
+ await branch(_objectSpread2(_objectSpread2({}, options), {}, {
17508
+ ref: name,
17509
+ object,
17510
+ checkout: false
17511
+ }));
17512
+ } catch (error) {
17513
+ const code = error === null || error === void 0 ? void 0 : error.code;
17514
+ if (code === "AlreadyExistsError") throw new GitPanelError("branchExists");
17515
+ if (code === "InvalidRefNameError") throw new GitPanelError("branchName");
17516
+ throw error;
17517
+ }
17518
+ } else if (!(await listBranches(options)).includes(name)) throw new GitPanelError("invalid");
17519
+ if (switching) {
17520
+ const commit = await resolveRef(_objectSpread2(_objectSpread2({}, options), {}, { ref: local }));
17521
+ await walk(_objectSpread2(_objectSpread2({}, options), {}, {
17522
+ trees: [TREE({ ref: commit })],
17523
+ map: async (path, [entry]) => {
17524
+ if (!entry || path === ".") return true;
17525
+ const type = await entry.type();
17526
+ if (type === "tree") return true;
17527
+ if (type !== "blob" || await entry.mode() !== 33188) throw new GitPanelError("unsupported");
17528
+ return true;
17529
+ }
17530
+ }));
17531
+ await checkout(_objectSpread2(_objectSpread2({}, options), {}, { ref: name }));
17532
+ if (await currentBranch(options) !== name) throw new GitPanelError("changed");
17533
+ }
17534
+ } else if (operation.kind === "stage") {
17535
+ const modes = /* @__PURE__ */ new Map();
17536
+ await walk(_objectSpread2(_objectSpread2({}, options), {}, {
17537
+ trees: [STAGE()],
17538
+ map: async (path, [entry]) => {
17539
+ if (entry && path !== "." && await entry.type() === "blob") modes.set(path, await entry.mode());
17540
+ return true;
17541
+ }
17542
+ }));
17543
+ for (const path of operation.paths) {
17544
+ pathParts(path);
17545
+ const mode = modes.get(path);
17546
+ if (mode !== void 0 && mode !== 33188) throw new GitPanelError("unsupported");
17547
+ if (await exists("/" + path)) await add(_objectSpread2(_objectSpread2({}, options), {}, { filepath: path }));
17548
+ else await remove(_objectSpread2(_objectSpread2({}, options), {}, { filepath: path }));
17549
+ }
17550
+ } else if (operation.kind === "unstage") for (const path of operation.paths) {
17551
+ pathParts(path);
17552
+ await resetIndex(_objectSpread2(_objectSpread2({}, options), {}, { filepath: path }));
17553
+ }
17554
+ else {
17555
+ var _await$configured, _operation$author, _await$configured2, _operation$author2;
17556
+ const message = operation.message.trim();
17557
+ if (!message) throw new GitPanelError("commitMessage");
17558
+ if (!await currentBranch(options)) throw new GitPanelError("unsupported");
17559
+ const configured = async (path) => {
17560
+ const value = await getConfig(_objectSpread2(_objectSpread2({}, options), {}, { path }));
17561
+ return typeof value === "string" && value.trim() ? value : void 0;
17562
+ };
17563
+ const name = (_await$configured = await configured("user.name")) !== null && _await$configured !== void 0 ? _await$configured : (_operation$author = operation.author) === null || _operation$author === void 0 || (_operation$author = _operation$author.name) === null || _operation$author === void 0 ? void 0 : _operation$author.trim();
17564
+ const email = (_await$configured2 = await configured("user.email")) !== null && _await$configured2 !== void 0 ? _await$configured2 : (_operation$author2 = operation.author) === null || _operation$author2 === void 0 || (_operation$author2 = _operation$author2.email) === null || _operation$author2 === void 0 ? void 0 : _operation$author2.trim();
17565
+ if (!name || !email) throw new GitPanelError("author");
17566
+ if (!(await statusMatrix(_objectSpread2(_objectSpread2({}, options), {}, { refresh: false }))).some(([, head, , stage]) => head !== stage)) throw new GitPanelError("nothingStaged");
17567
+ await commit(_objectSpread2(_objectSpread2({}, options), {}, {
17568
+ message: message + "\n",
17569
+ author: {
17570
+ name,
17571
+ email
17572
+ }
17573
+ }));
17574
+ }
17575
+ guard();
17576
+ await transaction.commit(guard);
17577
+ };
17578
+ return ((_globalThis$navigator = globalThis.navigator) === null || _globalThis$navigator === void 0 ? void 0 : _globalThis$navigator.locks) ? navigator.locks.request("tw-plus-git-mutation", execute) : execute();
17579
+ }
16827
17580
  // src/repository.ts
16828
17581
  init_objectSpread2();
17582
+ /** Commits read per history page unless asked otherwise. */
17583
+ var historyPageSize = 50;
16829
17584
  var projectSourceLimit = 16777216;
16830
17585
  var emptyTree = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
16831
17586
  var textLimit = 1048576;
@@ -17089,6 +17844,7 @@ async function openRepository(root) {
17089
17844
  }
17090
17845
  const branch = await currentBranch(options);
17091
17846
  const branches = await listBranches(options);
17847
+ const remoteBranches = (await listBranches(_objectSpread2(_objectSpread2({}, options), {}, { remote: "origin" }))).filter((name) => name !== "HEAD" && !branches.includes(name)).sort();
17092
17848
  const commits = head ? (await log(_objectSpread2(_objectSpread2({}, options), {}, {
17093
17849
  cache,
17094
17850
  ref: head,
@@ -17144,6 +17900,7 @@ async function openRepository(root) {
17144
17900
  branch: branch || void 0,
17145
17901
  head,
17146
17902
  branches,
17903
+ remoteBranches,
17147
17904
  commits,
17148
17905
  changes,
17149
17906
  scope,
@@ -17152,6 +17909,147 @@ async function openRepository(root) {
17152
17909
  upstream
17153
17910
  };
17154
17911
  };
17912
+ const walks = /* @__PURE__ */ new WeakMap();
17913
+ /**
17914
+ * Reads commits reachable from the local branches, `origin/*` and HEAD, newest committer time first, like
17915
+ * `git log --all --date-order` limited to those refs. A commit is listed only after every child read so far, and
17916
+ * only once no commit still to be read is newer, keeping a page's worth read ahead, so a child stays above its
17917
+ * parents unless committer times run backwards by more than that.
17918
+ */
17919
+ const history = async ({ limit = 50, after } = {}) => {
17920
+ fs.clearReads();
17921
+ if (!(limit >= 1)) limit = 50;
17922
+ let walk = after ? walks.get(after) : void 0;
17923
+ if (after && !walk) throw new GitPanelError("changed");
17924
+ if (after) walks.delete(after);
17925
+ const readNode = async (oid) => {
17926
+ try {
17927
+ const { commit } = await readCommit(_objectSpread2(_objectSpread2({}, options), {}, {
17928
+ cache,
17929
+ oid
17930
+ }));
17931
+ return {
17932
+ commit: {
17933
+ oid,
17934
+ parents: commit.parent,
17935
+ message: commit.message.split("\n")[0],
17936
+ author: commit.author.name,
17937
+ timestamp: commit.author.timestamp,
17938
+ refs: []
17939
+ },
17940
+ time: commit.committer.timestamp,
17941
+ children: 0,
17942
+ expanded: false
17943
+ };
17944
+ } catch (error) {
17945
+ if (errorCode(error) === "NotFoundError") return null;
17946
+ throw error;
17947
+ }
17948
+ };
17949
+ if (!walk) {
17950
+ walk = {
17951
+ nodes: /* @__PURE__ */ new Map(),
17952
+ pending: /* @__PURE__ */ new Set(),
17953
+ frontier: /* @__PURE__ */ new Set()
17954
+ };
17955
+ const tips = [];
17956
+ const branch = await currentBranch(options);
17957
+ for (const name of (await listBranches(options)).sort()) tips.push({
17958
+ ref: `refs/heads/${name}`,
17959
+ label: {
17960
+ kind: "branch",
17961
+ name,
17962
+ current: name === branch
17963
+ }
17964
+ });
17965
+ for (const name of (await listBranches(_objectSpread2(_objectSpread2({}, options), {}, { remote: "origin" }))).sort()) if (name !== "HEAD") tips.push({
17966
+ ref: `refs/remotes/origin/${name}`,
17967
+ label: {
17968
+ kind: "remote",
17969
+ name: `origin/${name}`,
17970
+ current: false
17971
+ }
17972
+ });
17973
+ if (!branch) tips.push({
17974
+ ref: "HEAD",
17975
+ label: {
17976
+ kind: "head",
17977
+ name: "HEAD",
17978
+ current: true
17979
+ }
17980
+ });
17981
+ for (const { ref, label } of tips) {
17982
+ let oid;
17983
+ try {
17984
+ oid = await resolveRef(_objectSpread2(_objectSpread2({}, options), {}, { ref }));
17985
+ } catch (error) {
17986
+ if (errorCode(error) === "NotFoundError") continue;
17987
+ throw error;
17988
+ }
17989
+ let node = walk.nodes.get(oid);
17990
+ if (!node) {
17991
+ const read = await readNode(oid);
17992
+ if (!read) continue;
17993
+ node = read;
17994
+ walk.nodes.set(oid, node);
17995
+ walk.pending.add(node);
17996
+ walk.frontier.add(node);
17997
+ }
17998
+ node.commit.refs.push(label);
17999
+ }
18000
+ }
18001
+ const { nodes, pending, frontier } = walk;
18002
+ const expand = async (node) => {
18003
+ frontier.delete(node);
18004
+ node.expanded = true;
18005
+ for (const parent of new Set(node.commit.parents)) {
18006
+ let next = nodes.get(parent);
18007
+ if (!next) {
18008
+ const read = await readNode(parent);
18009
+ if (!read) continue;
18010
+ next = read;
18011
+ nodes.set(parent, next);
18012
+ pending.add(next);
18013
+ frontier.add(next);
18014
+ }
18015
+ if (pending.has(node) && pending.has(next)) next.children++;
18016
+ }
18017
+ };
18018
+ const newer = (a, b) => a.time !== b.time ? a.time > b.time : a.commit.oid > b.commit.oid;
18019
+ const pick = (items, accept) => {
18020
+ let best = null;
18021
+ for (const node of items) if (accept(node) && (!best || newer(node, best))) best = node;
18022
+ return best;
18023
+ };
18024
+ const commits = [];
18025
+ while (commits.length < limit) {
18026
+ let ready = pick(pending, (node) => node.children === 0);
18027
+ let latest = pick(frontier, () => true);
18028
+ while (latest && (!ready || !ready.expanded || latest.time >= ready.time || pending.size < limit * 2)) {
18029
+ await expand(latest);
18030
+ ready = pick(pending, (node) => node.children === 0);
18031
+ latest = pick(frontier, () => true);
18032
+ }
18033
+ if (!ready) break;
18034
+ pending.delete(ready);
18035
+ for (const parent of new Set(ready.commit.parents)) {
18036
+ const node = nodes.get(parent);
18037
+ if (node && pending.has(node) && ready.expanded) node.children--;
18038
+ }
18039
+ commits.push(ready.commit);
18040
+ }
18041
+ await fs.checkReads();
18042
+ if (!pending.size) return {
18043
+ commits,
18044
+ cursor: null
18045
+ };
18046
+ const cursor = Object.freeze({ continues: "history" });
18047
+ walks.set(cursor, walk);
18048
+ return {
18049
+ commits,
18050
+ cursor
18051
+ };
18052
+ };
17155
18053
  const historyChanges = async (snapshot, oid) => {
17156
18054
  fs.clearReads();
17157
18055
  await assertSnapshot(snapshot);
@@ -17437,10 +18335,34 @@ async function openRepository(root) {
17437
18335
  throw error;
17438
18336
  }
17439
18337
  }),
18338
+ /** Stages, unstages or commits; see `runLocalOperation`. `guard` throws to stop before each write. */
18339
+ localOperation: (operation, guard) => serial(() => runLocalOperation(root, operation, guard)),
18340
+ /**
18341
+ * Whether a local branch, `origin/<name>` with `remote`, or the commit `name` with `remote` set to `'commit'`,
18342
+ * has the folder `path` (the root always exists).
18343
+ */
18344
+ hasFolder: (name, path, remote = false) => serial(async () => {
18345
+ const ref = remote === "commit" ? name : remote ? `refs/remotes/origin/${name}` : `refs/heads/${name}`;
18346
+ if (!path) return true;
18347
+ try {
18348
+ const { tree } = await readTree(_objectSpread2(_objectSpread2({}, options), {}, {
18349
+ oid: await resolveRef(_objectSpread2(_objectSpread2({}, options), {}, { ref })),
18350
+ filepath: path
18351
+ }));
18352
+ return tree.length > 0;
18353
+ } catch (_unused5) {
18354
+ return false;
18355
+ }
18356
+ }),
17440
18357
  read: (scope) => serial(() => read(scope)),
17441
18358
  readDiff: (snapshot, change) => serial(() => readDiff(snapshot, change)),
17442
18359
  historyChanges: (snapshot, oid) => serial(() => historyChanges(snapshot, oid)),
17443
18360
  /**
18361
+ * Reads one page of the commits reachable from the local branches, `origin/*` and a detached HEAD, newest first
18362
+ * with each child above its parents, and the refs at each. Pass the returned `cursor` as `after` for the next page.
18363
+ */
18364
+ history: (options) => serial(() => history(options)),
18365
+ /**
17444
18366
  * Reads the assets of both versions of a selected project file, for thumbnails. Staged changes compare HEAD with
17445
18367
  * the index, unstaged ones the index with the working tree, untracked ones nothing with the working tree, and
17446
18368
  * commit changes the first parent with the commit. Each version's sb3-source.json names its assets directory.
@@ -17456,4 +18378,4 @@ async function openRepository(root) {
17456
18378
  projectAssetLoader: (snapshot, folder, comparison) => ({ version, md5ext, signal }) => !isAssetName(md5ext) || signal.aborted ? Promise.resolve(null) : serial(() => readFolderAsset(snapshot, pathParts(folder), () => comparisonSource(snapshot, comparison, version), md5ext, signal)).catch(() => null)
17457
18379
  };
17458
18380
  }
17459
- export { createReadOnlyFs as i, upstreamWalkLimit as n, GitPanelError as r, openRepository as t };
18381
+ export { createReadOnlyFs as a, GitPanelError as i, openRepository as n, upstreamWalkLimit as r, historyPageSize as t };