git-fs-s3 0.13.0 → 0.15.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/dist/ops.js CHANGED
@@ -1,31 +1,46 @@
1
1
  import {
2
2
  getObjectSize,
3
3
  parseLooseObjectPath
4
- } from "./chunk-G636FB7W.js";
4
+ } from "./chunk-T5M5EYCZ.js";
5
5
  import {
6
+ HISTORY_WALK_DEPTH,
6
7
  assertBranchExists,
7
8
  assertSafeBranchName,
8
9
  createBranchFrom,
9
10
  createSemaphore,
10
11
  deleteBranchByName,
12
+ deleteFromTree,
11
13
  encodePack,
14
+ findTreeEntry,
15
+ getBlob,
16
+ getCommit,
17
+ getCommitHistory,
18
+ getCommitLog,
19
+ getFileContent,
20
+ getTreeFromRef,
12
21
  listBranches,
22
+ listTags,
23
+ listTreeEntries,
24
+ peelToCommit,
25
+ resolveCommit,
13
26
  resolveLooseRefFast,
14
- storePack
15
- } from "./chunk-QH3HS7VI.js";
27
+ resultKeyPrefixes,
28
+ runStep,
29
+ storePack,
30
+ summarizeCommit,
31
+ upsertTree
32
+ } from "./chunk-IAKZRWBZ.js";
16
33
  import {
17
34
  GitInvalidRequestError,
18
- GitObjectNotFoundError,
19
35
  GitPathNotFoundError,
20
- GitRefNotFoundError,
21
36
  inflate,
22
37
  isSafeTreePath,
23
38
  qualifyBranchRef,
24
39
  readBlobContent
25
- } from "./chunk-HO6OPXUS.js";
40
+ } from "./chunk-OKBQISUC.js";
26
41
 
27
42
  // src/ops/commit.ts
28
- import git2 from "isomorphic-git";
43
+ import git from "isomorphic-git";
29
44
 
30
45
  // src/ops/packed-writes.ts
31
46
  var OBJECT_TYPES = /* @__PURE__ */ new Set(["commit", "tree", "blob", "tag"]);
@@ -109,120 +124,6 @@ async function withPackedWrites(repo, fn) {
109
124
  return result;
110
125
  }
111
126
 
112
- // src/ops/tree.ts
113
- import git from "isomorphic-git";
114
- var joinPath = (prefix, name) => prefix ? `${prefix.replace(/\/+$/, "")}/${name}` : name;
115
- var BLOB_MODES = /* @__PURE__ */ new Set(["100644", "100755", "120000"]);
116
- async function upsertTree(repo, treeOid, entries) {
117
- const existing = treeOid ? (await git.readTree({ ...repo, oid: treeOid })).tree : [];
118
- const byName = new Map(existing.map((e) => [e.path, e]));
119
- const direct = /* @__PURE__ */ new Map();
120
- const nested = /* @__PURE__ */ new Map();
121
- for (const [filePath, blobOid] of entries) {
122
- const slash = filePath.indexOf("/");
123
- if (slash === -1) {
124
- direct.set(filePath, blobOid);
125
- } else {
126
- const dir = filePath.slice(0, slash);
127
- const rest = filePath.slice(slash + 1);
128
- if (!nested.has(dir)) nested.set(dir, /* @__PURE__ */ new Map());
129
- nested.get(dir)?.set(rest, blobOid);
130
- }
131
- }
132
- for (const [name, blobOid] of direct) {
133
- const current = byName.get(name);
134
- if (current && current.type !== "blob") {
135
- throw new GitInvalidRequestError(`"${name}" is a directory, not a file`);
136
- }
137
- byName.set(name, {
138
- mode: current && BLOB_MODES.has(current.mode) ? current.mode : "100644",
139
- path: name,
140
- oid: blobOid,
141
- type: "blob"
142
- });
143
- }
144
- const nestedResults = await Promise.all(
145
- Array.from(nested, async ([dir, subEntries]) => {
146
- const entry = byName.get(dir);
147
- if (entry && entry.type !== "tree") {
148
- throw new GitInvalidRequestError(`"${dir}" is a file, not a directory`);
149
- }
150
- const subtreeOid = entry?.oid;
151
- const newOid = await upsertTree(repo, subtreeOid, subEntries);
152
- return [dir, newOid];
153
- })
154
- );
155
- for (const [dir, newOid] of nestedResults) {
156
- byName.set(dir, { mode: "040000", path: dir, oid: newOid, type: "tree" });
157
- }
158
- return git.writeTree({ ...repo, tree: Array.from(byName.values()) });
159
- }
160
- async function deleteFromTree(repo, treeOid, filePath) {
161
- const result = await deleteFromSubtree(repo, treeOid, filePath, filePath);
162
- return result ?? git.writeTree({ ...repo, tree: [] });
163
- }
164
- async function deleteFromSubtree(repo, treeOid, filePath, fullPath) {
165
- const existing = (await git.readTree({ ...repo, oid: treeOid })).tree;
166
- const byName = new Map(existing.map((e) => [e.path, e]));
167
- const slash = filePath.indexOf("/");
168
- const name = slash === -1 ? filePath : filePath.slice(0, slash);
169
- const entry = byName.get(name);
170
- if (slash === -1) {
171
- if (entry?.type !== "blob") {
172
- throw new GitPathNotFoundError(`No such file: ${fullPath}`);
173
- }
174
- byName.delete(name);
175
- } else {
176
- if (entry?.type !== "tree") {
177
- throw new GitPathNotFoundError(`No such file: ${fullPath}`);
178
- }
179
- const newOid = await deleteFromSubtree(
180
- repo,
181
- entry.oid,
182
- filePath.slice(slash + 1),
183
- fullPath
184
- );
185
- if (newOid === null) byName.delete(name);
186
- else byName.set(name, { ...entry, oid: newOid });
187
- }
188
- if (byName.size === 0) return null;
189
- return git.writeTree({ ...repo, tree: Array.from(byName.values()) });
190
- }
191
- async function findTreeEntry(repo, rootTreeOid, treePath) {
192
- if (!treePath) {
193
- return { path: "", mode: "040000", type: "tree", oid: rootTreeOid };
194
- }
195
- const parts = treePath.split("/").filter(Boolean);
196
- let currentTreeOid = rootTreeOid;
197
- let currentPath = "";
198
- for (const [index, part] of parts.entries()) {
199
- const tree = await git.readTree({ ...repo, oid: currentTreeOid });
200
- const entry = tree.tree.find((candidate) => candidate.path === part);
201
- if (!entry) return null;
202
- currentPath = currentPath ? joinPath(currentPath, entry.path) : entry.path;
203
- if (index === parts.length - 1) {
204
- return {
205
- path: currentPath,
206
- mode: entry.mode,
207
- type: entry.type,
208
- oid: entry.oid
209
- };
210
- }
211
- if (entry.type !== "tree") return null;
212
- currentTreeOid = entry.oid;
213
- }
214
- return null;
215
- }
216
- async function listTreeEntries(repo, treeOid, prefix = "") {
217
- const tree = await git.readTree({ ...repo, oid: treeOid });
218
- return tree.tree.map((entry) => ({
219
- path: prefix ? joinPath(prefix, entry.path) : entry.path,
220
- mode: entry.mode,
221
- type: entry.type,
222
- oid: entry.oid
223
- }));
224
- }
225
-
226
127
  // src/ops/commit.ts
227
128
  function authorNow(name, email) {
228
129
  return {
@@ -240,11 +141,11 @@ async function writeCommit(repo, options) {
240
141
  let parentOid;
241
142
  let parentTreeOid;
242
143
  try {
243
- parentOid = await git2.resolveRef({
144
+ parentOid = await git.resolveRef({
244
145
  ...repo,
245
146
  ref: `refs/heads/${options.branch}`
246
147
  });
247
- const { commit } = await git2.readCommit({ ...repo, oid: parentOid });
148
+ const { commit } = await git.readCommit({ ...repo, oid: parentOid });
248
149
  parentTreeOid = commit.tree;
249
150
  } catch (err) {
250
151
  if (err?.code !== "NotFoundError") {
@@ -252,7 +153,7 @@ async function writeCommit(repo, options) {
252
153
  }
253
154
  }
254
155
  const treeOid = await options.buildTree(parentTreeOid, repo);
255
- const commitOid = await git2.writeCommit({
156
+ const commitOid = await git.writeCommit({
256
157
  ...repo,
257
158
  commit: {
258
159
  message: options.message,
@@ -262,7 +163,7 @@ async function writeCommit(repo, options) {
262
163
  committer: options.author
263
164
  }
264
165
  });
265
- await git2.writeRef({
166
+ await git.writeRef({
266
167
  ...repo,
267
168
  ref: `refs/heads/${options.branch}`,
268
169
  value: commitOid,
@@ -293,7 +194,7 @@ async function commitFilesToBare(repo, options) {
293
194
  await Promise.all(
294
195
  options.files.map(async (file) => {
295
196
  const content = typeof file.content === "string" ? new TextEncoder().encode(file.content) : file.content;
296
- const oid = await git2.writeBlob({ ...writeRepo, blob: content });
197
+ const oid = await git.writeBlob({ ...writeRepo, blob: content });
297
198
  blobs.set(file.path, oid);
298
199
  })
299
200
  );
@@ -320,180 +221,7 @@ async function deleteFileFromBare(repo, options) {
320
221
 
321
222
  // src/ops/diff.ts
322
223
  import { createTwoFilesPatch } from "diff";
323
- import git4 from "isomorphic-git";
324
-
325
- // src/ops/history.ts
326
- import git3 from "isomorphic-git";
327
-
328
- // src/ops/types.ts
329
- var runStep = (hooks, label, fn) => hooks?.step ? hooks.step(label, fn) : fn();
330
- function resultKeyPrefixes(gitdir) {
331
- return [
332
- `commitlog:${gitdir}:`,
333
- `tree:${gitdir}:`,
334
- `last-commits:${gitdir}:`,
335
- `file-history:${gitdir}:`
336
- ];
337
- }
338
-
339
- // src/ops/history.ts
340
- var HISTORY_WALK_DEPTH = 400;
341
- function summarizeCommit(commit) {
342
- return {
343
- sha: commit.oid,
344
- message: commit.commit.message.trim(),
345
- authorName: commit.commit.author.name,
346
- authorEmail: commit.commit.author.email,
347
- createdAt: new Date(commit.commit.author.timestamp * 1e3).toISOString()
348
- };
349
- }
350
- var isNotFound = (err) => err?.code === "NotFoundError";
351
- function wrapMissingObject(promise, context) {
352
- return promise.catch((err) => {
353
- if (isNotFound(err)) {
354
- throw new GitObjectNotFoundError(
355
- `Git data for ${context} is missing from storage`
356
- );
357
- }
358
- throw err;
359
- });
360
- }
361
- async function resolveRefOid(repo, ref) {
362
- try {
363
- return await git3.resolveRef({ ...repo, ref: qualifyBranchRef(ref) });
364
- } catch (err) {
365
- if (isNotFound(err))
366
- throw new GitRefNotFoundError(`Ref ${ref} does not exist`);
367
- throw err;
368
- }
369
- }
370
- async function resolveCommit(repo, ref) {
371
- const oid = await resolveRefOid(repo, ref);
372
- const { commit } = await wrapMissingObject(
373
- git3.readCommit({ ...repo, oid }),
374
- `${repo.gitdir} commit ${oid}`
375
- );
376
- return { oid, commit };
377
- }
378
- async function getBlob(repo, sha) {
379
- const { blob } = await wrapMissingObject(
380
- git3.readBlob({ ...repo, oid: sha }),
381
- `${repo.gitdir} blob ${sha}`
382
- );
383
- return blob;
384
- }
385
- async function getFileContent(repo, filePath, ref, hooks) {
386
- if (hooks?.prefetch) await runStep(hooks, "prefetch", hooks.prefetch);
387
- const { commit } = await resolveCommit(repo, ref);
388
- const context = `${repo.gitdir}@${ref}:${filePath}`;
389
- const entry = await wrapMissingObject(
390
- findTreeEntry(repo, commit.tree, filePath),
391
- context
392
- );
393
- if (entry?.type !== "blob") {
394
- throw new GitPathNotFoundError(`File not found: ${filePath}`);
395
- }
396
- const { blob } = await wrapMissingObject(
397
- git3.readBlob({ ...repo, oid: entry.oid }),
398
- context
399
- );
400
- return blob;
401
- }
402
- async function getCommit(repo, sha) {
403
- const result = await wrapMissingObject(
404
- git3.readCommit({ ...repo, oid: sha }),
405
- `${repo.gitdir} commit ${sha}`
406
- );
407
- return { oid: result.oid, commit: result.commit, payload: result.payload };
408
- }
409
- async function getCommitLog(repo, options, hooks) {
410
- const { ref } = options;
411
- const depth = options.depth ?? 50;
412
- let headSha = options.knownHeadSha;
413
- if (headSha === void 0) {
414
- try {
415
- headSha = await resolveRefOid(repo, ref);
416
- } catch (err) {
417
- if (err instanceof GitRefNotFoundError) return [];
418
- throw err;
419
- }
420
- }
421
- const cacheKey = `commitlog:${repo.gitdir}:${headSha}`;
422
- const cached = hooks?.resultCache?.get(cacheKey);
423
- const fullyWalked = cached?.at(-1)?.commit.parent.length === 0;
424
- if (cached && (cached.length >= depth || fullyWalked)) {
425
- hooks?.onNote?.(`getCommitLog: cache hit ${cacheKey} (depth=${depth})`);
426
- return cached.slice(0, depth);
427
- }
428
- hooks?.onNote?.(`getCommitLog: cache miss ${cacheKey} (depth=${depth})`);
429
- if (hooks?.prefetch) await runStep(hooks, "prefetch", hooks.prefetch);
430
- const log = await wrapMissingObject(
431
- runStep(
432
- hooks,
433
- `git.log ${ref} depth=${depth}`,
434
- () => git3.log({ ...repo, ref: headSha, depth })
435
- ),
436
- `${repo.gitdir}@${ref} history`
437
- );
438
- const result = log.map(({ oid, commit, payload }) => ({
439
- oid,
440
- commit,
441
- payload: payload ?? ""
442
- }));
443
- if (!cached || result.length > cached.length) {
444
- hooks?.resultCache?.set(cacheKey, result);
445
- }
446
- return result;
447
- }
448
- async function getTreeFromRef(repo, options, hooks) {
449
- const { ref } = options;
450
- const treePath = options.treePath ?? "";
451
- const { commit, oid: headSha } = await resolveCommit(repo, ref);
452
- const cacheKey = `tree:${repo.gitdir}:${headSha}:${treePath}`;
453
- const cached = hooks?.resultCache?.get(cacheKey);
454
- if (cached) {
455
- hooks?.onNote?.(`getTreeFromRef: cache hit ${cacheKey}`);
456
- return cached;
457
- }
458
- hooks?.onNote?.(`getTreeFromRef: cache miss ${cacheKey}`);
459
- if (hooks?.prefetch) await runStep(hooks, "prefetch", hooks.prefetch);
460
- const context = `${repo.gitdir}@${ref}:${treePath || "/"}`;
461
- const dir = treePath ? await wrapMissingObject(
462
- runStep(
463
- hooks,
464
- `findTreeEntry ${treePath}`,
465
- () => findTreeEntry(repo, commit.tree, treePath)
466
- ),
467
- context
468
- ) : { path: "", type: "tree", oid: commit.tree };
469
- if (!dir) {
470
- throw new GitPathNotFoundError(
471
- `Path "${treePath}" does not exist at ${ref}`
472
- );
473
- }
474
- const result = dir.type === "tree" ? await wrapMissingObject(
475
- runStep(
476
- hooks,
477
- `listTreeEntries ${treePath || "/"}`,
478
- () => listTreeEntries(repo, dir.oid, dir.path)
479
- ),
480
- context
481
- ) : [];
482
- hooks?.resultCache?.set(cacheKey, result);
483
- return result;
484
- }
485
- async function getCommitHistory(repo, options, hooks) {
486
- const limit = options.limit ?? 50;
487
- const skip = options.skip ?? 0;
488
- const log = await getCommitLog(
489
- repo,
490
- { ref: options.ref, depth: limit + skip },
491
- hooks
492
- );
493
- return log.slice(skip, skip + limit);
494
- }
495
-
496
- // src/ops/diff.ts
224
+ import git2 from "isomorphic-git";
497
225
  var MAX_DIFF_TEXT_BYTES = 1024 * 1024;
498
226
  var MAX_CONCURRENT_READS = 16;
499
227
  function countContentLines(content) {
@@ -570,12 +298,12 @@ async function diffTrees(repo, oldTreeOid, newTreeOid) {
570
298
  const readContent = async (side) => {
571
299
  if (!side) return null;
572
300
  const { blob } = await reads.run(
573
- () => git4.readBlob({ ...repo, oid: side.oid })
301
+ () => git2.readBlob({ ...repo, oid: side.oid })
574
302
  );
575
303
  return readBlobContent(blob);
576
304
  };
577
- const trees = oldTreeOid ? [git4.TREE({ ref: oldTreeOid }), git4.TREE({ ref: newTreeOid })] : [git4.TREE({ ref: newTreeOid })];
578
- const changes = await git4.walk({
305
+ const trees = oldTreeOid ? [git2.TREE({ ref: oldTreeOid }), git2.TREE({ ref: newTreeOid })] : [git2.TREE({ ref: newTreeOid })];
306
+ const changes = await git2.walk({
579
307
  ...repo,
580
308
  trees,
581
309
  map: async (filepath, entries) => {
@@ -645,7 +373,7 @@ async function getDiffBetweenRefs(repo, baseRef, compareRef) {
645
373
  resolveCommit(repo, baseRef),
646
374
  resolveCommit(repo, compareRef)
647
375
  ]);
648
- const [mergeBase] = await git4.findMergeBase({
376
+ const [mergeBase] = await git2.findMergeBase({
649
377
  ...repo,
650
378
  oids: [base.oid, compare.oid]
651
379
  });
@@ -823,16 +551,16 @@ async function getLastCommitsForTree(repo, options, hooks) {
823
551
  }
824
552
 
825
553
  // src/ops/merge.ts
826
- import git5 from "isomorphic-git";
554
+ import git3 from "isomorphic-git";
827
555
  async function analyzeMerge(repo, sourceBranch, targetBranch) {
828
556
  assertSafeBranchName(sourceBranch);
829
557
  assertSafeBranchName(targetBranch);
830
558
  try {
831
559
  const [sourceOid, targetOid] = await Promise.all([
832
- git5.resolveRef({ ...repo, ref: qualifyBranchRef(sourceBranch) }),
833
- git5.resolveRef({ ...repo, ref: qualifyBranchRef(targetBranch) })
560
+ git3.resolveRef({ ...repo, ref: qualifyBranchRef(sourceBranch) }),
561
+ git3.resolveRef({ ...repo, ref: qualifyBranchRef(targetBranch) })
834
562
  ]);
835
- const isDescendant = sourceOid === targetOid || await git5.isDescendent({
563
+ const isDescendant = sourceOid === targetOid || await git3.isDescendent({
836
564
  ...repo,
837
565
  oid: sourceOid,
838
566
  ancestor: targetOid
@@ -859,19 +587,19 @@ async function fastForwardMerge(repo, sourceBranch, targetBranch) {
859
587
  assertSafeBranchName(sourceBranch);
860
588
  assertSafeBranchName(targetBranch);
861
589
  const [sourceOid, targetOid] = await Promise.all([
862
- git5.resolveRef({ ...repo, ref: `refs/heads/${sourceBranch}` }),
863
- git5.resolveRef({ ...repo, ref: `refs/heads/${targetBranch}` })
590
+ git3.resolveRef({ ...repo, ref: `refs/heads/${sourceBranch}` }),
591
+ git3.resolveRef({ ...repo, ref: `refs/heads/${targetBranch}` })
864
592
  ]);
865
- if (sourceOid === targetOid || await git5.isDescendent({ ...repo, oid: targetOid, ancestor: sourceOid })) {
593
+ if (sourceOid === targetOid || await git3.isDescendent({ ...repo, oid: targetOid, ancestor: sourceOid })) {
866
594
  return { success: true, commitSha: targetOid };
867
595
  }
868
- const isFF = await git5.isDescendent({
596
+ const isFF = await git3.isDescendent({
869
597
  ...repo,
870
598
  oid: sourceOid,
871
599
  ancestor: targetOid
872
600
  });
873
601
  if (!isFF) return null;
874
- await git5.writeRef({
602
+ await git3.writeRef({
875
603
  ...repo,
876
604
  ref: `refs/heads/${targetBranch}`,
877
605
  value: sourceOid,
@@ -997,8 +725,10 @@ export {
997
725
  getSubmodules,
998
726
  getTreeFromRef,
999
727
  listBranches,
728
+ listTags,
1000
729
  listTreeEntries,
1001
730
  parseGitmodules,
731
+ peelToCommit,
1002
732
  resolveCommit,
1003
733
  resolveLooseRefFast,
1004
734
  resultKeyPrefixes,