@kubohiroya/turbowarp-plus-editor-git 0.15.0 → 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.
- package/README.ja.md +5 -3
- package/README.md +5 -3
- package/dist/file-diff-view.d.ts +3 -1
- package/dist/filesystem.d.ts +2 -2
- package/dist/history-graph-view.d.ts +40 -0
- package/dist/history-graph.d.ts +44 -0
- package/dist/index.d.ts +18 -1
- package/dist/index.js +693 -30
- package/dist/local-operations.d.ts +14 -0
- package/dist/messages.d.ts +52 -0
- package/dist/{project-comparison-LAyP_beL.js → project-comparison-MU0qD2wo.js} +213 -16
- package/dist/project-source-diff.d.ts +2 -0
- package/dist/project-source-diff.js +2 -2
- package/dist/project-source-review.d.ts +43 -0
- package/dist/project-source-tabs.d.ts +35 -0
- package/dist/pull-request-panel.d.ts +6 -1
- package/dist/{repository-Cx-mxT9l.js → repository-BYno-5f8.js} +491 -4
- package/dist/repository.d.ts +44 -0
- package/dist/repository.js +1 -1
- package/dist/style.css +27 -4
- package/package.json +1 -1
- package/src/file-diff-view.tsx +7 -3
- package/src/filesystem.ts +2 -1
- package/src/history-graph-view.tsx +233 -0
- package/src/history-graph.ts +90 -0
- package/src/index.tsx +135 -16
- package/src/local-operations.ts +59 -4
- package/src/messages.ts +26 -2
- package/src/project-source-diff.tsx +2 -0
- package/src/project-source-review.tsx +127 -15
- package/src/project-source-tabs.tsx +118 -0
- package/src/pull-request-panel.tsx +26 -5
- package/src/repository.ts +155 -1
- package/src/style.css +27 -4
|
@@ -12374,6 +12374,141 @@ async function _resolveFilepath({ fs, cache, gitdir, tree, pathArray, oid, filep
|
|
|
12374
12374
|
throw new NotFoundError(`file or directory found at "${oid}:${filepath}"`);
|
|
12375
12375
|
}
|
|
12376
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
|
+
/**
|
|
12377
12512
|
* Refuse to materialize a working-tree entry whose parent path traverses a
|
|
12378
12513
|
* symbolic link. A leading component that is a symlink could otherwise redirect
|
|
12379
12514
|
* a write or mkdir outside the working tree. git applies the same check: it does
|
|
@@ -12867,6 +13002,97 @@ async function batchAllSettled(operationName, tasks, onProgress, batchSize) {
|
|
|
12867
13002
|
if (rejections.length > 0) throw new MultipleGitError(rejections);
|
|
12868
13003
|
return results;
|
|
12869
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
|
+
}
|
|
12870
13096
|
var LINEBREAKS = /^.*(\r?\n|$)/gm;
|
|
12871
13097
|
function mergeFile({ branches, contents }) {
|
|
12872
13098
|
const ourName = branches[1];
|
|
@@ -15996,6 +16222,50 @@ async function readCommit({ fs, dir, gitdir = join(dir, ".git"), oid, cache = {}
|
|
|
15996
16222
|
}
|
|
15997
16223
|
}
|
|
15998
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
|
+
/**
|
|
15999
16269
|
* Remove a file from the git index (aka staging area)
|
|
16000
16270
|
*
|
|
16001
16271
|
* Note that this does NOT delete the file in the working directory.
|
|
@@ -17186,7 +17456,8 @@ async function runLocalOperation(root, operation, guard) {
|
|
|
17186
17456
|
var _globalThis$navigator;
|
|
17187
17457
|
const execute = async () => {
|
|
17188
17458
|
guard();
|
|
17189
|
-
const
|
|
17459
|
+
const switching = operation.kind === "switchBranch" || operation.kind === "createBranch" && operation.checkout;
|
|
17460
|
+
const transaction = createMutationFs(root, switching);
|
|
17190
17461
|
const options = {
|
|
17191
17462
|
fs: transaction.fs,
|
|
17192
17463
|
dir: "/",
|
|
@@ -17210,8 +17481,57 @@ async function runLocalOperation(root, operation, guard) {
|
|
|
17210
17481
|
"/.git/REVERT_HEAD",
|
|
17211
17482
|
"/.git/rebase-merge",
|
|
17212
17483
|
"/.git/rebase-apply"
|
|
17213
|
-
]) if (await exists(path)) throw new GitPanelError("
|
|
17214
|
-
if (operation.kind === "
|
|
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") {
|
|
17215
17535
|
const modes = /* @__PURE__ */ new Map();
|
|
17216
17536
|
await walk(_objectSpread2(_objectSpread2({}, options), {}, {
|
|
17217
17537
|
trees: [STAGE()],
|
|
@@ -17259,6 +17579,8 @@ async function runLocalOperation(root, operation, guard) {
|
|
|
17259
17579
|
}
|
|
17260
17580
|
// src/repository.ts
|
|
17261
17581
|
init_objectSpread2();
|
|
17582
|
+
/** Commits read per history page unless asked otherwise. */
|
|
17583
|
+
var historyPageSize = 50;
|
|
17262
17584
|
var projectSourceLimit = 16777216;
|
|
17263
17585
|
var emptyTree = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
|
|
17264
17586
|
var textLimit = 1048576;
|
|
@@ -17522,6 +17844,7 @@ async function openRepository(root) {
|
|
|
17522
17844
|
}
|
|
17523
17845
|
const branch = await currentBranch(options);
|
|
17524
17846
|
const branches = await listBranches(options);
|
|
17847
|
+
const remoteBranches = (await listBranches(_objectSpread2(_objectSpread2({}, options), {}, { remote: "origin" }))).filter((name) => name !== "HEAD" && !branches.includes(name)).sort();
|
|
17525
17848
|
const commits = head ? (await log(_objectSpread2(_objectSpread2({}, options), {}, {
|
|
17526
17849
|
cache,
|
|
17527
17850
|
ref: head,
|
|
@@ -17577,6 +17900,7 @@ async function openRepository(root) {
|
|
|
17577
17900
|
branch: branch || void 0,
|
|
17578
17901
|
head,
|
|
17579
17902
|
branches,
|
|
17903
|
+
remoteBranches,
|
|
17580
17904
|
commits,
|
|
17581
17905
|
changes,
|
|
17582
17906
|
scope,
|
|
@@ -17585,6 +17909,147 @@ async function openRepository(root) {
|
|
|
17585
17909
|
upstream
|
|
17586
17910
|
};
|
|
17587
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
|
+
};
|
|
17588
18053
|
const historyChanges = async (snapshot, oid) => {
|
|
17589
18054
|
fs.clearReads();
|
|
17590
18055
|
await assertSnapshot(snapshot);
|
|
@@ -17872,10 +18337,32 @@ async function openRepository(root) {
|
|
|
17872
18337
|
}),
|
|
17873
18338
|
/** Stages, unstages or commits; see `runLocalOperation`. `guard` throws to stop before each write. */
|
|
17874
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
|
+
}),
|
|
17875
18357
|
read: (scope) => serial(() => read(scope)),
|
|
17876
18358
|
readDiff: (snapshot, change) => serial(() => readDiff(snapshot, change)),
|
|
17877
18359
|
historyChanges: (snapshot, oid) => serial(() => historyChanges(snapshot, oid)),
|
|
17878
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
|
+
/**
|
|
17879
18366
|
* Reads the assets of both versions of a selected project file, for thumbnails. Staged changes compare HEAD with
|
|
17880
18367
|
* the index, unstaged ones the index with the working tree, untracked ones nothing with the working tree, and
|
|
17881
18368
|
* commit changes the first parent with the commit. Each version's sb3-source.json names its assets directory.
|
|
@@ -17891,4 +18378,4 @@ async function openRepository(root) {
|
|
|
17891
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)
|
|
17892
18379
|
};
|
|
17893
18380
|
}
|
|
17894
|
-
export { createReadOnlyFs as i,
|
|
18381
|
+
export { createReadOnlyFs as a, GitPanelError as i, openRepository as n, upstreamWalkLimit as r, historyPageSize as t };
|
package/dist/repository.d.ts
CHANGED
|
@@ -30,11 +30,42 @@ export type ProjectComparison = {
|
|
|
30
30
|
kind: 'commit';
|
|
31
31
|
commit: string;
|
|
32
32
|
};
|
|
33
|
+
/** A ref drawn next to a commit in the history: a local branch, `origin/<name>`, or HEAD when it is detached. */
|
|
34
|
+
export interface HistoryRef {
|
|
35
|
+
kind: 'branch' | 'remote' | 'head';
|
|
36
|
+
/** The branch name; `origin/<name>` for remote branches; `HEAD` for a detached HEAD. */
|
|
37
|
+
name: string;
|
|
38
|
+
/** The branch HEAD is on, or the detached HEAD. */
|
|
39
|
+
current: boolean;
|
|
40
|
+
}
|
|
41
|
+
export interface HistoryCommit {
|
|
42
|
+
oid: string;
|
|
43
|
+
parents: string[];
|
|
44
|
+
/** The first line of the message. */
|
|
45
|
+
message: string;
|
|
46
|
+
author: string;
|
|
47
|
+
/** Author time in seconds. */
|
|
48
|
+
timestamp: number;
|
|
49
|
+
refs: HistoryRef[];
|
|
50
|
+
}
|
|
51
|
+
/** Where `history` continues. It only works with the repository that returned it. */
|
|
52
|
+
export type HistoryCursor = {
|
|
53
|
+
readonly continues: 'history';
|
|
54
|
+
};
|
|
55
|
+
export interface HistoryPage {
|
|
56
|
+
commits: HistoryCommit[];
|
|
57
|
+
/** Pass as `after` to read the next page; `null` when every commit has been read. */
|
|
58
|
+
cursor: HistoryCursor | null;
|
|
59
|
+
}
|
|
60
|
+
/** Commits read per history page unless asked otherwise. */
|
|
61
|
+
export declare const historyPageSize = 50;
|
|
33
62
|
type Metadata = Map<string, Uint8Array | null>;
|
|
34
63
|
export interface Snapshot {
|
|
35
64
|
branch: string | undefined;
|
|
36
65
|
head: string | null;
|
|
37
66
|
branches: string[];
|
|
67
|
+
/** Branches fetched from `origin` that have no local branch of the same name yet. */
|
|
68
|
+
remoteBranches: string[];
|
|
38
69
|
commits: Commit[];
|
|
39
70
|
changes: FileChange[];
|
|
40
71
|
scope: string;
|
|
@@ -87,9 +118,22 @@ export declare function openRepository(root: FileSystemDirectoryHandle): Promise
|
|
|
87
118
|
remoteOperation: (operation: RemoteOperation, getSession: GetRemoteSession, guard: () => void, signal?: AbortSignal) => Promise<void>;
|
|
88
119
|
/** Stages, unstages or commits; see `runLocalOperation`. `guard` throws to stop before each write. */
|
|
89
120
|
localOperation: (operation: LocalOperation, guard: () => void) => Promise<void>;
|
|
121
|
+
/**
|
|
122
|
+
* Whether a local branch, `origin/<name>` with `remote`, or the commit `name` with `remote` set to `'commit'`,
|
|
123
|
+
* has the folder `path` (the root always exists).
|
|
124
|
+
*/
|
|
125
|
+
hasFolder: (name: string, path: string, remote?: boolean | "commit") => Promise<boolean>;
|
|
90
126
|
read: (scope?: string) => Promise<Snapshot>;
|
|
91
127
|
readDiff: (snapshot: Snapshot, change: FileChange) => Promise<FileDiff>;
|
|
92
128
|
historyChanges: (snapshot: Snapshot, oid: string) => Promise<FileChange[]>;
|
|
129
|
+
/**
|
|
130
|
+
* Reads one page of the commits reachable from the local branches, `origin/*` and a detached HEAD, newest first
|
|
131
|
+
* with each child above its parents, and the refs at each. Pass the returned `cursor` as `after` for the next page.
|
|
132
|
+
*/
|
|
133
|
+
history: (options?: {
|
|
134
|
+
limit?: number;
|
|
135
|
+
after?: HistoryCursor | null;
|
|
136
|
+
}) => Promise<HistoryPage>;
|
|
93
137
|
/**
|
|
94
138
|
* Reads the assets of both versions of a selected project file, for thumbnails. Staged changes compare HEAD with
|
|
95
139
|
* the index, unstaged ones the index with the working tree, untracked ones nothing with the working tree, and
|
package/dist/repository.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { i as GitPanelError, a as createReadOnlyFs, t as historyPageSize, n as openRepository, r as upstreamWalkLimit } from "./repository-BYno-5f8.js";
|
package/dist/style.css
CHANGED
|
@@ -148,15 +148,14 @@
|
|
|
148
148
|
.twgit-panel aside li { overflow-wrap: anywhere; }
|
|
149
149
|
.twgit-panel summary { cursor: pointer; }
|
|
150
150
|
.twgit-panel .twgit-file { width: 100%; border: 0; margin: 1px 0; }
|
|
151
|
-
.twgit-panel .twgit-
|
|
151
|
+
.twgit-panel .twgit-file-row { display: flex; gap: 6px; align-items: center; }
|
|
152
|
+
.twgit-panel .twgit-file-row .twgit-file { flex: 1; min-width: 0; width: auto; text-align: start; }
|
|
153
|
+
.twgit-panel .twgit-stage { flex: none; font-size: 11px; margin: 0; white-space: nowrap; }
|
|
152
154
|
.twgit-commit { display: grid; gap: 6px; margin: 10px 0; padding: 8px; border: 1px solid color-mix(in srgb, CanvasText 18%, Canvas); border-radius: 6px; }
|
|
153
155
|
.twgit-commit label { display: grid; gap: 4px; font-size: 12px; }
|
|
154
156
|
.twgit-commit textarea { font: inherit; resize: vertical; min-height: 3em; }
|
|
155
157
|
.twgit-diff { padding: 0 16px 16px; min-width: 0; overflow: auto; }
|
|
156
158
|
.twgit-diff .diff { font-size: 12px; }
|
|
157
|
-
.twgit-history { list-style: none; margin: 0; padding: 0; }
|
|
158
|
-
.twgit-history li { padding: 5px 0; }
|
|
159
|
-
.twgit-history small { display: block; font-size: 11px; }
|
|
160
159
|
.twgit-panel > footer { font-size: 11px; padding: 8px 16px; border-top: 1px solid GrayText; }
|
|
161
160
|
.twgit-error { margin: 6px 16px; color: #a11919; padding: 8px; background: #fff0f0; }
|
|
162
161
|
@media (max-width: 700px) { .twgit-content { grid-template-columns: minmax(180px, 42%) minmax(0, 1fr); } .twgit-panel > header { flex-wrap: wrap; } }
|
|
@@ -187,4 +186,28 @@
|
|
|
187
186
|
.twgit-comparison-body > p { margin: 0 0 8px; }
|
|
188
187
|
.twgit-comparison-body > section { margin-top: 16px; }
|
|
189
188
|
.twgit-comparison-actions { display: flex; gap: 8px; justify-content: flex-end; padding: 10px 16px; border-top: 1px solid GrayText; }
|
|
189
|
+
.twgit-branches ul { list-style: none; padding: 0; margin: 4px 0; }
|
|
190
|
+
.twgit-branches li { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; margin: 2px 0; }
|
|
191
|
+
.twgit-branches form { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; margin: 6px 0; }
|
|
192
|
+
.twgit-graph-list { list-style: none; margin: 0; padding: 0; }
|
|
193
|
+
.twgit-graph-row { position: relative; display: flex; align-items: stretch; gap: 4px; height: 44px; }
|
|
194
|
+
.twgit-graph-lanes { flex: none; display: block; }
|
|
195
|
+
.twgit-panel .twgit-graph-commit, .twgit-graph-commit { flex: 1; min-width: 0; display: flex; flex-direction: column; justify-content: center;
|
|
196
|
+
gap: 1px; margin: 2px 0; padding: 2px 6px; border: 0; text-align: start; }
|
|
197
|
+
.twgit-graph-subject, .twgit-graph-meta { display: block; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
|
|
198
|
+
.twgit-graph-meta { font-size: 11px; opacity: .8; }
|
|
199
|
+
.twgit-graph-ref { display: inline-block; margin-inline-end: 4px; padding: 0 5px; font-size: 11px; line-height: 16px; border-radius: 8px;
|
|
200
|
+
border: 1px solid color-mix(in srgb, CanvasText 35%, Canvas); }
|
|
201
|
+
.twgit-graph-ref-current { font-weight: 600; border-color: currentColor; }
|
|
202
|
+
.twgit-graph-ref-remote { border-style: dashed; }
|
|
203
|
+
.twgit-panel .twgit-graph-menu-button, .twgit-graph-menu-button { flex: none; align-self: center; padding: 0 6px; line-height: 22px; }
|
|
204
|
+
.twgit-graph-popup { position: absolute; z-index: 6; top: 100%; right: 0; display: grid; gap: 2px; min-width: 200px; padding: 6px;
|
|
205
|
+
background: Canvas; color: CanvasText; border: 1px solid GrayText; border-radius: 6px; box-shadow: 0 8px 24px #0004; }
|
|
206
|
+
.twgit-panel .twgit-graph-popup [role="menuitem"], .twgit-graph-popup [role="menuitem"] { border: 0; text-align: start; }
|
|
207
|
+
.twgit-graph-popup form { display: grid; gap: 6px; font-size: 12px; }
|
|
208
|
+
.twgit-graph-form-actions { display: flex; gap: 6px; justify-content: flex-end; }
|
|
209
|
+
.twgit-graph-more { margin: 6px 0; }
|
|
210
|
+
.twgit-graph-status { margin: 4px 0; font-size: 11px; min-height: 1em; }
|
|
211
|
+
.twgit-panel .twgit-graph-popup [role="menuitem"]:focus-visible, .twgit-graph-popup [role="menuitem"]:focus-visible { outline-offset: -2px; }
|
|
212
|
+
.twgit-graph-form-error { margin: 0; color: #a11919; overflow-wrap: anywhere; }
|
|
190
213
|
/*$vite$:1*/
|