screw-up 1.31.0 → 1.33.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.
Files changed (35) hide show
  1. package/dist/index.cjs +604 -179
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.mjs +4 -4
  4. package/dist/main.cjs +620 -195
  5. package/dist/main.cjs.map +1 -1
  6. package/dist/main.mjs +6 -6
  7. package/dist/{metadata-file-BWd04LhD.js → metadata-file-Case8fsm.js} +603 -177
  8. package/dist/metadata-file-Case8fsm.js.map +1 -0
  9. package/dist/{packageMetadata-BsMXJpMH.js → packageMetadata-4rUlIBjt.js} +6 -6
  10. package/dist/{packageMetadata-BsMXJpMH.js.map → packageMetadata-4rUlIBjt.js.map} +1 -1
  11. package/dist/{packageMetadata-BDGBM3Fx.cjs → packageMetadata-CaaD3Ehh.cjs} +3 -3
  12. package/dist/{packageMetadata-ip0rBTwa.cjs → packageMetadata-k_QXJ2PH.cjs} +5 -5
  13. package/dist/{packageMetadata-ip0rBTwa.cjs.map → packageMetadata-k_QXJ2PH.cjs.map} +1 -1
  14. package/dist/src/analyzer.d.ts +2 -2
  15. package/dist/src/analyzer.d.ts.map +1 -1
  16. package/dist/src/cli-internal.d.ts +2 -2
  17. package/dist/src/cli.d.ts +2 -2
  18. package/dist/src/declaration-import-fix.d.ts +2 -2
  19. package/dist/src/default-import-fix.d.ts +2 -2
  20. package/dist/src/fast-tags.d.ts +2 -2
  21. package/dist/src/fast-tags.d.ts.map +1 -1
  22. package/dist/src/generated/packageMetadata.d.ts +4 -4
  23. package/dist/src/git-operations.d.ts +2 -2
  24. package/dist/src/git-operations.d.ts.map +1 -1
  25. package/dist/src/git-ref-utils.d.ts +46 -4
  26. package/dist/src/git-ref-utils.d.ts.map +1 -1
  27. package/dist/src/index.d.ts +2 -2
  28. package/dist/src/internal.d.ts +2 -2
  29. package/dist/src/main.d.ts +2 -2
  30. package/dist/src/metadata-file.d.ts +2 -2
  31. package/dist/src/text-edits.d.ts +2 -2
  32. package/dist/src/types.d.ts +2 -2
  33. package/dist/src/vite-plugin.d.ts +2 -2
  34. package/package.json +8 -8
  35. package/dist/metadata-file-BWd04LhD.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,11 +1,11 @@
1
1
  /*!
2
2
  * name: screw-up
3
- * version: 1.31.0
3
+ * version: 1.33.0
4
4
  * description: Simply package metadata inserter on Vite plugin
5
5
  * author: Kouji Matsui (@kekyo@mi.kekyo.net)
6
6
  * license: MIT
7
7
  * repository.url: https://github.com/kekyo/screw-up.git
8
- * git.commit.hash: ebb41ebf06ebe1bec39a3770c70a62cb95b4b7d6
8
+ * git.commit.hash: be56ff1901b5073e1b0238a28b80d0c4f3c1e894
9
9
  */
10
10
  //#region \0rolldown/runtime.js
11
11
  var __create = Object.create;
@@ -31,13 +31,14 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
31
31
  }) : target, mod));
32
32
  //#endregion
33
33
  let fs_promises = require("fs/promises");
34
- fs_promises = __toESM(fs_promises);
34
+ fs_promises = __toESM(fs_promises, 1);
35
35
  let fs = require("fs");
36
36
  let path = require("path");
37
37
  require("glob");
38
38
  let isomorphic_git = require("isomorphic-git");
39
- isomorphic_git = __toESM(isomorphic_git);
39
+ isomorphic_git = __toESM(isomorphic_git, 1);
40
40
  let crypto$1 = require("crypto");
41
+ let zlib = require("zlib");
41
42
  //#region node_modules/async-primitives/dist/index.mjs
42
43
  /*!
43
44
  * name: async-primitives
@@ -222,8 +223,8 @@ createLogicalContext(Symbol("[root]"));
222
223
  //#endregion
223
224
  //#region src/generated/packageMetadata.ts
224
225
  var name = "screw-up";
225
- var version = "1.31.0";
226
- var git_commit_hash = "ebb41ebf06ebe1bec39a3770c70a62cb95b4b7d6";
226
+ var version = "1.33.0";
227
+ var git_commit_hash = "be56ff1901b5073e1b0238a28b80d0c4f3c1e894";
227
228
  //#endregion
228
229
  //#region node_modules/json5/dist/index.js
229
230
  var require_dist = /* @__PURE__ */ __commonJSMin(((exports, module) => {
@@ -1686,10 +1687,10 @@ var require_dayjs_min = /* @__PURE__ */ __commonJSMin(((exports, module) => {
1686
1687
  //#region src/internal.ts
1687
1688
  var import_dist = /* @__PURE__ */ __toESM(require_dist(), 1);
1688
1689
  var import_dayjs_min = /* @__PURE__ */ __toESM(require_dayjs_min(), 1);
1689
- var JSON5 = __resolveDefaultExport$3(import_dist.default, false);
1690
- var dayjs$1 = __resolveDefaultExport$3(import_dayjs_min.default, false);
1690
+ var JSON5 = __resolveDefaultExport$2(import_dist.default, false);
1691
+ var dayjs$1 = __resolveDefaultExport$2(import_dayjs_min.default, false);
1691
1692
  globalThis.__screwUpIsInCJS_db7919f73ec9 = true;
1692
- function __resolveDefaultExport$3(module, isESM) {
1693
+ function __resolveDefaultExport$2(module, isESM) {
1693
1694
  const __isInCJS = typeof globalThis !== "undefined" && globalThis.__screwUpIsInCJS_db7919f73ec9 === true;
1694
1695
  const maybe = module;
1695
1696
  const hasDefault = !!(maybe && typeof maybe === "object" && "default" in maybe);
@@ -1851,57 +1852,405 @@ var resolvePackageMetadata = async (projectRoot, fetchGitMetadata, alwaysOverrid
1851
1852
  };
1852
1853
  //#endregion
1853
1854
  //#region src/git-ref-utils.ts
1854
- var git$1 = __resolveDefaultExport$2(isomorphic_git.default, false);
1855
- globalThis.__screwUpIsInCJS_89cc61422477 = true;
1856
- function __resolveDefaultExport$2(module, isESM) {
1857
- const __isInCJS = typeof globalThis !== "undefined" && globalThis.__screwUpIsInCJS_89cc61422477 === true;
1858
- const maybe = module;
1859
- const hasDefault = !!(maybe && typeof maybe === "object" && "default" in maybe);
1860
- const unwrapNamespaceDefault = (value) => {
1861
- if (!value || typeof value !== "object") return value;
1862
- const inner = value;
1863
- if ((inner.__esModule === true || typeof Symbol !== "undefined" && inner[Symbol.toStringTag] === "Module") && "default" in inner) return inner.default;
1864
- return value;
1865
- };
1866
- const resolvedDefault = hasDefault ? unwrapNamespaceDefault(maybe.default) : void 0;
1867
- if (__isInCJS) return hasDefault ? resolvedDefault !== null && resolvedDefault !== void 0 ? resolvedDefault : module : module;
1868
- if (isESM) {
1869
- if (hasDefault) return resolvedDefault;
1870
- throw new Error("Default export not found.");
1871
- }
1872
- return hasDefault ? resolvedDefault !== null && resolvedDefault !== void 0 ? resolvedDefault : module : module;
1873
- }
1855
+ var PACK_TRAILER_SIZE = 20;
1856
+ var LOOSE_TAG_RESOLUTION_CONCURRENCY = 4;
1857
+ var PACKED_OBJECT_TYPE_BY_CODE = new Map([
1858
+ [1, "commit"],
1859
+ [2, "tree"],
1860
+ [3, "blob"],
1861
+ [4, "tag"],
1862
+ [6, "ofs-delta"],
1863
+ [7, "ref-delta"]
1864
+ ]);
1874
1865
  /**
1875
- * Resolve the actual Git directory for repositories, worktrees, and submodules.
1866
+ * Resolve Git directory paths for repositories, worktrees, and submodules.
1876
1867
  * @param repoPath - Repository path
1877
- * @returns The resolved Git directory path
1868
+ * @returns The resolved Git directory paths
1878
1869
  */
1879
- var getActualGitDir = async (repoPath) => {
1870
+ var resolveGitDirectoryPaths = async (repoPath) => {
1880
1871
  const gitDir = (0, path.join)(repoPath, ".git");
1881
1872
  const gitStat = await (0, fs_promises.stat)(gitDir).catch(() => null);
1882
- if (!(gitStat === null || gitStat === void 0 ? void 0 : gitStat.isFile())) return gitDir;
1883
- const match = (await (0, fs_promises.readFile)(gitDir, "utf-8")).match(/^gitdir:\s*(.+)$/m);
1884
- if (!match) return gitDir;
1885
- return (0, path.isAbsolute)(match[1]) ? match[1] : (0, path.join)(repoPath, match[1]);
1873
+ const resolvedGitDir = !(gitStat === null || gitStat === void 0 ? void 0 : gitStat.isFile()) ? gitDir : await (async () => {
1874
+ const match = (await (0, fs_promises.readFile)(gitDir, "utf-8")).match(/^gitdir:\s*(.+)$/m);
1875
+ if (!match) return gitDir;
1876
+ return (0, path.isAbsolute)(match[1]) ? match[1] : (0, path.join)(repoPath, match[1]);
1877
+ })();
1878
+ return {
1879
+ gitDir: resolvedGitDir,
1880
+ commonGitDir: await (0, fs_promises.readFile)((0, path.join)(resolvedGitDir, "commondir"), "utf-8").then((content) => {
1881
+ const commondir = content.trim();
1882
+ if (!commondir) return resolvedGitDir;
1883
+ return (0, path.isAbsolute)(commondir) ? commondir : (0, path.join)(resolvedGitDir, commondir);
1884
+ }).catch((error) => {
1885
+ if ((error === null || error === void 0 ? void 0 : error.code) !== "ENOENT") throw error;
1886
+ return resolvedGitDir;
1887
+ })
1888
+ };
1886
1889
  };
1887
1890
  /**
1888
- * Resolve a tag object OID to the commit OID it ultimately points to.
1889
- * Lightweight tags are returned unchanged.
1891
+ * Resolve the worktree-specific Git directory.
1890
1892
  * @param repoPath - Repository path
1891
- * @param tagOid - Tag or commit OID
1892
- * @returns Commit hash this tag points to
1893
+ * @returns The resolved worktree-specific Git directory path
1893
1894
  */
1894
- var resolveTagOidToCommit = async (repoPath, tagOid) => {
1895
+ var getActualGitDir = async (repoPath) => {
1896
+ return (await resolveGitDirectoryPaths(repoPath)).gitDir;
1897
+ };
1898
+ /**
1899
+ * Resolve the common Git directory used for refs and objects.
1900
+ * @param repoPath - Repository path
1901
+ * @returns The resolved common Git directory path
1902
+ */
1903
+ var getCommonGitDir = async (repoPath) => {
1904
+ return (await resolveGitDirectoryPaths(repoPath)).commonGitDir;
1905
+ };
1906
+ var readFixedRange = async (fileHandle, offset, length) => {
1907
+ const buffer = Buffer.alloc(length);
1908
+ const { bytesRead } = await fileHandle.read(buffer, 0, length, offset);
1909
+ if (bytesRead !== length) throw new Error(`Unexpected EOF while reading pack entry at offset ${offset} (expected ${length}, got ${bytesRead})`);
1910
+ return buffer;
1911
+ };
1912
+ var readLooseObject = async (gitDir, oid) => {
1895
1913
  try {
1896
- var _tagObject$tag;
1897
- const tagObject = await git$1.readTag({
1898
- fs: fs_promises.default,
1899
- dir: repoPath,
1900
- oid: tagOid
1914
+ const wrapped = (0, zlib.inflateSync)(await (0, fs_promises.readFile)((0, path.join)(gitDir, "objects", oid.slice(0, 2), oid.slice(2))));
1915
+ const headerEnd = wrapped.indexOf(0);
1916
+ if (headerEnd < 0) throw new Error(`Invalid loose object header: ${oid}`);
1917
+ const header = wrapped.subarray(0, headerEnd).toString("utf-8");
1918
+ const match = header.match(/^(commit|tree|blob|tag) (\d+)$/);
1919
+ if (!match) throw new Error(`Unsupported loose object header: ${header}`);
1920
+ const content = wrapped.subarray(headerEnd + 1);
1921
+ const expectedSize = Number(match[2]);
1922
+ if (content.length !== expectedSize) throw new Error(`Loose object size mismatch: ${oid} (expected ${expectedSize}, got ${content.length})`);
1923
+ return {
1924
+ oid,
1925
+ type: match[1],
1926
+ content
1927
+ };
1928
+ } catch (error) {
1929
+ if (error.code === "ENOENT") return null;
1930
+ throw error;
1931
+ }
1932
+ };
1933
+ var readLargePackOffset = (idxBuffer, largeOffsetsStart, largeOffsetIndex) => {
1934
+ const offset = Number(idxBuffer.readBigUInt64BE(largeOffsetsStart + largeOffsetIndex * 8));
1935
+ if (!Number.isSafeInteger(offset)) throw new Error(`Pack offset exceeds safe integer range: ${offset}`);
1936
+ return offset;
1937
+ };
1938
+ var loadPackIndex = async (idxPath) => {
1939
+ const packPath = idxPath.replace(/\.idx$/, ".pack");
1940
+ const [idxBuffer, packStat, fileHandle] = await Promise.all([
1941
+ (0, fs_promises.readFile)(idxPath),
1942
+ (0, fs_promises.stat)(packPath),
1943
+ (0, fs_promises.open)(packPath, "r")
1944
+ ]);
1945
+ if (idxBuffer.readUInt32BE(0) !== 4285812579) throw new Error(`Unsupported pack index signature: ${idxPath}`);
1946
+ if (idxBuffer.readUInt32BE(4) !== 2) throw new Error(`Unsupported pack index version: ${idxPath}`);
1947
+ const objectCount = idxBuffer.readUInt32BE(1028);
1948
+ const oidStart = 1032;
1949
+ const offsetStart = oidStart + objectCount * 20 + objectCount * 4;
1950
+ const largeOffsetStart = offsetStart + objectCount * 4;
1951
+ const objectByOid = /* @__PURE__ */ new Map();
1952
+ const objectByOffset = /* @__PURE__ */ new Map();
1953
+ const sortedObjects = [];
1954
+ const packIndex = {
1955
+ fileHandle,
1956
+ objectByOid,
1957
+ objectByOffset
1958
+ };
1959
+ for (let index = 0; index < objectCount; index++) {
1960
+ const oidOffset = oidStart + index * 20;
1961
+ const oid = idxBuffer.subarray(oidOffset, oidOffset + 20).toString("hex");
1962
+ const rawOffset = idxBuffer.readUInt32BE(offsetStart + index * 4);
1963
+ const offset = (rawOffset & 2147483648) === 0 ? rawOffset : readLargePackOffset(idxBuffer, largeOffsetStart, rawOffset & 2147483647);
1964
+ sortedObjects.push({
1965
+ oid,
1966
+ offset
1967
+ });
1968
+ }
1969
+ sortedObjects.sort((left, right) => left.offset - right.offset);
1970
+ const packEndOffset = packStat.size - PACK_TRAILER_SIZE;
1971
+ for (let index = 0; index < sortedObjects.length; index++) {
1972
+ var _sortedObjects$offset, _sortedObjects;
1973
+ const currentObject = sortedObjects[index];
1974
+ const nextOffset = (_sortedObjects$offset = (_sortedObjects = sortedObjects[index + 1]) === null || _sortedObjects === void 0 ? void 0 : _sortedObjects.offset) !== null && _sortedObjects$offset !== void 0 ? _sortedObjects$offset : packEndOffset;
1975
+ const location = {
1976
+ oid: currentObject.oid,
1977
+ offset: currentObject.offset,
1978
+ nextOffset,
1979
+ packIndex
1980
+ };
1981
+ objectByOid.set(currentObject.oid, location);
1982
+ objectByOffset.set(currentObject.offset, location);
1983
+ }
1984
+ return packIndex;
1985
+ };
1986
+ var loadPackStore = async (gitDir) => {
1987
+ try {
1988
+ const packDir = (0, path.join)(gitDir, "objects", "pack");
1989
+ const idxPaths = (await (0, fs_promises.readdir)(packDir)).filter((entryName) => entryName.endsWith(".idx")).map((entryName) => (0, path.join)(packDir, entryName));
1990
+ const packs = await Promise.all(idxPaths.map(loadPackIndex));
1991
+ const objectByOid = /* @__PURE__ */ new Map();
1992
+ for (const pack of packs) for (const [oid, location] of pack.objectByOid.entries()) objectByOid.set(oid, location);
1993
+ return {
1994
+ packs,
1995
+ objectByOid
1996
+ };
1997
+ } catch (error) {
1998
+ if (error.code === "ENOENT") return {
1999
+ packs: [],
2000
+ objectByOid: /* @__PURE__ */ new Map()
2001
+ };
2002
+ throw error;
2003
+ }
2004
+ };
2005
+ var decodeOfsDeltaDistance = (buffer, startOffset) => {
2006
+ let cursor = startOffset;
2007
+ let byte = buffer[cursor++];
2008
+ let distance = byte & 127;
2009
+ while (byte & 128) {
2010
+ byte = buffer[cursor++];
2011
+ distance = distance + 1 << 7 | byte & 127;
2012
+ }
2013
+ return {
2014
+ distance,
2015
+ nextOffset: cursor
2016
+ };
2017
+ };
2018
+ var parsePackedEntryHeader = (entryBuffer, objectOffset) => {
2019
+ let cursor = 0;
2020
+ let byte = entryBuffer[cursor++];
2021
+ const packedType = PACKED_OBJECT_TYPE_BY_CODE.get(byte >> 4 & 7);
2022
+ if (!packedType) throw new Error(`Unsupported packed object type at offset ${objectOffset}`);
2023
+ let declaredSize = byte & 15;
2024
+ let shift = 4;
2025
+ while (byte & 128) {
2026
+ byte = entryBuffer[cursor++];
2027
+ declaredSize |= (byte & 127) << shift;
2028
+ shift += 7;
2029
+ }
2030
+ let baseOffset;
2031
+ let baseOid;
2032
+ if (packedType === "ofs-delta") {
2033
+ const decoded = decodeOfsDeltaDistance(entryBuffer, cursor);
2034
+ cursor = decoded.nextOffset;
2035
+ baseOffset = objectOffset - decoded.distance;
2036
+ } else if (packedType === "ref-delta") {
2037
+ baseOid = entryBuffer.subarray(cursor, cursor + 20).toString("hex");
2038
+ cursor += 20;
2039
+ }
2040
+ return {
2041
+ packedType,
2042
+ declaredSize,
2043
+ headerLength: cursor,
2044
+ baseOffset,
2045
+ baseOid
2046
+ };
2047
+ };
2048
+ var readDeltaSize = (buffer, startOffset) => {
2049
+ let cursor = startOffset;
2050
+ let size = 0;
2051
+ let shift = 0;
2052
+ while (cursor < buffer.length) {
2053
+ const byte = buffer[cursor++];
2054
+ size |= (byte & 127) << shift;
2055
+ if ((byte & 128) === 0) return {
2056
+ size,
2057
+ nextOffset: cursor
2058
+ };
2059
+ shift += 7;
2060
+ }
2061
+ throw new Error("Invalid git delta size encoding");
2062
+ };
2063
+ var applyGitDelta = (baseContent, deltaContent) => {
2064
+ const baseSizeInfo = readDeltaSize(deltaContent, 0);
2065
+ if (baseSizeInfo.size !== baseContent.length) throw new Error(`Git delta base size mismatch: expected ${baseSizeInfo.size}, got ${baseContent.length}`);
2066
+ const targetSizeInfo = readDeltaSize(deltaContent, baseSizeInfo.nextOffset);
2067
+ const result = Buffer.alloc(targetSizeInfo.size);
2068
+ let deltaOffset = targetSizeInfo.nextOffset;
2069
+ let resultOffset = 0;
2070
+ while (deltaOffset < deltaContent.length) {
2071
+ const opcode = deltaContent[deltaOffset++];
2072
+ if ((opcode & 128) !== 0) {
2073
+ let copyOffset = 0;
2074
+ let copySize = 0;
2075
+ if (opcode & 1) copyOffset |= deltaContent[deltaOffset++];
2076
+ if (opcode & 2) copyOffset |= deltaContent[deltaOffset++] << 8;
2077
+ if (opcode & 4) copyOffset |= deltaContent[deltaOffset++] << 16;
2078
+ if (opcode & 8) copyOffset |= deltaContent[deltaOffset++] << 24;
2079
+ if (opcode & 16) copySize |= deltaContent[deltaOffset++];
2080
+ if (opcode & 32) copySize |= deltaContent[deltaOffset++] << 8;
2081
+ if (opcode & 64) copySize |= deltaContent[deltaOffset++] << 16;
2082
+ if (copySize === 0) copySize = 65536;
2083
+ baseContent.copy(result, resultOffset, copyOffset, copyOffset + copySize);
2084
+ resultOffset += copySize;
2085
+ continue;
2086
+ }
2087
+ if (opcode === 0) throw new Error("Invalid git delta opcode");
2088
+ deltaContent.copy(result, resultOffset, deltaOffset, deltaOffset + opcode);
2089
+ deltaOffset += opcode;
2090
+ resultOffset += opcode;
2091
+ }
2092
+ if (resultOffset !== result.length) throw new Error(`Git delta size mismatch: expected ${result.length}, got ${resultOffset}`);
2093
+ return result;
2094
+ };
2095
+ var inflatePackedObject = (compressedContent) => Buffer.from((0, zlib.inflateSync)(compressedContent));
2096
+ var parseTagTargetOid = (tagContent) => {
2097
+ const firstLineEnd = tagContent.indexOf(10);
2098
+ const firstLine = firstLineEnd >= 0 ? tagContent.subarray(0, firstLineEnd).toString("utf-8") : tagContent.toString("utf-8");
2099
+ const match = firstLine.match(/^object ([0-9a-f]{40})$/);
2100
+ if (!match) throw new Error(`Invalid annotated tag payload: ${firstLine}`);
2101
+ return match[1];
2102
+ };
2103
+ var parseTreeEntries = (treeContent) => {
2104
+ const entries = [];
2105
+ let offset = 0;
2106
+ while (offset < treeContent.length) {
2107
+ const modeEnd = treeContent.indexOf(32, offset);
2108
+ if (modeEnd < 0) throw new Error("Invalid tree entry mode");
2109
+ const nameEnd = treeContent.indexOf(0, modeEnd + 1);
2110
+ if (nameEnd < 0 || nameEnd + 21 > treeContent.length) throw new Error("Invalid tree entry name");
2111
+ entries.push({
2112
+ mode: treeContent.subarray(offset, modeEnd).toString("utf-8"),
2113
+ name: treeContent.subarray(modeEnd + 1, nameEnd).toString("utf-8"),
2114
+ oid: treeContent.subarray(nameEnd + 1, nameEnd + 21).toString("hex")
2115
+ });
2116
+ offset = nameEnd + 21;
2117
+ }
2118
+ return entries;
2119
+ };
2120
+ var createGitObjectResolver = async (repoPath) => {
2121
+ const commonGitDir = await getCommonGitDir(repoPath);
2122
+ const resolvedObjects = /* @__PURE__ */ new Map();
2123
+ let packStorePromise;
2124
+ const getPackStore = async () => {
2125
+ if (!packStorePromise) packStorePromise = loadPackStore(commonGitDir);
2126
+ return packStorePromise;
2127
+ };
2128
+ const readPackedObject = async (location) => {
2129
+ var _location$packIndex$o, _location$packIndex$o2, _header$baseOid;
2130
+ const entryLength = location.nextOffset - location.offset;
2131
+ const entryBuffer = await readFixedRange(location.packIndex.fileHandle, location.offset, entryLength);
2132
+ const header = parsePackedEntryHeader(entryBuffer, location.offset);
2133
+ const compressedContent = entryBuffer.subarray(header.headerLength);
2134
+ if (header.packedType === "commit" || header.packedType === "tree" || header.packedType === "blob" || header.packedType === "tag") {
2135
+ const content = inflatePackedObject(compressedContent);
2136
+ if (content.length !== header.declaredSize) throw new Error(`Packed object size mismatch: ${location.oid} (expected ${header.declaredSize}, got ${content.length})`);
2137
+ return {
2138
+ oid: location.oid,
2139
+ type: header.packedType,
2140
+ content
2141
+ };
2142
+ }
2143
+ const deltaContent = inflatePackedObject(compressedContent);
2144
+ if (deltaContent.length !== header.declaredSize) throw new Error(`Packed delta size mismatch: ${location.oid} (expected ${header.declaredSize}, got ${deltaContent.length})`);
2145
+ const baseObject = header.packedType === "ofs-delta" ? await readObject((_location$packIndex$o = (_location$packIndex$o2 = location.packIndex.objectByOffset.get(header.baseOffset)) === null || _location$packIndex$o2 === void 0 ? void 0 : _location$packIndex$o2.oid) !== null && _location$packIndex$o !== void 0 ? _location$packIndex$o : (() => {
2146
+ throw new Error(`Missing ofs-delta base object at offset ${header.baseOffset}`);
2147
+ })()) : await readObject((_header$baseOid = header.baseOid) !== null && _header$baseOid !== void 0 ? _header$baseOid : (() => {
2148
+ throw new Error("Missing ref-delta base object id");
2149
+ })());
2150
+ const content = applyGitDelta(baseObject.content, deltaContent);
2151
+ return {
2152
+ oid: location.oid,
2153
+ type: baseObject.type,
2154
+ content
2155
+ };
2156
+ };
2157
+ const readObject = async (oid) => {
2158
+ const cachedObject = resolvedObjects.get(oid);
2159
+ if (cachedObject) return cachedObject;
2160
+ const objectPromise = (async () => {
2161
+ const looseObject = await readLooseObject(commonGitDir, oid);
2162
+ if (looseObject) return looseObject;
2163
+ const location = (await getPackStore()).objectByOid.get(oid);
2164
+ if (!location) throw new Error(`Git object not found: ${oid}`);
2165
+ return readPackedObject(location);
2166
+ })();
2167
+ resolvedObjects.set(oid, objectPromise);
2168
+ try {
2169
+ return await objectPromise;
2170
+ } catch (error) {
2171
+ resolvedObjects.delete(oid);
2172
+ throw error;
2173
+ }
2174
+ };
2175
+ return {
2176
+ close: async () => {
2177
+ if (!packStorePromise) return;
2178
+ const packStore = await packStorePromise;
2179
+ await Promise.allSettled(packStore.packs.map(async (pack) => {
2180
+ await pack.fileHandle.close();
2181
+ }));
2182
+ },
2183
+ readObject,
2184
+ resolveTagOidToCommit: async (tagOid) => {
2185
+ let currentOid = tagOid;
2186
+ const visitedOids = /* @__PURE__ */ new Set();
2187
+ while (true) {
2188
+ if (visitedOids.has(currentOid)) throw new Error(`Detected cyclic tag reference: ${currentOid}`);
2189
+ visitedOids.add(currentOid);
2190
+ const object = await readObject(currentOid);
2191
+ if (object.type !== "tag") return currentOid;
2192
+ currentOid = parseTagTargetOid(object.content);
2193
+ }
2194
+ }
2195
+ };
2196
+ };
2197
+ var runWithConcurrency = async (values, concurrency, worker) => {
2198
+ let nextIndex = 0;
2199
+ const runWorker = async () => {
2200
+ while (nextIndex < values.length) {
2201
+ const currentIndex = nextIndex;
2202
+ nextIndex += 1;
2203
+ await worker(values[currentIndex]);
2204
+ }
2205
+ };
2206
+ await Promise.all(Array.from({ length: Math.min(concurrency, Math.max(values.length, 1)) }, () => runWorker()));
2207
+ };
2208
+ /**
2209
+ * Resolve multiple tag object OIDs to their peeled commit OIDs.
2210
+ * @param repoPath - Repository path
2211
+ * @param tagOids - Tag or commit OIDs
2212
+ * @returns Map of tag object OID to peeled commit OID
2213
+ */
2214
+ var resolveTagOidsToCommits = async (repoPath, tagOids) => {
2215
+ const resolver = await createGitObjectResolver(repoPath);
2216
+ const result = /* @__PURE__ */ new Map();
2217
+ const uniqueTagOids = Array.from(new Set(tagOids));
2218
+ try {
2219
+ await runWithConcurrency(uniqueTagOids, LOOSE_TAG_RESOLUTION_CONCURRENCY, async (tagOid) => {
2220
+ result.set(tagOid, await resolver.resolveTagOidToCommit(tagOid));
1901
2221
  });
1902
- if (tagObject === null || tagObject === void 0 || (_tagObject$tag = tagObject.tag) === null || _tagObject$tag === void 0 ? void 0 : _tagObject$tag.object) return tagObject.tag.object;
1903
- } catch (_unused) {}
1904
- return tagOid;
2222
+ } finally {
2223
+ await resolver.close();
2224
+ }
2225
+ return result;
2226
+ };
2227
+ var collectTreeFiles = async (resolver, treeOid, prefix, files) => {
2228
+ const treeObject = await resolver.readObject(treeOid);
2229
+ if (treeObject.type !== "tree") throw new Error(`Expected tree object: ${treeOid}`);
2230
+ for (const entry of parseTreeEntries(treeObject.content)) {
2231
+ const path$7 = prefix ? `${prefix}/${entry.name}` : entry.name;
2232
+ if (entry.mode === "40000") {
2233
+ await collectTreeFiles(resolver, entry.oid, path$7, files);
2234
+ continue;
2235
+ }
2236
+ if (entry.mode !== "160000") files.set(path$7, entry.oid);
2237
+ }
2238
+ };
2239
+ /**
2240
+ * Collect all tracked file blob OIDs under the specified tree.
2241
+ * @param repoPath - Repository path
2242
+ * @param treeOid - Tree object OID
2243
+ * @returns Map of repository-relative file path to blob OID
2244
+ */
2245
+ var listTreeFiles = async (repoPath, treeOid) => {
2246
+ const resolver = await createGitObjectResolver(repoPath);
2247
+ const files = /* @__PURE__ */ new Map();
2248
+ try {
2249
+ await collectTreeFiles(resolver, treeOid, "", files);
2250
+ } finally {
2251
+ await resolver.close();
2252
+ }
2253
+ return files;
1905
2254
  };
1906
2255
  //#endregion
1907
2256
  //#region src/fast-tags.ts
@@ -1954,8 +2303,8 @@ var readLooseTags = async (refsTagsPath) => {
1954
2303
  * @returns Array of all tag names
1955
2304
  */
1956
2305
  var listTagsFast = async (repoPath) => {
1957
- const actualGitDir = await getActualGitDir(repoPath);
1958
- const [packedTags, looseTags] = await Promise.all([parsePackedRefs((0, path.join)(actualGitDir, "packed-refs")), readLooseTags((0, path.join)(actualGitDir, "refs", "tags"))]);
2306
+ const commonGitDir = await getCommonGitDir(repoPath);
2307
+ const [packedTags, looseTags] = await Promise.all([parsePackedRefs((0, path.join)(commonGitDir, "packed-refs")), readLooseTags((0, path.join)(commonGitDir, "refs", "tags"))]);
1959
2308
  const allTags = new Set([...packedTags, ...looseTags]);
1960
2309
  return Array.from(allTags).sort();
1961
2310
  };
@@ -1968,11 +2317,11 @@ var listTagsFast = async (repoPath) => {
1968
2317
  var resolveTagsBatchWithCommit = async (repoPath, tagNames, logger) => {
1969
2318
  const startTime = Date.now();
1970
2319
  const result = /* @__PURE__ */ new Map();
1971
- const actualGitDir = await getActualGitDir(repoPath);
2320
+ const commonGitDir = await getCommonGitDir(repoPath);
1972
2321
  const tagSet = new Set(tagNames);
1973
2322
  const packedRefsStart = Date.now();
1974
2323
  try {
1975
- const lines = (await (0, fs_promises.readFile)((0, path.join)(actualGitDir, "packed-refs"), "utf-8")).split("\n");
2324
+ const lines = (await (0, fs_promises.readFile)((0, path.join)(commonGitDir, "packed-refs"), "utf-8")).split("\n");
1976
2325
  for (let i = 0; i < lines.length; i++) {
1977
2326
  const line = lines[i];
1978
2327
  if (line.startsWith("#") || !line.trim()) continue;
@@ -1995,19 +2344,28 @@ var resolveTagsBatchWithCommit = async (repoPath, tagNames, logger) => {
1995
2344
  const remainingTags = tagNames.filter((tag) => !result.has(tag));
1996
2345
  if (remainingTags.length > 0) {
1997
2346
  const looseRefsStart = Date.now();
1998
- await Promise.all(remainingTags.map(async (tagName) => {
1999
- const looseRefPath = (0, path.join)(actualGitDir, "refs", "tags", tagName);
2347
+ const looseTagEntries = (await Promise.all(remainingTags.map(async (tagName) => {
2348
+ const looseRefPath = (0, path.join)(commonGitDir, "refs", "tags", tagName);
2000
2349
  try {
2001
- const oid = (await (0, fs_promises.readFile)(looseRefPath, "utf-8")).trim();
2002
- const commitOid = await resolveTagOidToCommit(repoPath, oid);
2350
+ return {
2351
+ tagName,
2352
+ oid: (await (0, fs_promises.readFile)(looseRefPath, "utf-8")).trim()
2353
+ };
2354
+ } catch (error) {
2355
+ if (error.code !== "ENOENT") throw error;
2356
+ return;
2357
+ }
2358
+ }))).filter((entry) => entry !== void 0);
2359
+ if (looseTagEntries.length > 0) {
2360
+ const commitOids = await resolveTagOidsToCommits(repoPath, looseTagEntries.map((entry) => entry.oid));
2361
+ for (const { tagName, oid } of looseTagEntries) {
2362
+ var _commitOids$get;
2003
2363
  result.set(tagName, {
2004
2364
  oid,
2005
- commitOid
2365
+ commitOid: (_commitOids$get = commitOids.get(oid)) !== null && _commitOids$get !== void 0 ? _commitOids$get : oid
2006
2366
  });
2007
- } catch (error) {
2008
- if (error.code !== "ENOENT") throw error;
2009
2367
  }
2010
- }));
2368
+ }
2011
2369
  logger.debug(`[fast-tags] read loose refs: ${Date.now() - looseRefsStart}ms`);
2012
2370
  }
2013
2371
  const totalTime = Date.now() - startTime;
@@ -2203,16 +2561,26 @@ var formatVersion = (version) => {
2203
2561
  return result;
2204
2562
  };
2205
2563
  /**
2206
- * Get a commit by hash
2564
+ * Build a Git read context that can operate correctly inside worktrees.
2207
2565
  * @param repositoryPath - Local Git repository directory
2566
+ * @returns The resolved Git read context
2567
+ */
2568
+ var createGitReadContext = async (repositoryPath) => ({
2569
+ dir: repositoryPath,
2570
+ gitdir: await getCommonGitDir(repositoryPath)
2571
+ });
2572
+ /**
2573
+ * Get a commit by hash
2574
+ * @param context - Git read context
2208
2575
  * @param hash - The hash of the commit
2209
2576
  * @returns The commit or undefined if the commit is not found
2210
2577
  */
2211
- var getCommit = async (repositoryPath, hash) => {
2578
+ var getCommit = async (context, hash) => {
2212
2579
  try {
2213
2580
  const commit = await isomorphic_git.readCommit({
2214
2581
  fs: fs_promises.default,
2215
- dir: repositoryPath,
2582
+ dir: context.dir,
2583
+ gitdir: context.gitdir,
2216
2584
  oid: hash
2217
2585
  });
2218
2586
  return {
@@ -2220,7 +2588,8 @@ var getCommit = async (repositoryPath, hash) => {
2220
2588
  shortHash: commit.oid.substring(0, 7),
2221
2589
  date: (/* @__PURE__ */ new Date(commit.commit.author.timestamp * 1e3)).toISOString(),
2222
2590
  message: commit.commit.message.trim(),
2223
- parents: commit.commit.parent || []
2591
+ parents: commit.commit.parent || [],
2592
+ tree: commit.commit.tree
2224
2593
  };
2225
2594
  } catch (_unused) {
2226
2595
  return;
@@ -2228,19 +2597,20 @@ var getCommit = async (repositoryPath, hash) => {
2228
2597
  };
2229
2598
  /**
2230
2599
  * Get the current commit
2231
- * @param repositoryPath - Local Git repository directory
2600
+ * @param context - Git read context
2232
2601
  * @returns The current commit or undefined if the current commit is not found
2233
2602
  */
2234
- var getCurrentCommit = async (repositoryPath) => {
2603
+ var getCurrentCommit = async (context) => {
2235
2604
  try {
2236
2605
  const currentOid = await isomorphic_git.resolveRef({
2237
2606
  fs: fs_promises.default,
2238
- dir: repositoryPath,
2607
+ dir: context.dir,
2239
2608
  ref: "HEAD"
2240
2609
  });
2241
2610
  const commit = await isomorphic_git.readCommit({
2242
2611
  fs: fs_promises.default,
2243
- dir: repositoryPath,
2612
+ dir: context.dir,
2613
+ gitdir: context.gitdir,
2244
2614
  oid: currentOid
2245
2615
  });
2246
2616
  return {
@@ -2248,7 +2618,8 @@ var getCurrentCommit = async (repositoryPath) => {
2248
2618
  shortHash: commit.oid.substring(0, 7),
2249
2619
  date: (/* @__PURE__ */ new Date(commit.commit.author.timestamp * 1e3)).toISOString(),
2250
2620
  message: commit.commit.message.trim(),
2251
- parents: commit.commit.parent || []
2621
+ parents: commit.commit.parent || [],
2622
+ tree: commit.commit.tree
2252
2623
  };
2253
2624
  } catch (_unused2) {
2254
2625
  return;
@@ -2265,21 +2636,23 @@ var getRelatedTagsFromMap = (commitToTags, commitHash) => {
2265
2636
  };
2266
2637
  /**
2267
2638
  * Get the commit related branch name.
2268
- * @param repositoryPath - Local Git repository directory
2639
+ * @param context - Git read context
2269
2640
  * @param commitHash - The hash of the commit
2270
2641
  * @returns The commit related branch name or undefined if not found
2271
2642
  */
2272
- var getRelatedBranches = async (repositoryPath, commitHash) => {
2643
+ var getRelatedBranches = async (context, commitHash) => {
2273
2644
  try {
2274
2645
  const branches = await isomorphic_git.listBranches({
2275
2646
  fs: fs_promises.default,
2276
- dir: repositoryPath
2647
+ dir: context.dir,
2648
+ gitdir: context.gitdir
2277
2649
  });
2278
2650
  const relatedBranches = [];
2279
2651
  for (const branch of branches) try {
2280
2652
  if (await isomorphic_git.resolveRef({
2281
2653
  fs: fs_promises.default,
2282
- dir: repositoryPath,
2654
+ dir: context.dir,
2655
+ gitdir: context.gitdir,
2283
2656
  ref: branch
2284
2657
  }) === commitHash) relatedBranches.push(branch);
2285
2658
  } catch (_unused3) {}
@@ -2288,94 +2661,133 @@ var getRelatedBranches = async (repositoryPath, commitHash) => {
2288
2661
  return [];
2289
2662
  }
2290
2663
  };
2291
- /**
2292
- * Check if the repository has modified files (following RelaxVersioner logic).
2293
- * Checks for staged files, unstaged files, and untracked files (respecting .gitignore).
2294
- * @param repositoryPath - Local Git repository directory
2295
- * @returns Modified files
2296
- */
2297
- var isModifiedFile = ([, head, workdir, stage]) => {
2298
- return workdir === 2 || stage === 2 || stage === 3 || head === 1 && workdir === 0 || head === 0 && workdir === 1;
2299
- };
2300
- var getStatusRow = async (filepath, entries) => {
2301
- const [head, workdir, stage] = entries;
2302
- const [headType, workdirType, stageType] = await Promise.all([
2303
- head ? head.type() : void 0,
2304
- workdir ? workdir.type() : void 0,
2305
- stage ? stage.type() : void 0
2306
- ]);
2307
- const isBlob = [
2308
- headType,
2309
- workdirType,
2310
- stageType
2311
- ].includes("blob");
2312
- if ((headType === "tree" || headType === "special") && !isBlob) return;
2313
- if (headType === "commit") return;
2314
- if ((workdirType === "tree" || workdirType === "special") && !isBlob) return;
2315
- if (stageType === "commit") return;
2316
- if ((stageType === "tree" || stageType === "special") && !isBlob) return;
2317
- const headOid = headType === "blob" ? await head.oid() : void 0;
2318
- const stageOid = stageType === "blob" ? await stage.oid() : void 0;
2319
- let workdirOid;
2320
- if (headType !== "blob" && workdirType === "blob" && stageType !== "blob") workdirOid = "42";
2321
- else if (workdirType === "blob") workdirOid = await workdir.oid();
2322
- const entry = [
2323
- void 0,
2324
- headOid,
2325
- workdirOid,
2326
- stageOid
2327
- ];
2328
- const statusValues = entry.map((value) => entry.indexOf(value));
2329
- return [
2330
- filepath,
2331
- statusValues[1],
2332
- statusValues[2],
2333
- statusValues[3]
2334
- ];
2335
- };
2336
- var reduceModifiedFiles = async (parent, children) => {
2337
- const modifiedFiles = parent ? [parent] : [];
2338
- for (const child of children) modifiedFiles.push(...child);
2339
- return modifiedFiles;
2340
- };
2341
- var iterateSequentially = async (walk, children) => {
2342
- const results = [];
2343
- for (const child of children) results.push(await walk(child));
2344
- return results;
2345
- };
2346
- var getModifiedFiles = async (repositoryPath) => {
2664
+ var parseGitIndex = async (gitDir) => {
2347
2665
  try {
2348
- return await isomorphic_git.walk({
2349
- fs: fs_promises.default,
2350
- dir: repositoryPath,
2351
- trees: [
2352
- isomorphic_git.TREE({ ref: "HEAD" }),
2353
- isomorphic_git.WORKDIR(),
2354
- isomorphic_git.STAGE()
2355
- ],
2356
- map: async (filepath, entries) => {
2357
- const [head, workdir, stage] = entries;
2358
- if (!head && !stage && workdir) {
2359
- if (await isomorphic_git.isIgnored({
2360
- fs: fs_promises.default,
2361
- dir: repositoryPath,
2362
- filepath
2363
- })) return null;
2666
+ const buffer = await fs_promises.default.readFile((0, path.join)(gitDir, "index"));
2667
+ if (buffer.subarray(0, 4).toString("ascii") !== "DIRC") throw new Error("Unsupported git index signature");
2668
+ const version = buffer.readUInt32BE(4);
2669
+ if (version !== 2 && version !== 3) throw new Error(`Unsupported git index version: ${version}`);
2670
+ const entryCount = buffer.readUInt32BE(8);
2671
+ let offset = 12;
2672
+ const entries = /* @__PURE__ */ new Map();
2673
+ for (let index = 0; index < entryCount; index++) {
2674
+ const entryStart = offset;
2675
+ const size = buffer.readUInt32BE(entryStart + 36);
2676
+ const oid = buffer.subarray(entryStart + 40, entryStart + 60).toString("hex");
2677
+ const flags = buffer.readUInt16BE(entryStart + 60);
2678
+ const stage = flags >> 12 & 3;
2679
+ offset = entryStart + 62;
2680
+ if (version >= 3 && (flags & 16384) !== 0) offset += 2;
2681
+ const pathEnd = buffer.indexOf(0, offset);
2682
+ if (pathEnd < 0) throw new Error("Invalid git index path entry");
2683
+ const path$3 = buffer.subarray(offset, pathEnd).toString("utf-8");
2684
+ offset = pathEnd + 1;
2685
+ while ((offset - entryStart) % 8 !== 0) offset += 1;
2686
+ entries.set(path$3, {
2687
+ path: path$3,
2688
+ oid,
2689
+ size,
2690
+ stage
2691
+ });
2692
+ }
2693
+ return entries;
2694
+ } catch (error) {
2695
+ if (error.code === "ENOENT") return /* @__PURE__ */ new Map();
2696
+ throw error;
2697
+ }
2698
+ };
2699
+ var listTrackedDirectories = (indexEntries) => {
2700
+ const directories = new Set([""]);
2701
+ for (const path$4 of indexEntries.keys()) {
2702
+ const segments = path$4.split("/");
2703
+ let currentPath = "";
2704
+ for (let index = 0; index < segments.length - 1; index++) {
2705
+ currentPath = currentPath ? `${currentPath}/${segments[index]}` : segments[index];
2706
+ directories.add(currentPath);
2707
+ }
2708
+ }
2709
+ return directories;
2710
+ };
2711
+ var listWorkingDirectoryFiles = async (repositoryPath, trackedDirectories, relativePath = "") => {
2712
+ const directoryPath = relativePath ? (0, path.join)(repositoryPath, relativePath) : repositoryPath;
2713
+ const entries = await fs_promises.default.readdir(directoryPath, { withFileTypes: true });
2714
+ const files = [];
2715
+ for (const entry of entries) {
2716
+ if (entry.name === ".git") continue;
2717
+ const entryPath = relativePath ? `${relativePath}/${entry.name}` : entry.name;
2718
+ if (entry.isDirectory()) {
2719
+ if (!trackedDirectories.has(entryPath)) {
2720
+ if (await isomorphic_git.isIgnored({
2721
+ fs: fs_promises.default,
2722
+ dir: repositoryPath,
2723
+ filepath: entryPath
2724
+ })) continue;
2725
+ }
2726
+ files.push(...await listWorkingDirectoryFiles(repositoryPath, trackedDirectories, entryPath));
2727
+ continue;
2728
+ }
2729
+ if (entry.isFile() || entry.isSymbolicLink()) files.push(entryPath);
2730
+ }
2731
+ return files;
2732
+ };
2733
+ var calculateBlobOid = async (filePath) => {
2734
+ const content = await fs_promises.default.readFile(filePath);
2735
+ return (0, crypto$1.createHash)("sha1").update(`blob ${content.length}\0`).update(content).digest("hex");
2736
+ };
2737
+ var getModifiedFiles = async (repositoryPath, headTreeOid) => {
2738
+ try {
2739
+ const gitDir = await getActualGitDir(repositoryPath);
2740
+ const [headFiles, indexEntries] = await Promise.all([listTreeFiles(repositoryPath, headTreeOid), parseGitIndex(gitDir)]);
2741
+ const workdirFiles = await listWorkingDirectoryFiles(repositoryPath, listTrackedDirectories(indexEntries));
2742
+ const modifiedFiles = /* @__PURE__ */ new Map();
2743
+ const rememberModifiedFile = (path$5, reason) => {
2744
+ if (!modifiedFiles.has(path$5)) modifiedFiles.set(path$5, {
2745
+ path: path$5,
2746
+ reason
2747
+ });
2748
+ };
2749
+ for (const [path$6, headOid] of headFiles.entries()) {
2750
+ const indexEntry = indexEntries.get(path$6);
2751
+ if (!indexEntry) rememberModifiedFile(path$6, "staged");
2752
+ else if (indexEntry.stage !== 0 || indexEntry.oid !== headOid) rememberModifiedFile(path$6, "staged");
2753
+ }
2754
+ for (const indexEntry of indexEntries.values()) {
2755
+ if (!headFiles.has(indexEntry.path)) rememberModifiedFile(indexEntry.path, "staged");
2756
+ const absolutePath = (0, path.join)(repositoryPath, indexEntry.path);
2757
+ try {
2758
+ const stats = await fs_promises.default.lstat(absolutePath);
2759
+ if (!stats.isFile() && !stats.isSymbolicLink()) {
2760
+ rememberModifiedFile(indexEntry.path, "worktree");
2761
+ continue;
2364
2762
  }
2365
- const statusRow = await getStatusRow(filepath, entries);
2366
- if (!statusRow || !isModifiedFile(statusRow)) return;
2367
- return statusRow;
2368
- },
2369
- reduce: reduceModifiedFiles,
2370
- iterate: iterateSequentially
2371
- });
2763
+ if (indexEntry.stage !== 0) {
2764
+ rememberModifiedFile(indexEntry.path, "staged");
2765
+ continue;
2766
+ }
2767
+ if (indexEntry.size !== stats.size || await calculateBlobOid(absolutePath) !== indexEntry.oid) rememberModifiedFile(indexEntry.path, "worktree");
2768
+ } catch (error) {
2769
+ if (error.code === "ENOENT") {
2770
+ rememberModifiedFile(indexEntry.path, "worktree");
2771
+ continue;
2772
+ }
2773
+ throw error;
2774
+ }
2775
+ }
2776
+ const trackedPaths = new Set(indexEntries.keys());
2777
+ for (const filepath of workdirFiles) {
2778
+ if (trackedPaths.has(filepath)) continue;
2779
+ if (!await isomorphic_git.isIgnored({
2780
+ fs: fs_promises.default,
2781
+ dir: repositoryPath,
2782
+ filepath
2783
+ })) rememberModifiedFile(filepath, "untracked");
2784
+ }
2785
+ return Array.from(modifiedFiles.values());
2372
2786
  } catch (_unused5) {
2373
2787
  return [];
2374
2788
  }
2375
2789
  };
2376
- var formatModifiedFile = (modifiedFile) => {
2377
- return `'${modifiedFile[0]}':${modifiedFile[1]}:${modifiedFile[2]}:${modifiedFile[3]}`;
2378
- };
2790
+ var formatModifiedFile = (modifiedFile) => `'${modifiedFile.path}':${modifiedFile.reason}`;
2379
2791
  /**
2380
2792
  * Lookup version label recursively core analyzer
2381
2793
  * @param cwd - The directory to check
@@ -2384,7 +2796,7 @@ var formatModifiedFile = (modifiedFile) => {
2384
2796
  * @param commitToTags - Map of commit hash to tags for performance
2385
2797
  * @returns The version or undefined if no version is found
2386
2798
  */
2387
- var lookupVersionLabelRecursive = async (cwd, commit, reachedCommits, commitToTags) => {
2799
+ var lookupVersionLabelRecursive = async (context, commit, reachedCommits, commitToTags) => {
2388
2800
  const scheduledStack = [];
2389
2801
  let version = {
2390
2802
  major: 0,
@@ -2408,10 +2820,11 @@ var lookupVersionLabelRecursive = async (cwd, commit, reachedCommits, commitToTa
2408
2820
  try {
2409
2821
  const parentHashes = (await isomorphic_git.readCommit({
2410
2822
  fs: fs_promises.default,
2411
- dir: cwd,
2823
+ dir: context.dir,
2824
+ gitdir: context.gitdir,
2412
2825
  oid: currentCommit.hash
2413
2826
  })).commit.parent || [];
2414
- parentCommits = (await Promise.all(parentHashes.map((parentHash) => getCommit(cwd, parentHash)))).filter((ci) => ci !== void 0);
2827
+ parentCommits = (await Promise.all(parentHashes.map((parentHash) => getCommit(context, parentHash)))).filter((ci) => ci !== void 0);
2415
2828
  } catch (_unused6) {}
2416
2829
  if (parentCommits.length === 0) {
2417
2830
  reachedCommits.set(currentCommit.hash, version);
@@ -2426,7 +2839,7 @@ var lookupVersionLabelRecursive = async (cwd, commit, reachedCommits, commitToTa
2426
2839
  while (scheduledStack.length >= 1) {
2427
2840
  const { commit: scheduledCommit, parents } = scheduledStack.pop();
2428
2841
  if (parents.length >= 2) for (let index = 1; index < parents.length; index++) {
2429
- const alternateParentVersion = await lookupVersionLabelRecursive(cwd, parents[index], reachedCommits, commitToTags);
2842
+ const alternateParentVersion = await lookupVersionLabelRecursive(context, parents[index], reachedCommits, commitToTags);
2430
2843
  if (alternateParentVersion && compareVersions(alternateParentVersion, version) < 0) version = alternateParentVersion;
2431
2844
  }
2432
2845
  version = incrementLastVersionComponent(version);
@@ -2454,12 +2867,31 @@ var getGitMetadata = async (repositoryPath, checkWorkingDirectoryStatus, logger)
2454
2867
  logger.debug(`[screw-up] Total getGitMetadata: ${Date.now() - startTime}ms`);
2455
2868
  return metadata;
2456
2869
  }
2870
+ let gitContext;
2457
2871
  try {
2458
- const currentCommit = await getCurrentCommit(gitRootPath);
2459
- if (!currentCommit) {
2460
- logger.debug(`[screw-up] Total getGitMetadata: ${Date.now() - startTime}ms`);
2461
- return metadata;
2872
+ gitContext = await createGitReadContext(gitRootPath);
2873
+ } catch (error) {
2874
+ logger.warn(`Failed to resolve git metadata context: ${error}`);
2875
+ logger.debug(`[screw-up] Total getGitMetadata: ${Date.now() - startTime}ms`);
2876
+ return metadata;
2877
+ }
2878
+ const currentCommit = await getCurrentCommit(gitContext);
2879
+ if (!currentCommit) {
2880
+ logger.debug(`[screw-up] Total getGitMetadata: ${Date.now() - startTime}ms`);
2881
+ return metadata;
2882
+ }
2883
+ const gitMetadata = {
2884
+ tags: [],
2885
+ branches: [],
2886
+ commit: {
2887
+ hash: currentCommit.hash,
2888
+ shortHash: currentCommit.shortHash,
2889
+ date: dayjs(currentCommit.date).format("YYYY-MM-DDTHH:mm:ssZ"),
2890
+ message: currentCommit.message
2462
2891
  }
2892
+ };
2893
+ metadata.git = gitMetadata;
2894
+ try {
2463
2895
  const buildStart = Date.now();
2464
2896
  const commitToTags = await buildCompleteTagCache(gitRootPath, (tagName) => {
2465
2897
  const version = parseVersion(tagName);
@@ -2467,15 +2899,10 @@ var getGitMetadata = async (repositoryPath, checkWorkingDirectoryStatus, logger)
2467
2899
  }, logger);
2468
2900
  logger.debug(`[screw-up] buildCompleteTagCache: ${Date.now() - buildStart}ms`);
2469
2901
  logger.debug(`Built tag map with ${commitToTags.size} commits`);
2470
- let version = await lookupVersionLabelRecursive(gitRootPath, currentCommit, /* @__PURE__ */ new Map(), commitToTags);
2471
- const gitMetadata = {
2472
- tags: [],
2473
- branches: []
2474
- };
2475
- metadata.git = gitMetadata;
2902
+ let version = await lookupVersionLabelRecursive(gitContext, currentCommit, /* @__PURE__ */ new Map(), commitToTags);
2476
2903
  if (version) {
2477
2904
  if (checkWorkingDirectoryStatus) {
2478
- const modifiedFiles = await getModifiedFiles(gitRootPath);
2905
+ const modifiedFiles = await getModifiedFiles(gitRootPath, currentCommit.tree);
2479
2906
  if (modifiedFiles.length >= 1) {
2480
2907
  const newVersion = incrementLastVersionComponent(version);
2481
2908
  logger.debug(`Increased git version by detected modified items: ${formatVersion(version)} ---> ${formatVersion(newVersion)}, Files=[${modifiedFiles.map(formatModifiedFile).join(", ")}]`);
@@ -2486,16 +2913,14 @@ var getGitMetadata = async (repositoryPath, checkWorkingDirectoryStatus, logger)
2486
2913
  gitMetadata.version = gitVersion;
2487
2914
  metadata.version = gitVersion;
2488
2915
  }
2489
- gitMetadata.commit = {
2490
- hash: currentCommit.hash,
2491
- shortHash: currentCommit.shortHash,
2492
- date: dayjs(currentCommit.date).format("YYYY-MM-DDTHH:mm:ssZ"),
2493
- message: currentCommit.message
2494
- };
2495
2916
  gitMetadata.tags = getRelatedTagsFromMap(commitToTags, currentCommit.hash).map((tag) => tag.name);
2496
- gitMetadata.branches = await getRelatedBranches(gitRootPath, currentCommit.hash);
2497
2917
  } catch (error) {
2498
- logger.warn(`Failed to extract git metadata: ${error}`);
2918
+ logger.warn(`Failed to resolve git versioning metadata: ${error}`);
2919
+ }
2920
+ try {
2921
+ gitMetadata.branches = await getRelatedBranches(gitContext, currentCommit.hash);
2922
+ } catch (error) {
2923
+ logger.warn(`Failed to resolve git branch metadata: ${error}`);
2499
2924
  }
2500
2925
  logger.debug(`[screw-up] Total getGitMetadata: ${Date.now() - startTime}ms`);
2501
2926
  return metadata;