@rushstack/package-deps-hash 4.7.17 → 4.7.19

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/CHANGELOG.json CHANGED
@@ -1,6 +1,30 @@
1
1
  {
2
2
  "name": "@rushstack/package-deps-hash",
3
3
  "entries": [
4
+ {
5
+ "version": "4.7.19",
6
+ "tag": "@rushstack/package-deps-hash_v4.7.19",
7
+ "date": "Mon, 08 Jun 2026 15:15:50 GMT",
8
+ "comments": {
9
+ "dependency": [
10
+ {
11
+ "comment": "Updating dependency \"@rushstack/heft\" to `1.2.18`"
12
+ }
13
+ ]
14
+ }
15
+ },
16
+ {
17
+ "version": "4.7.18",
18
+ "tag": "@rushstack/package-deps-hash_v4.7.18",
19
+ "date": "Mon, 25 May 2026 15:14:32 GMT",
20
+ "comments": {
21
+ "patch": [
22
+ {
23
+ "comment": "Skip untracked files whose basename is a Windows reserved device name (e.g. `nul`, `con`, `aux`, `com1`-`com9`, `lpt1`-`lpt9`) when computing repo state on Windows. `git hash-object` cannot open such paths and otherwise aborts the entire repo-state calculation."
24
+ }
25
+ ]
26
+ }
27
+ },
4
28
  {
5
29
  "version": "4.7.17",
6
30
  "tag": "@rushstack/package-deps-hash_v4.7.17",
package/CHANGELOG.md CHANGED
@@ -1,6 +1,18 @@
1
1
  # Change Log - @rushstack/package-deps-hash
2
2
 
3
- This log was last generated on Mon, 20 Apr 2026 23:31:13 GMT and should not be manually modified.
3
+ This log was last generated on Mon, 08 Jun 2026 15:15:50 GMT and should not be manually modified.
4
+
5
+ ## 4.7.19
6
+ Mon, 08 Jun 2026 15:15:50 GMT
7
+
8
+ _Version update only_
9
+
10
+ ## 4.7.18
11
+ Mon, 25 May 2026 15:14:32 GMT
12
+
13
+ ### Patches
14
+
15
+ - Skip untracked files whose basename is a Windows reserved device name (e.g. `nul`, `con`, `aux`, `com1`-`com9`, `lpt1`-`lpt9`) when computing repo state on Windows. `git hash-object` cannot open such paths and otherwise aborts the entire repo-state calculation.
4
16
 
5
17
  ## 4.7.17
6
18
  Mon, 20 Apr 2026 23:31:13 GMT
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.58.6"
8
+ "packageVersion": "7.58.7"
9
9
  }
10
10
  ]
11
11
  }
@@ -2,6 +2,7 @@
2
2
  // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
3
3
  // See LICENSE in the project root for license information.
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.isWindowsReservedPath = isWindowsReservedPath;
5
6
  exports.parseGitLsTree = parseGitLsTree;
6
7
  exports.parseGitHashObject = parseGitHashObject;
7
8
  exports.parseGitDiffIndex = parseGitDiffIndex;
@@ -29,6 +30,27 @@ const STANDARD_GIT_OPTIONS = [
29
30
  '-c',
30
31
  'maintenance.auto=false'
31
32
  ];
33
+ // Windows reserved device names (case-insensitive). A file whose final path segment matches one
34
+ // of these (with or without an extension) cannot be opened by name on Windows, so passing it to
35
+ // `git hash-object` aborts the process. Such files are typically untracked artifacts left behind
36
+ // by tooling (e.g. stray `nul` from a shell redirect).
37
+ const WINDOWS_RESERVED_BASENAMES = new Set([
38
+ 'CON', 'PRN', 'AUX', 'NUL',
39
+ 'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9',
40
+ 'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9'
41
+ ]);
42
+ /**
43
+ * Returns `true` if `filePath`'s final path segment is a Windows reserved device name
44
+ * (with or without an extension), case-insensitively. Exported for tests.
45
+ * @internal
46
+ */
47
+ function isWindowsReservedPath(filePath) {
48
+ const lastSlash = Math.max(filePath.lastIndexOf('/'), filePath.lastIndexOf('\\'));
49
+ const basename = lastSlash >= 0 ? filePath.slice(lastSlash + 1) : filePath;
50
+ const dot = basename.indexOf('.');
51
+ const stem = (dot >= 0 ? basename.slice(0, dot) : basename).toUpperCase();
52
+ return WINDOWS_RESERVED_BASENAMES.has(stem);
53
+ }
32
54
  const OBJECTMODE_SUBMODULE = '160000';
33
55
  const OBJECTMODE_SYMLINK = '120000';
34
56
  const OBJECTMODE_FILE_NONEXECUTABLE = '100644';
@@ -339,8 +361,15 @@ async function getDetailedRepoStateAsync(rootDirectory, additionalRelativePathsT
339
361
  }
340
362
  }
341
363
  const [{ files, symlinks }, locallyModified] = await Promise.all([statePromise, locallyModifiedPromise]);
364
+ const isWindows = process.platform === 'win32';
342
365
  for (const [filePath, exists] of locallyModified) {
343
366
  if (exists && !symlinks.has(filePath)) {
367
+ // Skip Windows reserved device names. `git hash-object` cannot open them and would abort
368
+ // the entire repo-state computation. These are almost always stray artifacts (e.g. a `nul`
369
+ // file produced by a misdirected shell redirect) rather than meaningful inputs.
370
+ if (isWindows && isWindowsReservedPath(filePath)) {
371
+ continue;
372
+ }
344
373
  yield filePath;
345
374
  }
346
375
  else {
@@ -1 +1 @@
1
- {"version":3,"file":"getRepoState.js","sourceRoot":"","sources":["../src/getRepoState.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;AAgD3D,wCAoDC;AAOD,gDA+BC;AAkBD,8CAoCC;AASD,wCA2BC;AAaD,kCAyBC;AAsED,wCAoCC;AAUD,8CAcC;AAiCD,8DAsGC;AAWD,wCAiCC;AAOD,0DAeC;AAkBD,0CAyBC;AA7nBD,6CAAmC;AACnC,6CAAiD;AAEjD,4EAAuG;AACvG,4EAAyE;AAQzE,MAAM,mBAAmB,GAAgB;IACvC,KAAK,EAAE,CAAC;IACR,KAAK,EAAE,EAAE;IACT,KAAK,EAAE,CAAC;CACT,CAAC;AAEF,MAAM,oBAAoB,GAAsB;IAC9C,wCAAwC;IACxC,qBAAqB;IACrB,6GAA6G;IAC7G,IAAI;IACJ,wBAAwB;CACzB,CAAC;AAEF,MAAM,oBAAoB,GAAa,QAAQ,CAAC;AAChD,MAAM,kBAAkB,GAAa,QAAQ,CAAC;AAC9C,MAAM,6BAA6B,GAAa,QAAQ,CAAC;AACzD,MAAM,0BAA0B,GAAa,QAAQ,CAAC;AAEtD,+IAA+I;AAC/I,iCAAiC;AACjC,MAAM,iBAAiB,GAAW,6CAA6C,CAAC;AAQhF;;;GAGG;AACH,SAAgB,cAAc,CAAC,MAAc;IAC3C,MAAM,KAAK,GAAwB,IAAI,GAAG,EAAE,CAAC;IAC7C,MAAM,QAAQ,GAAwB,IAAI,GAAG,EAAE,CAAC;IAChD,MAAM,UAAU,GAAwB,IAAI,GAAG,EAAE,CAAC;IAElD,mBAAmB;IACnB,qDAAqD;IACrD,qBAAqB;IACrB,oCAAoC;IACpC,6FAA6F;IAE7F,IAAI,IAAI,GAAW,CAAC,CAAC;IACrB,IAAI,KAAK,GAAW,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC/C,OAAO,KAAK,IAAI,CAAC,EAAE,CAAC;QAClB,MAAM,IAAI,GAAW,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAE/C,MAAM,QAAQ,GAAW,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,QAAQ,GAAW,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;QAElD,+EAA+E;QAC/E,MAAM,IAAI,GAAW,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;QAEzD,MAAM,IAAI,GAAW,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;QAEtD,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,oBAAoB,CAAC,CAAC,CAAC;gBAC1B,sBAAsB;gBACtB,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;gBAC/B,MAAM;YACR,CAAC;YACD,KAAK,kBAAkB,CAAC,CAAC,CAAC;gBACxB,0BAA0B;gBAC1B,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;gBAC7B,MAAM;YACR,CAAC;YACD,KAAK,6BAA6B,CAAC;YACnC,KAAK,0BAA0B,CAAC;YAChC,OAAO,CAAC,CAAC,CAAC;gBACR,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;gBAC1B,MAAM;YACR,CAAC;QACH,CAAC;QAED,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC;QACjB,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACrC,CAAC;IAED,OAAO;QACL,KAAK;QACL,QAAQ;QACR,UAAU;KACX,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,QAAe,CAAC,CAAC,kBAAkB,CACjC,MAAc,EACd,SAAgC;IAEhC,MAAM,QAAQ,GAAW,SAAS,CAAC,MAAM,CAAC;IAC1C,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;QACnB,OAAO;IACT,CAAC;IAED,MAAM,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAEvB,IAAI,IAAI,GAAW,CAAC,CAAC;IACrB,IAAI,CAAC,GAAW,CAAC,CAAC;IAClB,IAAI,KAAK,GAAW,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,QAAQ,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAW,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC/C,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QAC3B,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC;QACjB,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACrC,CAAC;IAED,0DAA0D;IAC1D,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACd,MAAM,IAAI,GAAW,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QAC3B,CAAC,EAAE,CAAC;IACN,CAAC;IAED,IAAI,CAAC,KAAK,QAAQ,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,YAAY,QAAQ,+CAA+C,CAAC,EAAE,CAAC,CAAC;IAC1F,CAAC;AACH,CAAC;AAaD;;;;GAIG;AACH,SAAgB,iBAAiB,CAAC,MAAc;IAC9C,MAAM,MAAM,GAAiC,IAAI,GAAG,EAAE,CAAC;IAEvD,mBAAmB;IACnB,qDAAqD;IACrD,qBAAqB;IACrB,8DAA8D;IAC9D,2IAA2I;IAE3I,IAAI,IAAI,GAAW,CAAC,CAAC;IACrB,IAAI,KAAK,GAAW,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC/C,OAAO,KAAK,IAAI,CAAC,EAAE,CAAC;QAClB,MAAM,MAAM,GAAW,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACjD,MAAM,MAAM,GAA8B,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAA8B,CAAC;QAExF,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC;QACjB,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACnC,MAAM,QAAQ,GAAW,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAEnD,wGAAwG;QACxG,+EAA+E;QAC/E,MAAM,IAAI,GAAW,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACzC,MAAM,OAAO,GAAW,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;QAC/C,MAAM,OAAO,GAAW,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QAC9C,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE;YACnB,IAAI;YACJ,OAAO;YACP,OAAO;YACP,MAAM;SACP,CAAC,CAAC;QAEH,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC;QACjB,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACrC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,cAAc,CAAC,MAAc;IAC3C,MAAM,MAAM,GAAyB,IAAI,GAAG,EAAE,CAAC;IAE/C,mBAAmB;IACnB,qDAAqD;IACrD,qBAAqB;IACrB,cAAc;IACd,0CAA0C;IAE1C,IAAI,WAAW,GAAW,CAAC,CAAC;IAC5B,IAAI,QAAQ,GAAW,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IACzD,OAAO,QAAQ,IAAI,CAAC,EAAE,CAAC;QACrB,wGAAwG;QACxG,8FAA8F;QAC9F,MAAM,iBAAiB,GAAW,MAAM,CAAC,MAAM,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;QACjE,gFAAgF;QAChF,MAAM,OAAO,GACX,iBAAiB,KAAK,GAAG,IAAI,CAAC,iBAAiB,KAAK,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,GAAG,CAAC,CAAC;QAEjG,MAAM,QAAQ,GAAW,MAAM,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC;QACjE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC;QAE/B,WAAW,GAAG,QAAQ,GAAG,CAAC,CAAC;QAC3B,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,aAAa,GAAwB,IAAI,GAAG,EAAE,CAAC;AAErD;;;;;;;;GAQG;AACH,SAAgB,WAAW,CAAC,uBAA+B,EAAE,OAAgB;IAC3E,IAAI,YAAY,GAAuB,aAAa,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;IAClF,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,MAAM,GAA2C,uBAAU,CAAC,SAAS,CACzE,OAAO,IAAI,KAAK,EAChB,CAAC,qBAAqB,EAAE,WAAW,EAAE,iBAAiB,CAAC,EACvD;YACE,uBAAuB;SACxB,CACF,CAAC;QAEF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,uBAAuB,CAAC,OAAO,CAAC,CAAC;YAEjC,MAAM,IAAI,KAAK,CAAC,oCAAoC,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QACzF,CAAC;QAED,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAEpC,aAAa,CAAC,GAAG,CAAC,uBAAuB,EAAE,YAAY,CAAC,CAAC;QACzD,+DAA+D;QAC/D,aAAa,CAAC,GAAG,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;IAChD,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,aAAa,CAC1B,OAA2B,EAC3B,IAAc,EACd,uBAA+B,EAC/B,KAAgB;IAEhB,MAAM,YAAY,GAA4B;QAC5C,uBAAuB;QACvB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;KAChC,CAAC;IAEF,IAAI,MAAM,GAAW,EAAE,CAAC;IACxB,IAAI,MAAM,GAAW,EAAE,CAAC;IAExB,MAAM,IAAI,GAA+B,uBAAU,CAAC,KAAK,CAAC,OAAO,IAAI,KAAK,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;IAChG,IAAI,CAAC,MAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAClC,IAAI,CAAC,MAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAElC,IAAI,CAAC,MAAO,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;QACxC,MAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;IACH,IAAI,CAAC,MAAO,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;QACxC,MAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,IAAI,KAAK,EAAE,CAAC;QACV;;;;WAIG;QACH,IAAA,sBAAQ,EAAC,KAAK,EAAE,IAAI,CAAC,KAAM,EAAE,CAAC,GAAG,EAAE,EAAE,GAAE,CAAC,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,IAAA,kBAAI,EAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC3C,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;QACjB,uBAAuB,CAAC,OAAO,CAAC,CAAC;QAEjC,MAAM,IAAI,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,qBAAqB,MAAM,MAAM,MAAM,EAAE,CAAC,CAAC;IAC3E,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,UAAU,CAAI,KAAqC;IAC1D,OAAO,MAAM,CAAC,QAAQ,IAAI,KAAK,CAAC;AAClC,CAAC;AAED;;;;;;;;;;;;GAYG;AACI,KAAK,UAAU,cAAc,CAClC,aAAqB,EACrB,WAAqD,EACrD,OAAgB;IAEhB,MAAM,SAAS,GAAa,EAAE,CAAC;IAE/B,MAAM,KAAK,GAAa,sBAAQ,CAAC,IAAI,CACnC,UAAU,CAAC,WAAW,CAAC;QACrB,CAAC,CAAC,CAAC,QAAQ,CAAC;YACR,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;gBAC/B,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACrB,MAAM,GAAG,IAAI,IAAI,CAAC;YACpB,CAAC;QACH,CAAC,CAAC,EAAE;QACN,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC;YACd,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;gBACrC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACrB,MAAM,GAAG,IAAI,IAAI,CAAC;YACpB,CAAC;QACH,CAAC,CAAC,EAAE,EACR;QACE,QAAQ,EAAE,OAAO;QACjB,UAAU,EAAE,KAAK;QACjB,WAAW,EAAE,IAAI;KAClB,CACF,CAAC;IAEF,MAAM,gBAAgB,GAAW,MAAM,aAAa,CAClD,OAAO,EACP,oBAAoB,CAAC,MAAM,CAAC,CAAC,aAAa,EAAE,eAAe,CAAC,CAAC,EAC7D,aAAa,EACb,KAAK,CACN,CAAC;IAEF,OAAO,kBAAkB,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;AACzD,CAAC;AAED;;;;;;;GAOG;AACI,KAAK,UAAU,iBAAiB,CACrC,aAAqB,EACrB,6BAAwC,EACxC,OAAgB,EAChB,UAAqB;IAErB,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,yBAAyB,CAC/C,aAAa,EACb,6BAA6B,EAC7B,OAAO,EACP,UAAU,CACX,CAAC;IAEF,OAAO,KAAK,CAAC;AACf,CAAC;AAyBD;;;;;;;GAOG;AACI,KAAK,UAAU,yBAAyB,CAC7C,aAAqB,EACrB,6BAAwC,EACxC,OAAgB,EAChB,UAAqB;IAErB,MAAM,YAAY,GAA2B,aAAa,CACxD,OAAO,EACP,oBAAoB,CAAC,MAAM,CAAC;QAC1B,UAAU;QACV,2BAA2B;QAC3B,UAAU;QACV,2BAA2B;QAC3B,IAAI;QACJ,sDAAsD;QACtD,aAAa;QACb,2GAA2G;QAC3G,YAAY,iBAAiB,EAAE;QAC/B,IAAI;QACJ,GAAG,CAAC,UAAU,aAAV,UAAU,cAAV,UAAU,GAAI,EAAE,CAAC;KACtB,CAAC,EACF,aAAa,CACd,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACvB,MAAM,sBAAsB,GAAkC,aAAa,CACzE,OAAO,EACP,oBAAoB,CAAC,MAAM,CAAC;QAC1B,QAAQ;QACR,2BAA2B;QAC3B,IAAI;QACJ,0BAA0B;QAC1B,IAAI;QACJ,mEAAmE;QACnE,cAAc;QACd,8EAA8E;QAC9E,qBAAqB;QACrB,mCAAmC;QACnC,mBAAmB;QACnB,IAAI;QACJ,GAAG,CAAC,UAAU,aAAV,UAAU,cAAV,UAAU,GAAI,EAAE,CAAC;KACtB,CAAC,EACF,aAAa,CACd,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAEvB,KAAK,SAAS,CAAC,CAAC,cAAc;QAC5B,IAAI,6BAA6B,EAAE,CAAC;YAClC,KAAK,MAAM,IAAI,IAAI,6BAA6B,EAAE,CAAC;gBACjD,MAAM,IAAI,CAAC;YACb,CAAC;QACH,CAAC;QAED,MAAM,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,eAAe,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,sBAAsB,CAAC,CAAC,CAAC;QAEzG,KAAK,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,eAAe,EAAE,CAAC;YACjD,IAAI,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACtC,MAAM,QAAQ,CAAC;YACjB,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBACvB,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,iBAAiB,GAAwC,cAAc,CAC3E,aAAa,EACb,cAAc,EAAE,EAChB,OAAO,CACR,CAAC;IAEF,MAAM,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,oBAAoB,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAChF,YAAY;QACZ,sBAAsB;KACvB,CAAC,CAAC;IAEH,sFAAsF;IACtF,KAAK,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,MAAM,iBAAiB,EAAE,CAAC;QACvD,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,2CAA2C;IAC3C,MAAM,aAAa,GAAY,UAAU,CAAC,IAAI,GAAG,CAAC,IAAI,uBAAU,CAAC,MAAM,CAAC,GAAG,aAAa,cAAc,CAAC,CAAC;IAExG,IAAI,aAAa,EAAE,CAAC;QAClB,8GAA8G;QAC9G,uDAAuD;QACvD,KAAK,MAAM,aAAa,IAAI,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC;YAC9C,MAAM,cAAc,GAAwB,MAAM,iBAAiB,CACjE,GAAG,aAAa,IAAI,aAAa,EAAE,EACnC,EAAE,EACF,OAAO,CACR,CAAC;YACF,KAAK,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,cAAc,EAAE,CAAC;gBAC9C,KAAK,CAAC,GAAG,CAAC,GAAG,aAAa,IAAI,QAAQ,EAAE,EAAE,IAAI,CAAC,CAAC;YAClD,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO;QACL,aAAa;QACb,qBAAqB,EAAE,oBAAoB,CAAC,IAAI,GAAG,CAAC;QACpD,KAAK;QACL,QAAQ;KACT,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,cAAc,CAC5B,uBAA+B,EAC/B,WAAmB,MAAM,EACzB,OAAgB;IAEhB,MAAM,aAAa,GAAW,WAAW,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC;IAE5E,MAAM,MAAM,GAA2C,uBAAU,CAAC,SAAS,CACzE,OAAO,IAAI,KAAK,EAChB,oBAAoB,CAAC,MAAM,CAAC;QAC1B,YAAY;QACZ,eAAe;QACf,cAAc;QACd,gBAAgB;QAChB,UAAU;QACV,IAAI;QACJ,QAAQ;QACR,IAAI;KACL,CAAC,EACF;QACE,uBAAuB,EAAE,aAAa;KACvC,CACF,CAAC;IAEF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,uBAAuB,CAAC,OAAO,CAAC,CAAC;QAEjC,MAAM,IAAI,KAAK,CAAC,qCAAqC,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1F,CAAC;IAED,MAAM,OAAO,GAAiC,iBAAiB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAE/E,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,SAAgB,uBAAuB,CAAC,OAAgB;IACtD,MAAM,UAAU,GAAgB,aAAa,CAAC,OAAO,CAAC,CAAC;IACvD,IACE,UAAU,CAAC,KAAK,GAAG,mBAAmB,CAAC,KAAK;QAC5C,CAAC,UAAU,CAAC,KAAK,KAAK,mBAAmB,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,GAAG,mBAAmB,CAAC,KAAK,CAAC;QAChG,CAAC,UAAU,CAAC,KAAK,KAAK,mBAAmB,CAAC,KAAK;YAC7C,UAAU,CAAC,KAAK,KAAK,mBAAmB,CAAC,KAAK;YAC9C,UAAU,CAAC,KAAK,GAAG,mBAAmB,CAAC,KAAK,CAAC,EAC/C,CAAC;QACD,MAAM,IAAI,KAAK,CACb,sCAAsC;YACpC,GAAG,mBAAmB,CAAC,KAAK,IAAI,mBAAmB,CAAC,KAAK,IAAI,mBAAmB,CAAC,KAAK,IAAI;YAC1F,mBAAmB,UAAU,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,GAAG,CACjF,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,OAAgB;IACrC,MAAM,MAAM,GAA2C,uBAAU,CAAC,SAAS,CACzE,OAAO,IAAI,KAAK,EAChB,oBAAoB,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,CACzC,CAAC;IAEF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,+EAA+E;YAC7E,UAAU,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,CAC9C,CAAC;IACJ,CAAC;IAED,OAAO,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AACxC,CAAC;AAED,SAAgB,eAAe,CAAC,gBAAwB;IACtD,kHAAkH;IAClH,YAAY;IACZ,sBAAsB;IACtB,0BAA0B;IAC1B,+BAA+B;IAC/B,gCAAgC;IAChC,MAAM,YAAY,GAAW,kCAAkC,CAAC;IAChE,MAAM,KAAK,GAA4B,YAAY,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC3E,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,4EAA4E;YAC1E,uBAAuB,gBAAgB,GAAG,CAC7C,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAW,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAW,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAW,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAE7C,OAAO;QACL,KAAK;QACL,KAAK;QACL,KAAK;KACN,CAAC;AACJ,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport type * as child_process from 'node:child_process';\nimport { once } from 'node:events';\nimport { Readable, pipeline } from 'node:stream';\n\nimport { Executable, type IExecutableSpawnOptions } from '@rushstack/node-core-library/lib/Executable';\nimport { FileSystem } from '@rushstack/node-core-library/lib/FileSystem';\n\nexport interface IGitVersion {\n major: number;\n minor: number;\n patch: number;\n}\n\nconst MINIMUM_GIT_VERSION: IGitVersion = {\n major: 2,\n minor: 35,\n patch: 0\n};\n\nconst STANDARD_GIT_OPTIONS: readonly string[] = [\n // Don't request any optional file locks\n '--no-optional-locks',\n // Ensure that commands don't run automatic maintenance, since performance of the command itself is paramount\n '-c',\n 'maintenance.auto=false'\n];\n\nconst OBJECTMODE_SUBMODULE: '160000' = '160000';\nconst OBJECTMODE_SYMLINK: '120000' = '120000';\nconst OBJECTMODE_FILE_NONEXECUTABLE: '100644' = '100644';\nconst OBJECTMODE_FILE_EXECUTABLE: '100755' = '100755';\n\n// Note that `type` is a stub that is being ignored by the parser in favor of using `mode` to infer, since `%(objecttype)` requires git 2.51.0+\n// e.g. 10644 blob <hash>\\t<path>\nconst GIT_LSTREE_FORMAT: string = '%(objectmode) type %(objectname)%x09%(path)';\n\ninterface IGitTreeState {\n files: Map<string, string>; // type \"blob\"\n symlinks: Map<string, string>; // type \"link\"\n submodules: Map<string, string>; // type \"commit\"\n}\n\n/**\n * Parses the output of the \"git ls-tree -r -z\" command or of other commands that have been coerced to match its format.\n * @internal\n */\nexport function parseGitLsTree(output: string): IGitTreeState {\n const files: Map<string, string> = new Map();\n const symlinks: Map<string, string> = new Map();\n const submodules: Map<string, string> = new Map();\n\n // Parse the output\n // With the -z modifier, paths are delimited by nulls\n // A line looks like:\n // <mode> <type> <newhash>\\t<path>\\0\n // 100644 blob a300ccb0b36bd2c85ef18e3c619a2c747f95959e\\ttools/prettier-git/prettier-git.js\\0\n\n let last: number = 0;\n let index: number = output.indexOf('\\0', last);\n while (index >= 0) {\n const item: string = output.slice(last, index);\n\n const tabIndex: number = item.indexOf('\\t');\n const filePath: string = item.slice(tabIndex + 1);\n\n // The newHash will be all zeros if the file is deleted, or a hash if it exists\n const hash: string = item.slice(tabIndex - 40, tabIndex);\n\n const mode: string = item.slice(0, item.indexOf(' '));\n\n switch (mode) {\n case OBJECTMODE_SUBMODULE: {\n // This is a submodule\n submodules.set(filePath, hash);\n break;\n }\n case OBJECTMODE_SYMLINK: {\n // This is a symbolic link\n symlinks.set(filePath, hash);\n break;\n }\n case OBJECTMODE_FILE_NONEXECUTABLE:\n case OBJECTMODE_FILE_EXECUTABLE:\n default: {\n files.set(filePath, hash);\n break;\n }\n }\n\n last = index + 1;\n index = output.indexOf('\\0', last);\n }\n\n return {\n files,\n symlinks,\n submodules\n };\n}\n\n/**\n * Parses the output of `git hash-object`\n * yields [filePath, hash] pairs.\n * @internal\n */\nexport function* parseGitHashObject(\n output: string,\n filePaths: ReadonlyArray<string>\n): IterableIterator<[string, string]> {\n const expected: number = filePaths.length;\n if (expected === 0) {\n return;\n }\n\n output = output.trim();\n\n let last: number = 0;\n let i: number = 0;\n let index: number = output.indexOf('\\n', last);\n for (; i < expected && index > 0; i++) {\n const hash: string = output.slice(last, index);\n yield [filePaths[i], hash];\n last = index + 1;\n index = output.indexOf('\\n', last);\n }\n\n // Handle last line. Will be non-empty to due trim() call.\n if (index < 0) {\n const hash: string = output.slice(last);\n yield [filePaths[i], hash];\n i++;\n }\n\n if (i !== expected) {\n throw new Error(`Expected ${expected} hashes from \"git hash-object\" but received ${i}`);\n }\n}\n\n/**\n * Information about the changes to a file.\n * @beta\n */\nexport interface IFileDiffStatus {\n mode: string;\n oldhash: string;\n newhash: string;\n status: 'A' | 'D' | 'M';\n}\n\n/**\n * Parses the output of `git diff-index --color=never --no-renames --no-commit-id -z <REVISION> --\n * Returns a map of file path to diff\n * @internal\n */\nexport function parseGitDiffIndex(output: string): Map<string, IFileDiffStatus> {\n const result: Map<string, IFileDiffStatus> = new Map();\n\n // Parse the output\n // With the -z modifier, paths are delimited by nulls\n // A line looks like:\n // :<oldmode> <newmode> <oldhash> <newhash> <status>\\0<path>\\0\n // :100644 100644 a300ccb0b36bd2c85ef18e3c619a2c747f95959e 0000000000000000000000000000000000000000 M\\0tools/prettier-git/prettier-git.js\\0\n\n let last: number = 0;\n let index: number = output.indexOf('\\0', last);\n while (index >= 0) {\n const header: string = output.slice(last, index);\n const status: IFileDiffStatus['status'] = header.slice(-1) as IFileDiffStatus['status'];\n\n last = index + 1;\n index = output.indexOf('\\0', last);\n const filePath: string = output.slice(last, index);\n\n // We passed --no-renames above, so a rename will be a delete of the old location and an add at the new.\n // The newHash will be all zeros if the file is deleted, or a hash if it exists\n const mode: string = header.slice(8, 14);\n const oldhash: string = header.slice(-83, -43);\n const newhash: string = header.slice(-42, -2);\n result.set(filePath, {\n mode,\n oldhash,\n newhash,\n status\n });\n\n last = index + 1;\n index = output.indexOf('\\0', last);\n }\n\n return result;\n}\n\n/**\n * Parses the output of `git status -z -u` to extract the set of files that have changed since HEAD.\n *\n * @param output - The raw output from Git\n * @returns a map of file path to if it exists\n * @internal\n */\nexport function parseGitStatus(output: string): Map<string, boolean> {\n const result: Map<string, boolean> = new Map();\n\n // Parse the output\n // With the -z modifier, paths are delimited by nulls\n // A line looks like:\n // XY <path>\\0\n // M tools/prettier-git/prettier-git.js\\0\n\n let startOfLine: number = 0;\n let eolIndex: number = output.indexOf('\\0', startOfLine);\n while (eolIndex >= 0) {\n // We passed --no-renames above, so a rename will be a delete of the old location and an add at the new.\n // charAt(startOfLine) is the index status, charAt(startOfLine + 1) is the working tree status\n const workingTreeStatus: string = output.charAt(startOfLine + 1);\n // Deleted in working tree, or not modified in working tree and deleted in index\n const deleted: boolean =\n workingTreeStatus === 'D' || (workingTreeStatus === ' ' && output.charAt(startOfLine) === 'D');\n\n const filePath: string = output.slice(startOfLine + 3, eolIndex);\n result.set(filePath, !deleted);\n\n startOfLine = eolIndex + 1;\n eolIndex = output.indexOf('\\0', startOfLine);\n }\n\n return result;\n}\n\nconst repoRootCache: Map<string, string> = new Map();\n\n/**\n * Finds the root of the current Git repository\n *\n * @param currentWorkingDirectory - The working directory for which to locate the repository\n * @param gitPath - The path to the Git executable\n *\n * @returns The full path to the root directory of the Git repository\n * @beta\n */\nexport function getRepoRoot(currentWorkingDirectory: string, gitPath?: string): string {\n let cachedResult: string | undefined = repoRootCache.get(currentWorkingDirectory);\n if (!cachedResult) {\n const result: child_process.SpawnSyncReturns<string> = Executable.spawnSync(\n gitPath || 'git',\n ['--no-optional-locks', 'rev-parse', '--show-toplevel'],\n {\n currentWorkingDirectory\n }\n );\n\n if (result.status !== 0) {\n ensureGitMinimumVersion(gitPath);\n\n throw new Error(`git rev-parse exited with status ${result.status}: ${result.stderr}`);\n }\n\n cachedResult = result.stdout.trim();\n\n repoRootCache.set(currentWorkingDirectory, cachedResult);\n // To ensure that calling getRepoRoot on the result is a no-op.\n repoRootCache.set(cachedResult, cachedResult);\n }\n\n return cachedResult;\n}\n\n/**\n * Helper function for async process invocation with optional stdin support.\n * @param gitPath - Path to the Git executable\n * @param args - The process arguments\n * @param currentWorkingDirectory - The working directory. Should be the repository root.\n * @param stdin - An optional Readable stream to use as stdin to the process.\n */\nasync function spawnGitAsync(\n gitPath: string | undefined,\n args: string[],\n currentWorkingDirectory: string,\n stdin?: Readable\n): Promise<string> {\n const spawnOptions: IExecutableSpawnOptions = {\n currentWorkingDirectory,\n stdio: ['pipe', 'pipe', 'pipe']\n };\n\n let stdout: string = '';\n let stderr: string = '';\n\n const proc: child_process.ChildProcess = Executable.spawn(gitPath || 'git', args, spawnOptions);\n proc.stdout!.setEncoding('utf-8');\n proc.stderr!.setEncoding('utf-8');\n\n proc.stdout!.on('data', (chunk: string) => {\n stdout += chunk.toString();\n });\n proc.stderr!.on('data', (chunk: string) => {\n stderr += chunk.toString();\n });\n\n if (stdin) {\n /**\n * For `git hash-object` data is piped in asynchronously. In the event that one of the\n * passed filenames cannot be hashed, subsequent writes to `proc.stdin` will error.\n * Silence this error since it will be handled by the non-zero exit code of the process.\n */\n pipeline(stdin, proc.stdin!, (err) => {});\n }\n\n const [status] = await once(proc, 'close');\n if (status !== 0) {\n ensureGitMinimumVersion(gitPath);\n\n throw new Error(`git ${args[0]} exited with code ${status}:\\n${stderr}`);\n }\n\n return stdout;\n}\n\nfunction isIterable<T>(value: Iterable<T> | AsyncIterable<T>): value is Iterable<T> {\n return Symbol.iterator in value;\n}\n\n/**\n * Uses `git hash-object` to hash the provided files. Unlike `getGitHashForFiles`, this API is asynchronous, and also allows for\n * the input file paths to be specified as an async iterable.\n *\n * @param rootDirectory - The root directory to which paths are specified relative. Must be the root of the Git repository.\n * @param filesToHash - The file paths to hash using `git hash-object`\n * @param gitPath - The path to the Git executable\n * @returns An iterable of [filePath, hash] pairs\n *\n * @remarks\n * The input file paths must be specified relative to the Git repository root, or else be absolute paths.\n * @beta\n */\nexport async function hashFilesAsync(\n rootDirectory: string,\n filesToHash: Iterable<string> | AsyncIterable<string>,\n gitPath?: string\n): Promise<Iterable<[string, string]>> {\n const hashPaths: string[] = [];\n\n const input: Readable = Readable.from(\n isIterable(filesToHash)\n ? (function* (): IterableIterator<string> {\n for (const file of filesToHash) {\n hashPaths.push(file);\n yield `${file}\\n`;\n }\n })()\n : (async function* (): AsyncIterableIterator<string> {\n for await (const file of filesToHash) {\n hashPaths.push(file);\n yield `${file}\\n`;\n }\n })(),\n {\n encoding: 'utf-8',\n objectMode: false,\n autoDestroy: true\n }\n );\n\n const hashObjectResult: string = await spawnGitAsync(\n gitPath,\n STANDARD_GIT_OPTIONS.concat(['hash-object', '--stdin-paths']),\n rootDirectory,\n input\n );\n\n return parseGitHashObject(hashObjectResult, hashPaths);\n}\n\n/**\n * Gets the object hashes for all files in the Git repo, combining the current commit with working tree state.\n * Uses async operations and runs all primary Git calls in parallel.\n * @param rootDirectory - The root directory of the Git repository\n * @param additionalRelativePathsToHash - Root-relative file paths to have Git hash and include in the results\n * @param gitPath - The path to the Git executable\n * @beta\n */\nexport async function getRepoStateAsync(\n rootDirectory: string,\n additionalRelativePathsToHash?: string[],\n gitPath?: string,\n filterPath?: string[]\n): Promise<Map<string, string>> {\n const { files } = await getDetailedRepoStateAsync(\n rootDirectory,\n additionalRelativePathsToHash,\n gitPath,\n filterPath\n );\n\n return files;\n}\n\n/**\n * Information about the detailed state of the Git repository.\n * @beta\n */\nexport interface IDetailedRepoState {\n /**\n * The Git file hashes for all files in the repository, including uncommitted changes.\n */\n files: Map<string, string>;\n /**\n * The Git file hashes for all symbolic links in the repository, including uncommitted changes.\n */\n symlinks: Map<string, string>;\n /**\n * A boolean indicating whether the repository has submodules.\n */\n hasSubmodules: boolean;\n /**\n * A boolean indicating whether the repository has uncommitted changes.\n */\n hasUncommittedChanges: boolean;\n}\n\n/**\n * Gets the object hashes for all files in the Git repo, combining the current commit with working tree state.\n * Uses async operations and runs all primary Git calls in parallel.\n * @param rootDirectory - The root directory of the Git repository\n * @param additionalRelativePathsToHash - Root-relative file paths to have Git hash and include in the results\n * @param gitPath - The path to the Git executable\n * @beta\n */\nexport async function getDetailedRepoStateAsync(\n rootDirectory: string,\n additionalRelativePathsToHash?: string[],\n gitPath?: string,\n filterPath?: string[]\n): Promise<IDetailedRepoState> {\n const statePromise: Promise<IGitTreeState> = spawnGitAsync(\n gitPath,\n STANDARD_GIT_OPTIONS.concat([\n 'ls-files',\n // Read from the index only\n '--cached',\n // Use NUL as the separator\n '-z',\n // Specify the full path to files relative to the root\n '--full-name',\n // Match the format of \"git ls-tree\". The %(objecttype) placeholder requires git 2.51.0+, so not using yet.\n `--format=${GIT_LSTREE_FORMAT}`,\n '--',\n ...(filterPath ?? [])\n ]),\n rootDirectory\n ).then(parseGitLsTree);\n const locallyModifiedPromise: Promise<Map<string, boolean>> = spawnGitAsync(\n gitPath,\n STANDARD_GIT_OPTIONS.concat([\n 'status',\n // Use NUL as the separator\n '-z',\n // Include untracked files\n '-u',\n // Disable rename detection so that renames show up as add + delete\n '--no-renames',\n // Don't process submodules with this command; they'll be handled individually\n '--ignore-submodules',\n // Don't compare against the remote\n '--no-ahead-behind',\n '--',\n ...(filterPath ?? [])\n ]),\n rootDirectory\n ).then(parseGitStatus);\n\n async function* getFilesToHash(): AsyncIterableIterator<string> {\n if (additionalRelativePathsToHash) {\n for (const file of additionalRelativePathsToHash) {\n yield file;\n }\n }\n\n const [{ files, symlinks }, locallyModified] = await Promise.all([statePromise, locallyModifiedPromise]);\n\n for (const [filePath, exists] of locallyModified) {\n if (exists && !symlinks.has(filePath)) {\n yield filePath;\n } else {\n files.delete(filePath);\n symlinks.delete(filePath);\n }\n }\n }\n\n const hashObjectPromise: Promise<Iterable<[string, string]>> = hashFilesAsync(\n rootDirectory,\n getFilesToHash(),\n gitPath\n );\n\n const [{ files, symlinks, submodules }, locallyModifiedFiles] = await Promise.all([\n statePromise,\n locallyModifiedPromise\n ]);\n\n // The result of \"git hash-object\" will be a list of file hashes delimited by newlines\n for (const [filePath, hash] of await hashObjectPromise) {\n files.set(filePath, hash);\n }\n\n // Existence check for the .gitmodules file\n const hasSubmodules: boolean = submodules.size > 0 && FileSystem.exists(`${rootDirectory}/.gitmodules`);\n\n if (hasSubmodules) {\n // Submodules are not the normal critical path. Accept serial performance rather than investing in complexity.\n // Can revisit if submodules become more commonly used.\n for (const submodulePath of submodules.keys()) {\n const submoduleState: Map<string, string> = await getRepoStateAsync(\n `${rootDirectory}/${submodulePath}`,\n [],\n gitPath\n );\n for (const [filePath, hash] of submoduleState) {\n files.set(`${submodulePath}/${filePath}`, hash);\n }\n }\n }\n\n return {\n hasSubmodules,\n hasUncommittedChanges: locallyModifiedFiles.size > 0,\n files,\n symlinks\n };\n}\n\n/**\n * Find all changed files tracked by Git, their current hashes, and the nature of the change. Only useful if all changes are staged or committed.\n * @param currentWorkingDirectory - The working directory. Only used to find the repository root.\n * @param revision - The Git revision specifier to detect changes relative to. Defaults to HEAD (i.e. will compare staged vs. committed)\n * If comparing against a different branch, call `git merge-base` first to find the target commit.\n * @param gitPath - The path to the Git executable\n * @returns A map from the Git file path to the corresponding file change metadata\n * @beta\n */\nexport function getRepoChanges(\n currentWorkingDirectory: string,\n revision: string = 'HEAD',\n gitPath?: string\n): Map<string, IFileDiffStatus> {\n const rootDirectory: string = getRepoRoot(currentWorkingDirectory, gitPath);\n\n const result: child_process.SpawnSyncReturns<string> = Executable.spawnSync(\n gitPath || 'git',\n STANDARD_GIT_OPTIONS.concat([\n 'diff-index',\n '--color=never',\n '--no-renames',\n '--no-commit-id',\n '--cached',\n '-z',\n revision,\n '--'\n ]),\n {\n currentWorkingDirectory: rootDirectory\n }\n );\n\n if (result.status !== 0) {\n ensureGitMinimumVersion(gitPath);\n\n throw new Error(`git diff-index exited with status ${result.status}: ${result.stderr}`);\n }\n\n const changes: Map<string, IFileDiffStatus> = parseGitDiffIndex(result.stdout);\n\n return changes;\n}\n\n/**\n * Checks the git version and throws an error if it is less than the minimum required version.\n *\n * @public\n */\nexport function ensureGitMinimumVersion(gitPath?: string): void {\n const gitVersion: IGitVersion = getGitVersion(gitPath);\n if (\n gitVersion.major < MINIMUM_GIT_VERSION.major ||\n (gitVersion.major === MINIMUM_GIT_VERSION.major && gitVersion.minor < MINIMUM_GIT_VERSION.minor) ||\n (gitVersion.major === MINIMUM_GIT_VERSION.major &&\n gitVersion.minor === MINIMUM_GIT_VERSION.minor &&\n gitVersion.patch < MINIMUM_GIT_VERSION.patch)\n ) {\n throw new Error(\n `The minimum Git version required is ` +\n `${MINIMUM_GIT_VERSION.major}.${MINIMUM_GIT_VERSION.minor}.${MINIMUM_GIT_VERSION.patch}. ` +\n `Your version is ${gitVersion.major}.${gitVersion.minor}.${gitVersion.patch}.`\n );\n }\n}\n\nfunction getGitVersion(gitPath?: string): IGitVersion {\n const result: child_process.SpawnSyncReturns<string> = Executable.spawnSync(\n gitPath || 'git',\n STANDARD_GIT_OPTIONS.concat(['version'])\n );\n\n if (result.status !== 0) {\n throw new Error(\n `While validating the Git installation, the \"git version\" command failed with ` +\n `status ${result.status}: ${result.stderr}`\n );\n }\n\n return parseGitVersion(result.stdout);\n}\n\nexport function parseGitVersion(gitVersionOutput: string): IGitVersion {\n // This regexp matches output of \"git version\" that looks like `git version <number>.<number>.<number>(+whatever)`\n // Examples:\n // - git version 1.2.3\n // - git version 1.2.3.4.5\n // - git version 1.2.3windows.1\n // - git version 1.2.3.windows.1\n const versionRegex: RegExp = /^git version (\\d+)\\.(\\d+)\\.(\\d+)/;\n const match: RegExpMatchArray | null = versionRegex.exec(gitVersionOutput);\n if (!match) {\n throw new Error(\n `While validating the Git installation, the \"git version\" command produced ` +\n `unexpected output: \"${gitVersionOutput}\"`\n );\n }\n\n const major: number = parseInt(match[1], 10);\n const minor: number = parseInt(match[2], 10);\n const patch: number = parseInt(match[3], 10);\n\n return {\n major,\n minor,\n patch\n };\n}\n"]}
1
+ {"version":3,"file":"getRepoState.js","sourceRoot":"","sources":["../src/getRepoState.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport type * as child_process from 'node:child_process';\nimport { once } from 'node:events';\nimport { Readable, pipeline } from 'node:stream';\n\nimport { Executable, type IExecutableSpawnOptions } from '@rushstack/node-core-library/lib/Executable';\nimport { FileSystem } from '@rushstack/node-core-library/lib/FileSystem';\n\nexport interface IGitVersion {\n major: number;\n minor: number;\n patch: number;\n}\n\nconst MINIMUM_GIT_VERSION: IGitVersion = {\n major: 2,\n minor: 35,\n patch: 0\n};\n\nconst STANDARD_GIT_OPTIONS: readonly string[] = [\n // Don't request any optional file locks\n '--no-optional-locks',\n // Ensure that commands don't run automatic maintenance, since performance of the command itself is paramount\n '-c',\n 'maintenance.auto=false'\n];\n\n// Windows reserved device names (case-insensitive). A file whose final path segment matches one\n// of these (with or without an extension) cannot be opened by name on Windows, so passing it to\n// `git hash-object` aborts the process. Such files are typically untracked artifacts left behind\n// by tooling (e.g. stray `nul` from a shell redirect).\nconst WINDOWS_RESERVED_BASENAMES: ReadonlySet<string> = new Set([\n 'CON', 'PRN', 'AUX', 'NUL',\n 'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9',\n 'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9'\n]);\n\n/**\n * Returns `true` if `filePath`'s final path segment is a Windows reserved device name\n * (with or without an extension), case-insensitively. Exported for tests.\n * @internal\n */\nexport function isWindowsReservedPath(filePath: string): boolean {\n const lastSlash: number = Math.max(filePath.lastIndexOf('/'), filePath.lastIndexOf('\\\\'));\n const basename: string = lastSlash >= 0 ? filePath.slice(lastSlash + 1) : filePath;\n const dot: number = basename.indexOf('.');\n const stem: string = (dot >= 0 ? basename.slice(0, dot) : basename).toUpperCase();\n return WINDOWS_RESERVED_BASENAMES.has(stem);\n}\n\nconst OBJECTMODE_SUBMODULE: '160000' = '160000';\nconst OBJECTMODE_SYMLINK: '120000' = '120000';\nconst OBJECTMODE_FILE_NONEXECUTABLE: '100644' = '100644';\nconst OBJECTMODE_FILE_EXECUTABLE: '100755' = '100755';\n\n// Note that `type` is a stub that is being ignored by the parser in favor of using `mode` to infer, since `%(objecttype)` requires git 2.51.0+\n// e.g. 10644 blob <hash>\\t<path>\nconst GIT_LSTREE_FORMAT: string = '%(objectmode) type %(objectname)%x09%(path)';\n\ninterface IGitTreeState {\n files: Map<string, string>; // type \"blob\"\n symlinks: Map<string, string>; // type \"link\"\n submodules: Map<string, string>; // type \"commit\"\n}\n\n/**\n * Parses the output of the \"git ls-tree -r -z\" command or of other commands that have been coerced to match its format.\n * @internal\n */\nexport function parseGitLsTree(output: string): IGitTreeState {\n const files: Map<string, string> = new Map();\n const symlinks: Map<string, string> = new Map();\n const submodules: Map<string, string> = new Map();\n\n // Parse the output\n // With the -z modifier, paths are delimited by nulls\n // A line looks like:\n // <mode> <type> <newhash>\\t<path>\\0\n // 100644 blob a300ccb0b36bd2c85ef18e3c619a2c747f95959e\\ttools/prettier-git/prettier-git.js\\0\n\n let last: number = 0;\n let index: number = output.indexOf('\\0', last);\n while (index >= 0) {\n const item: string = output.slice(last, index);\n\n const tabIndex: number = item.indexOf('\\t');\n const filePath: string = item.slice(tabIndex + 1);\n\n // The newHash will be all zeros if the file is deleted, or a hash if it exists\n const hash: string = item.slice(tabIndex - 40, tabIndex);\n\n const mode: string = item.slice(0, item.indexOf(' '));\n\n switch (mode) {\n case OBJECTMODE_SUBMODULE: {\n // This is a submodule\n submodules.set(filePath, hash);\n break;\n }\n case OBJECTMODE_SYMLINK: {\n // This is a symbolic link\n symlinks.set(filePath, hash);\n break;\n }\n case OBJECTMODE_FILE_NONEXECUTABLE:\n case OBJECTMODE_FILE_EXECUTABLE:\n default: {\n files.set(filePath, hash);\n break;\n }\n }\n\n last = index + 1;\n index = output.indexOf('\\0', last);\n }\n\n return {\n files,\n symlinks,\n submodules\n };\n}\n\n/**\n * Parses the output of `git hash-object`\n * yields [filePath, hash] pairs.\n * @internal\n */\nexport function* parseGitHashObject(\n output: string,\n filePaths: ReadonlyArray<string>\n): IterableIterator<[string, string]> {\n const expected: number = filePaths.length;\n if (expected === 0) {\n return;\n }\n\n output = output.trim();\n\n let last: number = 0;\n let i: number = 0;\n let index: number = output.indexOf('\\n', last);\n for (; i < expected && index > 0; i++) {\n const hash: string = output.slice(last, index);\n yield [filePaths[i], hash];\n last = index + 1;\n index = output.indexOf('\\n', last);\n }\n\n // Handle last line. Will be non-empty to due trim() call.\n if (index < 0) {\n const hash: string = output.slice(last);\n yield [filePaths[i], hash];\n i++;\n }\n\n if (i !== expected) {\n throw new Error(`Expected ${expected} hashes from \"git hash-object\" but received ${i}`);\n }\n}\n\n/**\n * Information about the changes to a file.\n * @beta\n */\nexport interface IFileDiffStatus {\n mode: string;\n oldhash: string;\n newhash: string;\n status: 'A' | 'D' | 'M';\n}\n\n/**\n * Parses the output of `git diff-index --color=never --no-renames --no-commit-id -z <REVISION> --\n * Returns a map of file path to diff\n * @internal\n */\nexport function parseGitDiffIndex(output: string): Map<string, IFileDiffStatus> {\n const result: Map<string, IFileDiffStatus> = new Map();\n\n // Parse the output\n // With the -z modifier, paths are delimited by nulls\n // A line looks like:\n // :<oldmode> <newmode> <oldhash> <newhash> <status>\\0<path>\\0\n // :100644 100644 a300ccb0b36bd2c85ef18e3c619a2c747f95959e 0000000000000000000000000000000000000000 M\\0tools/prettier-git/prettier-git.js\\0\n\n let last: number = 0;\n let index: number = output.indexOf('\\0', last);\n while (index >= 0) {\n const header: string = output.slice(last, index);\n const status: IFileDiffStatus['status'] = header.slice(-1) as IFileDiffStatus['status'];\n\n last = index + 1;\n index = output.indexOf('\\0', last);\n const filePath: string = output.slice(last, index);\n\n // We passed --no-renames above, so a rename will be a delete of the old location and an add at the new.\n // The newHash will be all zeros if the file is deleted, or a hash if it exists\n const mode: string = header.slice(8, 14);\n const oldhash: string = header.slice(-83, -43);\n const newhash: string = header.slice(-42, -2);\n result.set(filePath, {\n mode,\n oldhash,\n newhash,\n status\n });\n\n last = index + 1;\n index = output.indexOf('\\0', last);\n }\n\n return result;\n}\n\n/**\n * Parses the output of `git status -z -u` to extract the set of files that have changed since HEAD.\n *\n * @param output - The raw output from Git\n * @returns a map of file path to if it exists\n * @internal\n */\nexport function parseGitStatus(output: string): Map<string, boolean> {\n const result: Map<string, boolean> = new Map();\n\n // Parse the output\n // With the -z modifier, paths are delimited by nulls\n // A line looks like:\n // XY <path>\\0\n // M tools/prettier-git/prettier-git.js\\0\n\n let startOfLine: number = 0;\n let eolIndex: number = output.indexOf('\\0', startOfLine);\n while (eolIndex >= 0) {\n // We passed --no-renames above, so a rename will be a delete of the old location and an add at the new.\n // charAt(startOfLine) is the index status, charAt(startOfLine + 1) is the working tree status\n const workingTreeStatus: string = output.charAt(startOfLine + 1);\n // Deleted in working tree, or not modified in working tree and deleted in index\n const deleted: boolean =\n workingTreeStatus === 'D' || (workingTreeStatus === ' ' && output.charAt(startOfLine) === 'D');\n\n const filePath: string = output.slice(startOfLine + 3, eolIndex);\n result.set(filePath, !deleted);\n\n startOfLine = eolIndex + 1;\n eolIndex = output.indexOf('\\0', startOfLine);\n }\n\n return result;\n}\n\nconst repoRootCache: Map<string, string> = new Map();\n\n/**\n * Finds the root of the current Git repository\n *\n * @param currentWorkingDirectory - The working directory for which to locate the repository\n * @param gitPath - The path to the Git executable\n *\n * @returns The full path to the root directory of the Git repository\n * @beta\n */\nexport function getRepoRoot(currentWorkingDirectory: string, gitPath?: string): string {\n let cachedResult: string | undefined = repoRootCache.get(currentWorkingDirectory);\n if (!cachedResult) {\n const result: child_process.SpawnSyncReturns<string> = Executable.spawnSync(\n gitPath || 'git',\n ['--no-optional-locks', 'rev-parse', '--show-toplevel'],\n {\n currentWorkingDirectory\n }\n );\n\n if (result.status !== 0) {\n ensureGitMinimumVersion(gitPath);\n\n throw new Error(`git rev-parse exited with status ${result.status}: ${result.stderr}`);\n }\n\n cachedResult = result.stdout.trim();\n\n repoRootCache.set(currentWorkingDirectory, cachedResult);\n // To ensure that calling getRepoRoot on the result is a no-op.\n repoRootCache.set(cachedResult, cachedResult);\n }\n\n return cachedResult;\n}\n\n/**\n * Helper function for async process invocation with optional stdin support.\n * @param gitPath - Path to the Git executable\n * @param args - The process arguments\n * @param currentWorkingDirectory - The working directory. Should be the repository root.\n * @param stdin - An optional Readable stream to use as stdin to the process.\n */\nasync function spawnGitAsync(\n gitPath: string | undefined,\n args: string[],\n currentWorkingDirectory: string,\n stdin?: Readable\n): Promise<string> {\n const spawnOptions: IExecutableSpawnOptions = {\n currentWorkingDirectory,\n stdio: ['pipe', 'pipe', 'pipe']\n };\n\n let stdout: string = '';\n let stderr: string = '';\n\n const proc: child_process.ChildProcess = Executable.spawn(gitPath || 'git', args, spawnOptions);\n proc.stdout!.setEncoding('utf-8');\n proc.stderr!.setEncoding('utf-8');\n\n proc.stdout!.on('data', (chunk: string) => {\n stdout += chunk.toString();\n });\n proc.stderr!.on('data', (chunk: string) => {\n stderr += chunk.toString();\n });\n\n if (stdin) {\n /**\n * For `git hash-object` data is piped in asynchronously. In the event that one of the\n * passed filenames cannot be hashed, subsequent writes to `proc.stdin` will error.\n * Silence this error since it will be handled by the non-zero exit code of the process.\n */\n pipeline(stdin, proc.stdin!, (err) => {});\n }\n\n const [status] = await once(proc, 'close');\n if (status !== 0) {\n ensureGitMinimumVersion(gitPath);\n\n throw new Error(`git ${args[0]} exited with code ${status}:\\n${stderr}`);\n }\n\n return stdout;\n}\n\nfunction isIterable<T>(value: Iterable<T> | AsyncIterable<T>): value is Iterable<T> {\n return Symbol.iterator in value;\n}\n\n/**\n * Uses `git hash-object` to hash the provided files. Unlike `getGitHashForFiles`, this API is asynchronous, and also allows for\n * the input file paths to be specified as an async iterable.\n *\n * @param rootDirectory - The root directory to which paths are specified relative. Must be the root of the Git repository.\n * @param filesToHash - The file paths to hash using `git hash-object`\n * @param gitPath - The path to the Git executable\n * @returns An iterable of [filePath, hash] pairs\n *\n * @remarks\n * The input file paths must be specified relative to the Git repository root, or else be absolute paths.\n * @beta\n */\nexport async function hashFilesAsync(\n rootDirectory: string,\n filesToHash: Iterable<string> | AsyncIterable<string>,\n gitPath?: string\n): Promise<Iterable<[string, string]>> {\n const hashPaths: string[] = [];\n\n const input: Readable = Readable.from(\n isIterable(filesToHash)\n ? (function* (): IterableIterator<string> {\n for (const file of filesToHash) {\n hashPaths.push(file);\n yield `${file}\\n`;\n }\n })()\n : (async function* (): AsyncIterableIterator<string> {\n for await (const file of filesToHash) {\n hashPaths.push(file);\n yield `${file}\\n`;\n }\n })(),\n {\n encoding: 'utf-8',\n objectMode: false,\n autoDestroy: true\n }\n );\n\n const hashObjectResult: string = await spawnGitAsync(\n gitPath,\n STANDARD_GIT_OPTIONS.concat(['hash-object', '--stdin-paths']),\n rootDirectory,\n input\n );\n\n return parseGitHashObject(hashObjectResult, hashPaths);\n}\n\n/**\n * Gets the object hashes for all files in the Git repo, combining the current commit with working tree state.\n * Uses async operations and runs all primary Git calls in parallel.\n * @param rootDirectory - The root directory of the Git repository\n * @param additionalRelativePathsToHash - Root-relative file paths to have Git hash and include in the results\n * @param gitPath - The path to the Git executable\n * @beta\n */\nexport async function getRepoStateAsync(\n rootDirectory: string,\n additionalRelativePathsToHash?: string[],\n gitPath?: string,\n filterPath?: string[]\n): Promise<Map<string, string>> {\n const { files } = await getDetailedRepoStateAsync(\n rootDirectory,\n additionalRelativePathsToHash,\n gitPath,\n filterPath\n );\n\n return files;\n}\n\n/**\n * Information about the detailed state of the Git repository.\n * @beta\n */\nexport interface IDetailedRepoState {\n /**\n * The Git file hashes for all files in the repository, including uncommitted changes.\n */\n files: Map<string, string>;\n /**\n * The Git file hashes for all symbolic links in the repository, including uncommitted changes.\n */\n symlinks: Map<string, string>;\n /**\n * A boolean indicating whether the repository has submodules.\n */\n hasSubmodules: boolean;\n /**\n * A boolean indicating whether the repository has uncommitted changes.\n */\n hasUncommittedChanges: boolean;\n}\n\n/**\n * Gets the object hashes for all files in the Git repo, combining the current commit with working tree state.\n * Uses async operations and runs all primary Git calls in parallel.\n * @param rootDirectory - The root directory of the Git repository\n * @param additionalRelativePathsToHash - Root-relative file paths to have Git hash and include in the results\n * @param gitPath - The path to the Git executable\n * @beta\n */\nexport async function getDetailedRepoStateAsync(\n rootDirectory: string,\n additionalRelativePathsToHash?: string[],\n gitPath?: string,\n filterPath?: string[]\n): Promise<IDetailedRepoState> {\n const statePromise: Promise<IGitTreeState> = spawnGitAsync(\n gitPath,\n STANDARD_GIT_OPTIONS.concat([\n 'ls-files',\n // Read from the index only\n '--cached',\n // Use NUL as the separator\n '-z',\n // Specify the full path to files relative to the root\n '--full-name',\n // Match the format of \"git ls-tree\". The %(objecttype) placeholder requires git 2.51.0+, so not using yet.\n `--format=${GIT_LSTREE_FORMAT}`,\n '--',\n ...(filterPath ?? [])\n ]),\n rootDirectory\n ).then(parseGitLsTree);\n const locallyModifiedPromise: Promise<Map<string, boolean>> = spawnGitAsync(\n gitPath,\n STANDARD_GIT_OPTIONS.concat([\n 'status',\n // Use NUL as the separator\n '-z',\n // Include untracked files\n '-u',\n // Disable rename detection so that renames show up as add + delete\n '--no-renames',\n // Don't process submodules with this command; they'll be handled individually\n '--ignore-submodules',\n // Don't compare against the remote\n '--no-ahead-behind',\n '--',\n ...(filterPath ?? [])\n ]),\n rootDirectory\n ).then(parseGitStatus);\n\n async function* getFilesToHash(): AsyncIterableIterator<string> {\n if (additionalRelativePathsToHash) {\n for (const file of additionalRelativePathsToHash) {\n yield file;\n }\n }\n\n const [{ files, symlinks }, locallyModified] = await Promise.all([statePromise, locallyModifiedPromise]);\n\n const isWindows: boolean = process.platform === 'win32';\n for (const [filePath, exists] of locallyModified) {\n if (exists && !symlinks.has(filePath)) {\n // Skip Windows reserved device names. `git hash-object` cannot open them and would abort\n // the entire repo-state computation. These are almost always stray artifacts (e.g. a `nul`\n // file produced by a misdirected shell redirect) rather than meaningful inputs.\n if (isWindows && isWindowsReservedPath(filePath)) {\n continue;\n }\n yield filePath;\n } else {\n files.delete(filePath);\n symlinks.delete(filePath);\n }\n }\n }\n\n const hashObjectPromise: Promise<Iterable<[string, string]>> = hashFilesAsync(\n rootDirectory,\n getFilesToHash(),\n gitPath\n );\n\n const [{ files, symlinks, submodules }, locallyModifiedFiles] = await Promise.all([\n statePromise,\n locallyModifiedPromise\n ]);\n\n // The result of \"git hash-object\" will be a list of file hashes delimited by newlines\n for (const [filePath, hash] of await hashObjectPromise) {\n files.set(filePath, hash);\n }\n\n // Existence check for the .gitmodules file\n const hasSubmodules: boolean = submodules.size > 0 && FileSystem.exists(`${rootDirectory}/.gitmodules`);\n\n if (hasSubmodules) {\n // Submodules are not the normal critical path. Accept serial performance rather than investing in complexity.\n // Can revisit if submodules become more commonly used.\n for (const submodulePath of submodules.keys()) {\n const submoduleState: Map<string, string> = await getRepoStateAsync(\n `${rootDirectory}/${submodulePath}`,\n [],\n gitPath\n );\n for (const [filePath, hash] of submoduleState) {\n files.set(`${submodulePath}/${filePath}`, hash);\n }\n }\n }\n\n return {\n hasSubmodules,\n hasUncommittedChanges: locallyModifiedFiles.size > 0,\n files,\n symlinks\n };\n}\n\n/**\n * Find all changed files tracked by Git, their current hashes, and the nature of the change. Only useful if all changes are staged or committed.\n * @param currentWorkingDirectory - The working directory. Only used to find the repository root.\n * @param revision - The Git revision specifier to detect changes relative to. Defaults to HEAD (i.e. will compare staged vs. committed)\n * If comparing against a different branch, call `git merge-base` first to find the target commit.\n * @param gitPath - The path to the Git executable\n * @returns A map from the Git file path to the corresponding file change metadata\n * @beta\n */\nexport function getRepoChanges(\n currentWorkingDirectory: string,\n revision: string = 'HEAD',\n gitPath?: string\n): Map<string, IFileDiffStatus> {\n const rootDirectory: string = getRepoRoot(currentWorkingDirectory, gitPath);\n\n const result: child_process.SpawnSyncReturns<string> = Executable.spawnSync(\n gitPath || 'git',\n STANDARD_GIT_OPTIONS.concat([\n 'diff-index',\n '--color=never',\n '--no-renames',\n '--no-commit-id',\n '--cached',\n '-z',\n revision,\n '--'\n ]),\n {\n currentWorkingDirectory: rootDirectory\n }\n );\n\n if (result.status !== 0) {\n ensureGitMinimumVersion(gitPath);\n\n throw new Error(`git diff-index exited with status ${result.status}: ${result.stderr}`);\n }\n\n const changes: Map<string, IFileDiffStatus> = parseGitDiffIndex(result.stdout);\n\n return changes;\n}\n\n/**\n * Checks the git version and throws an error if it is less than the minimum required version.\n *\n * @public\n */\nexport function ensureGitMinimumVersion(gitPath?: string): void {\n const gitVersion: IGitVersion = getGitVersion(gitPath);\n if (\n gitVersion.major < MINIMUM_GIT_VERSION.major ||\n (gitVersion.major === MINIMUM_GIT_VERSION.major && gitVersion.minor < MINIMUM_GIT_VERSION.minor) ||\n (gitVersion.major === MINIMUM_GIT_VERSION.major &&\n gitVersion.minor === MINIMUM_GIT_VERSION.minor &&\n gitVersion.patch < MINIMUM_GIT_VERSION.patch)\n ) {\n throw new Error(\n `The minimum Git version required is ` +\n `${MINIMUM_GIT_VERSION.major}.${MINIMUM_GIT_VERSION.minor}.${MINIMUM_GIT_VERSION.patch}. ` +\n `Your version is ${gitVersion.major}.${gitVersion.minor}.${gitVersion.patch}.`\n );\n }\n}\n\nfunction getGitVersion(gitPath?: string): IGitVersion {\n const result: child_process.SpawnSyncReturns<string> = Executable.spawnSync(\n gitPath || 'git',\n STANDARD_GIT_OPTIONS.concat(['version'])\n );\n\n if (result.status !== 0) {\n throw new Error(\n `While validating the Git installation, the \"git version\" command failed with ` +\n `status ${result.status}: ${result.stderr}`\n );\n }\n\n return parseGitVersion(result.stdout);\n}\n\nexport function parseGitVersion(gitVersionOutput: string): IGitVersion {\n // This regexp matches output of \"git version\" that looks like `git version <number>.<number>.<number>(+whatever)`\n // Examples:\n // - git version 1.2.3\n // - git version 1.2.3.4.5\n // - git version 1.2.3windows.1\n // - git version 1.2.3.windows.1\n const versionRegex: RegExp = /^git version (\\d+)\\.(\\d+)\\.(\\d+)/;\n const match: RegExpMatchArray | null = versionRegex.exec(gitVersionOutput);\n if (!match) {\n throw new Error(\n `While validating the Git installation, the \"git version\" command produced ` +\n `unexpected output: \"${gitVersionOutput}\"`\n );\n }\n\n const major: number = parseInt(match[1], 10);\n const minor: number = parseInt(match[2], 10);\n const patch: number = parseInt(match[3], 10);\n\n return {\n major,\n minor,\n patch\n };\n}\n"]}
@@ -3,6 +3,12 @@ export interface IGitVersion {
3
3
  minor: number;
4
4
  patch: number;
5
5
  }
6
+ /**
7
+ * Returns `true` if `filePath`'s final path segment is a Windows reserved device name
8
+ * (with or without an extension), case-insensitively. Exported for tests.
9
+ * @internal
10
+ */
11
+ export declare function isWindowsReservedPath(filePath: string): boolean;
6
12
  interface IGitTreeState {
7
13
  files: Map<string, string>;
8
14
  symlinks: Map<string, string>;
@@ -1 +1 @@
1
- {"version":3,"file":"getRepoState.d.ts","sourceRoot":"","sources":["../src/getRepoState.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"getRepoState.d.ts","sourceRoot":"","sources":["../src/getRepoState.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,27 @@ const STANDARD_GIT_OPTIONS = [
16
16
  '-c',
17
17
  'maintenance.auto=false'
18
18
  ];
19
+ // Windows reserved device names (case-insensitive). A file whose final path segment matches one
20
+ // of these (with or without an extension) cannot be opened by name on Windows, so passing it to
21
+ // `git hash-object` aborts the process. Such files are typically untracked artifacts left behind
22
+ // by tooling (e.g. stray `nul` from a shell redirect).
23
+ const WINDOWS_RESERVED_BASENAMES = new Set([
24
+ 'CON', 'PRN', 'AUX', 'NUL',
25
+ 'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9',
26
+ 'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9'
27
+ ]);
28
+ /**
29
+ * Returns `true` if `filePath`'s final path segment is a Windows reserved device name
30
+ * (with or without an extension), case-insensitively. Exported for tests.
31
+ * @internal
32
+ */
33
+ export function isWindowsReservedPath(filePath) {
34
+ const lastSlash = Math.max(filePath.lastIndexOf('/'), filePath.lastIndexOf('\\'));
35
+ const basename = lastSlash >= 0 ? filePath.slice(lastSlash + 1) : filePath;
36
+ const dot = basename.indexOf('.');
37
+ const stem = (dot >= 0 ? basename.slice(0, dot) : basename).toUpperCase();
38
+ return WINDOWS_RESERVED_BASENAMES.has(stem);
39
+ }
19
40
  const OBJECTMODE_SUBMODULE = '160000';
20
41
  const OBJECTMODE_SYMLINK = '120000';
21
42
  const OBJECTMODE_FILE_NONEXECUTABLE = '100644';
@@ -326,8 +347,15 @@ export async function getDetailedRepoStateAsync(rootDirectory, additionalRelativ
326
347
  }
327
348
  }
328
349
  const [{ files, symlinks }, locallyModified] = await Promise.all([statePromise, locallyModifiedPromise]);
350
+ const isWindows = process.platform === 'win32';
329
351
  for (const [filePath, exists] of locallyModified) {
330
352
  if (exists && !symlinks.has(filePath)) {
353
+ // Skip Windows reserved device names. `git hash-object` cannot open them and would abort
354
+ // the entire repo-state computation. These are almost always stray artifacts (e.g. a `nul`
355
+ // file produced by a misdirected shell redirect) rather than meaningful inputs.
356
+ if (isWindows && isWindowsReservedPath(filePath)) {
357
+ continue;
358
+ }
331
359
  yield filePath;
332
360
  }
333
361
  else {
@@ -1 +1 @@
1
- {"version":3,"file":"getRepoState.js","sourceRoot":"","sources":["../src/getRepoState.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport type * as child_process from 'node:child_process';\nimport { once } from 'node:events';\nimport { Readable, pipeline } from 'node:stream';\n\nimport { Executable, type IExecutableSpawnOptions } from '@rushstack/node-core-library/lib/Executable';\nimport { FileSystem } from '@rushstack/node-core-library/lib/FileSystem';\n\nexport interface IGitVersion {\n major: number;\n minor: number;\n patch: number;\n}\n\nconst MINIMUM_GIT_VERSION: IGitVersion = {\n major: 2,\n minor: 35,\n patch: 0\n};\n\nconst STANDARD_GIT_OPTIONS: readonly string[] = [\n // Don't request any optional file locks\n '--no-optional-locks',\n // Ensure that commands don't run automatic maintenance, since performance of the command itself is paramount\n '-c',\n 'maintenance.auto=false'\n];\n\nconst OBJECTMODE_SUBMODULE: '160000' = '160000';\nconst OBJECTMODE_SYMLINK: '120000' = '120000';\nconst OBJECTMODE_FILE_NONEXECUTABLE: '100644' = '100644';\nconst OBJECTMODE_FILE_EXECUTABLE: '100755' = '100755';\n\n// Note that `type` is a stub that is being ignored by the parser in favor of using `mode` to infer, since `%(objecttype)` requires git 2.51.0+\n// e.g. 10644 blob <hash>\\t<path>\nconst GIT_LSTREE_FORMAT: string = '%(objectmode) type %(objectname)%x09%(path)';\n\ninterface IGitTreeState {\n files: Map<string, string>; // type \"blob\"\n symlinks: Map<string, string>; // type \"link\"\n submodules: Map<string, string>; // type \"commit\"\n}\n\n/**\n * Parses the output of the \"git ls-tree -r -z\" command or of other commands that have been coerced to match its format.\n * @internal\n */\nexport function parseGitLsTree(output: string): IGitTreeState {\n const files: Map<string, string> = new Map();\n const symlinks: Map<string, string> = new Map();\n const submodules: Map<string, string> = new Map();\n\n // Parse the output\n // With the -z modifier, paths are delimited by nulls\n // A line looks like:\n // <mode> <type> <newhash>\\t<path>\\0\n // 100644 blob a300ccb0b36bd2c85ef18e3c619a2c747f95959e\\ttools/prettier-git/prettier-git.js\\0\n\n let last: number = 0;\n let index: number = output.indexOf('\\0', last);\n while (index >= 0) {\n const item: string = output.slice(last, index);\n\n const tabIndex: number = item.indexOf('\\t');\n const filePath: string = item.slice(tabIndex + 1);\n\n // The newHash will be all zeros if the file is deleted, or a hash if it exists\n const hash: string = item.slice(tabIndex - 40, tabIndex);\n\n const mode: string = item.slice(0, item.indexOf(' '));\n\n switch (mode) {\n case OBJECTMODE_SUBMODULE: {\n // This is a submodule\n submodules.set(filePath, hash);\n break;\n }\n case OBJECTMODE_SYMLINK: {\n // This is a symbolic link\n symlinks.set(filePath, hash);\n break;\n }\n case OBJECTMODE_FILE_NONEXECUTABLE:\n case OBJECTMODE_FILE_EXECUTABLE:\n default: {\n files.set(filePath, hash);\n break;\n }\n }\n\n last = index + 1;\n index = output.indexOf('\\0', last);\n }\n\n return {\n files,\n symlinks,\n submodules\n };\n}\n\n/**\n * Parses the output of `git hash-object`\n * yields [filePath, hash] pairs.\n * @internal\n */\nexport function* parseGitHashObject(\n output: string,\n filePaths: ReadonlyArray<string>\n): IterableIterator<[string, string]> {\n const expected: number = filePaths.length;\n if (expected === 0) {\n return;\n }\n\n output = output.trim();\n\n let last: number = 0;\n let i: number = 0;\n let index: number = output.indexOf('\\n', last);\n for (; i < expected && index > 0; i++) {\n const hash: string = output.slice(last, index);\n yield [filePaths[i], hash];\n last = index + 1;\n index = output.indexOf('\\n', last);\n }\n\n // Handle last line. Will be non-empty to due trim() call.\n if (index < 0) {\n const hash: string = output.slice(last);\n yield [filePaths[i], hash];\n i++;\n }\n\n if (i !== expected) {\n throw new Error(`Expected ${expected} hashes from \"git hash-object\" but received ${i}`);\n }\n}\n\n/**\n * Information about the changes to a file.\n * @beta\n */\nexport interface IFileDiffStatus {\n mode: string;\n oldhash: string;\n newhash: string;\n status: 'A' | 'D' | 'M';\n}\n\n/**\n * Parses the output of `git diff-index --color=never --no-renames --no-commit-id -z <REVISION> --\n * Returns a map of file path to diff\n * @internal\n */\nexport function parseGitDiffIndex(output: string): Map<string, IFileDiffStatus> {\n const result: Map<string, IFileDiffStatus> = new Map();\n\n // Parse the output\n // With the -z modifier, paths are delimited by nulls\n // A line looks like:\n // :<oldmode> <newmode> <oldhash> <newhash> <status>\\0<path>\\0\n // :100644 100644 a300ccb0b36bd2c85ef18e3c619a2c747f95959e 0000000000000000000000000000000000000000 M\\0tools/prettier-git/prettier-git.js\\0\n\n let last: number = 0;\n let index: number = output.indexOf('\\0', last);\n while (index >= 0) {\n const header: string = output.slice(last, index);\n const status: IFileDiffStatus['status'] = header.slice(-1) as IFileDiffStatus['status'];\n\n last = index + 1;\n index = output.indexOf('\\0', last);\n const filePath: string = output.slice(last, index);\n\n // We passed --no-renames above, so a rename will be a delete of the old location and an add at the new.\n // The newHash will be all zeros if the file is deleted, or a hash if it exists\n const mode: string = header.slice(8, 14);\n const oldhash: string = header.slice(-83, -43);\n const newhash: string = header.slice(-42, -2);\n result.set(filePath, {\n mode,\n oldhash,\n newhash,\n status\n });\n\n last = index + 1;\n index = output.indexOf('\\0', last);\n }\n\n return result;\n}\n\n/**\n * Parses the output of `git status -z -u` to extract the set of files that have changed since HEAD.\n *\n * @param output - The raw output from Git\n * @returns a map of file path to if it exists\n * @internal\n */\nexport function parseGitStatus(output: string): Map<string, boolean> {\n const result: Map<string, boolean> = new Map();\n\n // Parse the output\n // With the -z modifier, paths are delimited by nulls\n // A line looks like:\n // XY <path>\\0\n // M tools/prettier-git/prettier-git.js\\0\n\n let startOfLine: number = 0;\n let eolIndex: number = output.indexOf('\\0', startOfLine);\n while (eolIndex >= 0) {\n // We passed --no-renames above, so a rename will be a delete of the old location and an add at the new.\n // charAt(startOfLine) is the index status, charAt(startOfLine + 1) is the working tree status\n const workingTreeStatus: string = output.charAt(startOfLine + 1);\n // Deleted in working tree, or not modified in working tree and deleted in index\n const deleted: boolean =\n workingTreeStatus === 'D' || (workingTreeStatus === ' ' && output.charAt(startOfLine) === 'D');\n\n const filePath: string = output.slice(startOfLine + 3, eolIndex);\n result.set(filePath, !deleted);\n\n startOfLine = eolIndex + 1;\n eolIndex = output.indexOf('\\0', startOfLine);\n }\n\n return result;\n}\n\nconst repoRootCache: Map<string, string> = new Map();\n\n/**\n * Finds the root of the current Git repository\n *\n * @param currentWorkingDirectory - The working directory for which to locate the repository\n * @param gitPath - The path to the Git executable\n *\n * @returns The full path to the root directory of the Git repository\n * @beta\n */\nexport function getRepoRoot(currentWorkingDirectory: string, gitPath?: string): string {\n let cachedResult: string | undefined = repoRootCache.get(currentWorkingDirectory);\n if (!cachedResult) {\n const result: child_process.SpawnSyncReturns<string> = Executable.spawnSync(\n gitPath || 'git',\n ['--no-optional-locks', 'rev-parse', '--show-toplevel'],\n {\n currentWorkingDirectory\n }\n );\n\n if (result.status !== 0) {\n ensureGitMinimumVersion(gitPath);\n\n throw new Error(`git rev-parse exited with status ${result.status}: ${result.stderr}`);\n }\n\n cachedResult = result.stdout.trim();\n\n repoRootCache.set(currentWorkingDirectory, cachedResult);\n // To ensure that calling getRepoRoot on the result is a no-op.\n repoRootCache.set(cachedResult, cachedResult);\n }\n\n return cachedResult;\n}\n\n/**\n * Helper function for async process invocation with optional stdin support.\n * @param gitPath - Path to the Git executable\n * @param args - The process arguments\n * @param currentWorkingDirectory - The working directory. Should be the repository root.\n * @param stdin - An optional Readable stream to use as stdin to the process.\n */\nasync function spawnGitAsync(\n gitPath: string | undefined,\n args: string[],\n currentWorkingDirectory: string,\n stdin?: Readable\n): Promise<string> {\n const spawnOptions: IExecutableSpawnOptions = {\n currentWorkingDirectory,\n stdio: ['pipe', 'pipe', 'pipe']\n };\n\n let stdout: string = '';\n let stderr: string = '';\n\n const proc: child_process.ChildProcess = Executable.spawn(gitPath || 'git', args, spawnOptions);\n proc.stdout!.setEncoding('utf-8');\n proc.stderr!.setEncoding('utf-8');\n\n proc.stdout!.on('data', (chunk: string) => {\n stdout += chunk.toString();\n });\n proc.stderr!.on('data', (chunk: string) => {\n stderr += chunk.toString();\n });\n\n if (stdin) {\n /**\n * For `git hash-object` data is piped in asynchronously. In the event that one of the\n * passed filenames cannot be hashed, subsequent writes to `proc.stdin` will error.\n * Silence this error since it will be handled by the non-zero exit code of the process.\n */\n pipeline(stdin, proc.stdin!, (err) => {});\n }\n\n const [status] = await once(proc, 'close');\n if (status !== 0) {\n ensureGitMinimumVersion(gitPath);\n\n throw new Error(`git ${args[0]} exited with code ${status}:\\n${stderr}`);\n }\n\n return stdout;\n}\n\nfunction isIterable<T>(value: Iterable<T> | AsyncIterable<T>): value is Iterable<T> {\n return Symbol.iterator in value;\n}\n\n/**\n * Uses `git hash-object` to hash the provided files. Unlike `getGitHashForFiles`, this API is asynchronous, and also allows for\n * the input file paths to be specified as an async iterable.\n *\n * @param rootDirectory - The root directory to which paths are specified relative. Must be the root of the Git repository.\n * @param filesToHash - The file paths to hash using `git hash-object`\n * @param gitPath - The path to the Git executable\n * @returns An iterable of [filePath, hash] pairs\n *\n * @remarks\n * The input file paths must be specified relative to the Git repository root, or else be absolute paths.\n * @beta\n */\nexport async function hashFilesAsync(\n rootDirectory: string,\n filesToHash: Iterable<string> | AsyncIterable<string>,\n gitPath?: string\n): Promise<Iterable<[string, string]>> {\n const hashPaths: string[] = [];\n\n const input: Readable = Readable.from(\n isIterable(filesToHash)\n ? (function* (): IterableIterator<string> {\n for (const file of filesToHash) {\n hashPaths.push(file);\n yield `${file}\\n`;\n }\n })()\n : (async function* (): AsyncIterableIterator<string> {\n for await (const file of filesToHash) {\n hashPaths.push(file);\n yield `${file}\\n`;\n }\n })(),\n {\n encoding: 'utf-8',\n objectMode: false,\n autoDestroy: true\n }\n );\n\n const hashObjectResult: string = await spawnGitAsync(\n gitPath,\n STANDARD_GIT_OPTIONS.concat(['hash-object', '--stdin-paths']),\n rootDirectory,\n input\n );\n\n return parseGitHashObject(hashObjectResult, hashPaths);\n}\n\n/**\n * Gets the object hashes for all files in the Git repo, combining the current commit with working tree state.\n * Uses async operations and runs all primary Git calls in parallel.\n * @param rootDirectory - The root directory of the Git repository\n * @param additionalRelativePathsToHash - Root-relative file paths to have Git hash and include in the results\n * @param gitPath - The path to the Git executable\n * @beta\n */\nexport async function getRepoStateAsync(\n rootDirectory: string,\n additionalRelativePathsToHash?: string[],\n gitPath?: string,\n filterPath?: string[]\n): Promise<Map<string, string>> {\n const { files } = await getDetailedRepoStateAsync(\n rootDirectory,\n additionalRelativePathsToHash,\n gitPath,\n filterPath\n );\n\n return files;\n}\n\n/**\n * Information about the detailed state of the Git repository.\n * @beta\n */\nexport interface IDetailedRepoState {\n /**\n * The Git file hashes for all files in the repository, including uncommitted changes.\n */\n files: Map<string, string>;\n /**\n * The Git file hashes for all symbolic links in the repository, including uncommitted changes.\n */\n symlinks: Map<string, string>;\n /**\n * A boolean indicating whether the repository has submodules.\n */\n hasSubmodules: boolean;\n /**\n * A boolean indicating whether the repository has uncommitted changes.\n */\n hasUncommittedChanges: boolean;\n}\n\n/**\n * Gets the object hashes for all files in the Git repo, combining the current commit with working tree state.\n * Uses async operations and runs all primary Git calls in parallel.\n * @param rootDirectory - The root directory of the Git repository\n * @param additionalRelativePathsToHash - Root-relative file paths to have Git hash and include in the results\n * @param gitPath - The path to the Git executable\n * @beta\n */\nexport async function getDetailedRepoStateAsync(\n rootDirectory: string,\n additionalRelativePathsToHash?: string[],\n gitPath?: string,\n filterPath?: string[]\n): Promise<IDetailedRepoState> {\n const statePromise: Promise<IGitTreeState> = spawnGitAsync(\n gitPath,\n STANDARD_GIT_OPTIONS.concat([\n 'ls-files',\n // Read from the index only\n '--cached',\n // Use NUL as the separator\n '-z',\n // Specify the full path to files relative to the root\n '--full-name',\n // Match the format of \"git ls-tree\". The %(objecttype) placeholder requires git 2.51.0+, so not using yet.\n `--format=${GIT_LSTREE_FORMAT}`,\n '--',\n ...(filterPath ?? [])\n ]),\n rootDirectory\n ).then(parseGitLsTree);\n const locallyModifiedPromise: Promise<Map<string, boolean>> = spawnGitAsync(\n gitPath,\n STANDARD_GIT_OPTIONS.concat([\n 'status',\n // Use NUL as the separator\n '-z',\n // Include untracked files\n '-u',\n // Disable rename detection so that renames show up as add + delete\n '--no-renames',\n // Don't process submodules with this command; they'll be handled individually\n '--ignore-submodules',\n // Don't compare against the remote\n '--no-ahead-behind',\n '--',\n ...(filterPath ?? [])\n ]),\n rootDirectory\n ).then(parseGitStatus);\n\n async function* getFilesToHash(): AsyncIterableIterator<string> {\n if (additionalRelativePathsToHash) {\n for (const file of additionalRelativePathsToHash) {\n yield file;\n }\n }\n\n const [{ files, symlinks }, locallyModified] = await Promise.all([statePromise, locallyModifiedPromise]);\n\n for (const [filePath, exists] of locallyModified) {\n if (exists && !symlinks.has(filePath)) {\n yield filePath;\n } else {\n files.delete(filePath);\n symlinks.delete(filePath);\n }\n }\n }\n\n const hashObjectPromise: Promise<Iterable<[string, string]>> = hashFilesAsync(\n rootDirectory,\n getFilesToHash(),\n gitPath\n );\n\n const [{ files, symlinks, submodules }, locallyModifiedFiles] = await Promise.all([\n statePromise,\n locallyModifiedPromise\n ]);\n\n // The result of \"git hash-object\" will be a list of file hashes delimited by newlines\n for (const [filePath, hash] of await hashObjectPromise) {\n files.set(filePath, hash);\n }\n\n // Existence check for the .gitmodules file\n const hasSubmodules: boolean = submodules.size > 0 && FileSystem.exists(`${rootDirectory}/.gitmodules`);\n\n if (hasSubmodules) {\n // Submodules are not the normal critical path. Accept serial performance rather than investing in complexity.\n // Can revisit if submodules become more commonly used.\n for (const submodulePath of submodules.keys()) {\n const submoduleState: Map<string, string> = await getRepoStateAsync(\n `${rootDirectory}/${submodulePath}`,\n [],\n gitPath\n );\n for (const [filePath, hash] of submoduleState) {\n files.set(`${submodulePath}/${filePath}`, hash);\n }\n }\n }\n\n return {\n hasSubmodules,\n hasUncommittedChanges: locallyModifiedFiles.size > 0,\n files,\n symlinks\n };\n}\n\n/**\n * Find all changed files tracked by Git, their current hashes, and the nature of the change. Only useful if all changes are staged or committed.\n * @param currentWorkingDirectory - The working directory. Only used to find the repository root.\n * @param revision - The Git revision specifier to detect changes relative to. Defaults to HEAD (i.e. will compare staged vs. committed)\n * If comparing against a different branch, call `git merge-base` first to find the target commit.\n * @param gitPath - The path to the Git executable\n * @returns A map from the Git file path to the corresponding file change metadata\n * @beta\n */\nexport function getRepoChanges(\n currentWorkingDirectory: string,\n revision: string = 'HEAD',\n gitPath?: string\n): Map<string, IFileDiffStatus> {\n const rootDirectory: string = getRepoRoot(currentWorkingDirectory, gitPath);\n\n const result: child_process.SpawnSyncReturns<string> = Executable.spawnSync(\n gitPath || 'git',\n STANDARD_GIT_OPTIONS.concat([\n 'diff-index',\n '--color=never',\n '--no-renames',\n '--no-commit-id',\n '--cached',\n '-z',\n revision,\n '--'\n ]),\n {\n currentWorkingDirectory: rootDirectory\n }\n );\n\n if (result.status !== 0) {\n ensureGitMinimumVersion(gitPath);\n\n throw new Error(`git diff-index exited with status ${result.status}: ${result.stderr}`);\n }\n\n const changes: Map<string, IFileDiffStatus> = parseGitDiffIndex(result.stdout);\n\n return changes;\n}\n\n/**\n * Checks the git version and throws an error if it is less than the minimum required version.\n *\n * @public\n */\nexport function ensureGitMinimumVersion(gitPath?: string): void {\n const gitVersion: IGitVersion = getGitVersion(gitPath);\n if (\n gitVersion.major < MINIMUM_GIT_VERSION.major ||\n (gitVersion.major === MINIMUM_GIT_VERSION.major && gitVersion.minor < MINIMUM_GIT_VERSION.minor) ||\n (gitVersion.major === MINIMUM_GIT_VERSION.major &&\n gitVersion.minor === MINIMUM_GIT_VERSION.minor &&\n gitVersion.patch < MINIMUM_GIT_VERSION.patch)\n ) {\n throw new Error(\n `The minimum Git version required is ` +\n `${MINIMUM_GIT_VERSION.major}.${MINIMUM_GIT_VERSION.minor}.${MINIMUM_GIT_VERSION.patch}. ` +\n `Your version is ${gitVersion.major}.${gitVersion.minor}.${gitVersion.patch}.`\n );\n }\n}\n\nfunction getGitVersion(gitPath?: string): IGitVersion {\n const result: child_process.SpawnSyncReturns<string> = Executable.spawnSync(\n gitPath || 'git',\n STANDARD_GIT_OPTIONS.concat(['version'])\n );\n\n if (result.status !== 0) {\n throw new Error(\n `While validating the Git installation, the \"git version\" command failed with ` +\n `status ${result.status}: ${result.stderr}`\n );\n }\n\n return parseGitVersion(result.stdout);\n}\n\nexport function parseGitVersion(gitVersionOutput: string): IGitVersion {\n // This regexp matches output of \"git version\" that looks like `git version <number>.<number>.<number>(+whatever)`\n // Examples:\n // - git version 1.2.3\n // - git version 1.2.3.4.5\n // - git version 1.2.3windows.1\n // - git version 1.2.3.windows.1\n const versionRegex: RegExp = /^git version (\\d+)\\.(\\d+)\\.(\\d+)/;\n const match: RegExpMatchArray | null = versionRegex.exec(gitVersionOutput);\n if (!match) {\n throw new Error(\n `While validating the Git installation, the \"git version\" command produced ` +\n `unexpected output: \"${gitVersionOutput}\"`\n );\n }\n\n const major: number = parseInt(match[1], 10);\n const minor: number = parseInt(match[2], 10);\n const patch: number = parseInt(match[3], 10);\n\n return {\n major,\n minor,\n patch\n };\n}\n"]}
1
+ {"version":3,"file":"getRepoState.js","sourceRoot":"","sources":["../src/getRepoState.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport type * as child_process from 'node:child_process';\nimport { once } from 'node:events';\nimport { Readable, pipeline } from 'node:stream';\n\nimport { Executable, type IExecutableSpawnOptions } from '@rushstack/node-core-library/lib/Executable';\nimport { FileSystem } from '@rushstack/node-core-library/lib/FileSystem';\n\nexport interface IGitVersion {\n major: number;\n minor: number;\n patch: number;\n}\n\nconst MINIMUM_GIT_VERSION: IGitVersion = {\n major: 2,\n minor: 35,\n patch: 0\n};\n\nconst STANDARD_GIT_OPTIONS: readonly string[] = [\n // Don't request any optional file locks\n '--no-optional-locks',\n // Ensure that commands don't run automatic maintenance, since performance of the command itself is paramount\n '-c',\n 'maintenance.auto=false'\n];\n\n// Windows reserved device names (case-insensitive). A file whose final path segment matches one\n// of these (with or without an extension) cannot be opened by name on Windows, so passing it to\n// `git hash-object` aborts the process. Such files are typically untracked artifacts left behind\n// by tooling (e.g. stray `nul` from a shell redirect).\nconst WINDOWS_RESERVED_BASENAMES: ReadonlySet<string> = new Set([\n 'CON', 'PRN', 'AUX', 'NUL',\n 'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9',\n 'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9'\n]);\n\n/**\n * Returns `true` if `filePath`'s final path segment is a Windows reserved device name\n * (with or without an extension), case-insensitively. Exported for tests.\n * @internal\n */\nexport function isWindowsReservedPath(filePath: string): boolean {\n const lastSlash: number = Math.max(filePath.lastIndexOf('/'), filePath.lastIndexOf('\\\\'));\n const basename: string = lastSlash >= 0 ? filePath.slice(lastSlash + 1) : filePath;\n const dot: number = basename.indexOf('.');\n const stem: string = (dot >= 0 ? basename.slice(0, dot) : basename).toUpperCase();\n return WINDOWS_RESERVED_BASENAMES.has(stem);\n}\n\nconst OBJECTMODE_SUBMODULE: '160000' = '160000';\nconst OBJECTMODE_SYMLINK: '120000' = '120000';\nconst OBJECTMODE_FILE_NONEXECUTABLE: '100644' = '100644';\nconst OBJECTMODE_FILE_EXECUTABLE: '100755' = '100755';\n\n// Note that `type` is a stub that is being ignored by the parser in favor of using `mode` to infer, since `%(objecttype)` requires git 2.51.0+\n// e.g. 10644 blob <hash>\\t<path>\nconst GIT_LSTREE_FORMAT: string = '%(objectmode) type %(objectname)%x09%(path)';\n\ninterface IGitTreeState {\n files: Map<string, string>; // type \"blob\"\n symlinks: Map<string, string>; // type \"link\"\n submodules: Map<string, string>; // type \"commit\"\n}\n\n/**\n * Parses the output of the \"git ls-tree -r -z\" command or of other commands that have been coerced to match its format.\n * @internal\n */\nexport function parseGitLsTree(output: string): IGitTreeState {\n const files: Map<string, string> = new Map();\n const symlinks: Map<string, string> = new Map();\n const submodules: Map<string, string> = new Map();\n\n // Parse the output\n // With the -z modifier, paths are delimited by nulls\n // A line looks like:\n // <mode> <type> <newhash>\\t<path>\\0\n // 100644 blob a300ccb0b36bd2c85ef18e3c619a2c747f95959e\\ttools/prettier-git/prettier-git.js\\0\n\n let last: number = 0;\n let index: number = output.indexOf('\\0', last);\n while (index >= 0) {\n const item: string = output.slice(last, index);\n\n const tabIndex: number = item.indexOf('\\t');\n const filePath: string = item.slice(tabIndex + 1);\n\n // The newHash will be all zeros if the file is deleted, or a hash if it exists\n const hash: string = item.slice(tabIndex - 40, tabIndex);\n\n const mode: string = item.slice(0, item.indexOf(' '));\n\n switch (mode) {\n case OBJECTMODE_SUBMODULE: {\n // This is a submodule\n submodules.set(filePath, hash);\n break;\n }\n case OBJECTMODE_SYMLINK: {\n // This is a symbolic link\n symlinks.set(filePath, hash);\n break;\n }\n case OBJECTMODE_FILE_NONEXECUTABLE:\n case OBJECTMODE_FILE_EXECUTABLE:\n default: {\n files.set(filePath, hash);\n break;\n }\n }\n\n last = index + 1;\n index = output.indexOf('\\0', last);\n }\n\n return {\n files,\n symlinks,\n submodules\n };\n}\n\n/**\n * Parses the output of `git hash-object`\n * yields [filePath, hash] pairs.\n * @internal\n */\nexport function* parseGitHashObject(\n output: string,\n filePaths: ReadonlyArray<string>\n): IterableIterator<[string, string]> {\n const expected: number = filePaths.length;\n if (expected === 0) {\n return;\n }\n\n output = output.trim();\n\n let last: number = 0;\n let i: number = 0;\n let index: number = output.indexOf('\\n', last);\n for (; i < expected && index > 0; i++) {\n const hash: string = output.slice(last, index);\n yield [filePaths[i], hash];\n last = index + 1;\n index = output.indexOf('\\n', last);\n }\n\n // Handle last line. Will be non-empty to due trim() call.\n if (index < 0) {\n const hash: string = output.slice(last);\n yield [filePaths[i], hash];\n i++;\n }\n\n if (i !== expected) {\n throw new Error(`Expected ${expected} hashes from \"git hash-object\" but received ${i}`);\n }\n}\n\n/**\n * Information about the changes to a file.\n * @beta\n */\nexport interface IFileDiffStatus {\n mode: string;\n oldhash: string;\n newhash: string;\n status: 'A' | 'D' | 'M';\n}\n\n/**\n * Parses the output of `git diff-index --color=never --no-renames --no-commit-id -z <REVISION> --\n * Returns a map of file path to diff\n * @internal\n */\nexport function parseGitDiffIndex(output: string): Map<string, IFileDiffStatus> {\n const result: Map<string, IFileDiffStatus> = new Map();\n\n // Parse the output\n // With the -z modifier, paths are delimited by nulls\n // A line looks like:\n // :<oldmode> <newmode> <oldhash> <newhash> <status>\\0<path>\\0\n // :100644 100644 a300ccb0b36bd2c85ef18e3c619a2c747f95959e 0000000000000000000000000000000000000000 M\\0tools/prettier-git/prettier-git.js\\0\n\n let last: number = 0;\n let index: number = output.indexOf('\\0', last);\n while (index >= 0) {\n const header: string = output.slice(last, index);\n const status: IFileDiffStatus['status'] = header.slice(-1) as IFileDiffStatus['status'];\n\n last = index + 1;\n index = output.indexOf('\\0', last);\n const filePath: string = output.slice(last, index);\n\n // We passed --no-renames above, so a rename will be a delete of the old location and an add at the new.\n // The newHash will be all zeros if the file is deleted, or a hash if it exists\n const mode: string = header.slice(8, 14);\n const oldhash: string = header.slice(-83, -43);\n const newhash: string = header.slice(-42, -2);\n result.set(filePath, {\n mode,\n oldhash,\n newhash,\n status\n });\n\n last = index + 1;\n index = output.indexOf('\\0', last);\n }\n\n return result;\n}\n\n/**\n * Parses the output of `git status -z -u` to extract the set of files that have changed since HEAD.\n *\n * @param output - The raw output from Git\n * @returns a map of file path to if it exists\n * @internal\n */\nexport function parseGitStatus(output: string): Map<string, boolean> {\n const result: Map<string, boolean> = new Map();\n\n // Parse the output\n // With the -z modifier, paths are delimited by nulls\n // A line looks like:\n // XY <path>\\0\n // M tools/prettier-git/prettier-git.js\\0\n\n let startOfLine: number = 0;\n let eolIndex: number = output.indexOf('\\0', startOfLine);\n while (eolIndex >= 0) {\n // We passed --no-renames above, so a rename will be a delete of the old location and an add at the new.\n // charAt(startOfLine) is the index status, charAt(startOfLine + 1) is the working tree status\n const workingTreeStatus: string = output.charAt(startOfLine + 1);\n // Deleted in working tree, or not modified in working tree and deleted in index\n const deleted: boolean =\n workingTreeStatus === 'D' || (workingTreeStatus === ' ' && output.charAt(startOfLine) === 'D');\n\n const filePath: string = output.slice(startOfLine + 3, eolIndex);\n result.set(filePath, !deleted);\n\n startOfLine = eolIndex + 1;\n eolIndex = output.indexOf('\\0', startOfLine);\n }\n\n return result;\n}\n\nconst repoRootCache: Map<string, string> = new Map();\n\n/**\n * Finds the root of the current Git repository\n *\n * @param currentWorkingDirectory - The working directory for which to locate the repository\n * @param gitPath - The path to the Git executable\n *\n * @returns The full path to the root directory of the Git repository\n * @beta\n */\nexport function getRepoRoot(currentWorkingDirectory: string, gitPath?: string): string {\n let cachedResult: string | undefined = repoRootCache.get(currentWorkingDirectory);\n if (!cachedResult) {\n const result: child_process.SpawnSyncReturns<string> = Executable.spawnSync(\n gitPath || 'git',\n ['--no-optional-locks', 'rev-parse', '--show-toplevel'],\n {\n currentWorkingDirectory\n }\n );\n\n if (result.status !== 0) {\n ensureGitMinimumVersion(gitPath);\n\n throw new Error(`git rev-parse exited with status ${result.status}: ${result.stderr}`);\n }\n\n cachedResult = result.stdout.trim();\n\n repoRootCache.set(currentWorkingDirectory, cachedResult);\n // To ensure that calling getRepoRoot on the result is a no-op.\n repoRootCache.set(cachedResult, cachedResult);\n }\n\n return cachedResult;\n}\n\n/**\n * Helper function for async process invocation with optional stdin support.\n * @param gitPath - Path to the Git executable\n * @param args - The process arguments\n * @param currentWorkingDirectory - The working directory. Should be the repository root.\n * @param stdin - An optional Readable stream to use as stdin to the process.\n */\nasync function spawnGitAsync(\n gitPath: string | undefined,\n args: string[],\n currentWorkingDirectory: string,\n stdin?: Readable\n): Promise<string> {\n const spawnOptions: IExecutableSpawnOptions = {\n currentWorkingDirectory,\n stdio: ['pipe', 'pipe', 'pipe']\n };\n\n let stdout: string = '';\n let stderr: string = '';\n\n const proc: child_process.ChildProcess = Executable.spawn(gitPath || 'git', args, spawnOptions);\n proc.stdout!.setEncoding('utf-8');\n proc.stderr!.setEncoding('utf-8');\n\n proc.stdout!.on('data', (chunk: string) => {\n stdout += chunk.toString();\n });\n proc.stderr!.on('data', (chunk: string) => {\n stderr += chunk.toString();\n });\n\n if (stdin) {\n /**\n * For `git hash-object` data is piped in asynchronously. In the event that one of the\n * passed filenames cannot be hashed, subsequent writes to `proc.stdin` will error.\n * Silence this error since it will be handled by the non-zero exit code of the process.\n */\n pipeline(stdin, proc.stdin!, (err) => {});\n }\n\n const [status] = await once(proc, 'close');\n if (status !== 0) {\n ensureGitMinimumVersion(gitPath);\n\n throw new Error(`git ${args[0]} exited with code ${status}:\\n${stderr}`);\n }\n\n return stdout;\n}\n\nfunction isIterable<T>(value: Iterable<T> | AsyncIterable<T>): value is Iterable<T> {\n return Symbol.iterator in value;\n}\n\n/**\n * Uses `git hash-object` to hash the provided files. Unlike `getGitHashForFiles`, this API is asynchronous, and also allows for\n * the input file paths to be specified as an async iterable.\n *\n * @param rootDirectory - The root directory to which paths are specified relative. Must be the root of the Git repository.\n * @param filesToHash - The file paths to hash using `git hash-object`\n * @param gitPath - The path to the Git executable\n * @returns An iterable of [filePath, hash] pairs\n *\n * @remarks\n * The input file paths must be specified relative to the Git repository root, or else be absolute paths.\n * @beta\n */\nexport async function hashFilesAsync(\n rootDirectory: string,\n filesToHash: Iterable<string> | AsyncIterable<string>,\n gitPath?: string\n): Promise<Iterable<[string, string]>> {\n const hashPaths: string[] = [];\n\n const input: Readable = Readable.from(\n isIterable(filesToHash)\n ? (function* (): IterableIterator<string> {\n for (const file of filesToHash) {\n hashPaths.push(file);\n yield `${file}\\n`;\n }\n })()\n : (async function* (): AsyncIterableIterator<string> {\n for await (const file of filesToHash) {\n hashPaths.push(file);\n yield `${file}\\n`;\n }\n })(),\n {\n encoding: 'utf-8',\n objectMode: false,\n autoDestroy: true\n }\n );\n\n const hashObjectResult: string = await spawnGitAsync(\n gitPath,\n STANDARD_GIT_OPTIONS.concat(['hash-object', '--stdin-paths']),\n rootDirectory,\n input\n );\n\n return parseGitHashObject(hashObjectResult, hashPaths);\n}\n\n/**\n * Gets the object hashes for all files in the Git repo, combining the current commit with working tree state.\n * Uses async operations and runs all primary Git calls in parallel.\n * @param rootDirectory - The root directory of the Git repository\n * @param additionalRelativePathsToHash - Root-relative file paths to have Git hash and include in the results\n * @param gitPath - The path to the Git executable\n * @beta\n */\nexport async function getRepoStateAsync(\n rootDirectory: string,\n additionalRelativePathsToHash?: string[],\n gitPath?: string,\n filterPath?: string[]\n): Promise<Map<string, string>> {\n const { files } = await getDetailedRepoStateAsync(\n rootDirectory,\n additionalRelativePathsToHash,\n gitPath,\n filterPath\n );\n\n return files;\n}\n\n/**\n * Information about the detailed state of the Git repository.\n * @beta\n */\nexport interface IDetailedRepoState {\n /**\n * The Git file hashes for all files in the repository, including uncommitted changes.\n */\n files: Map<string, string>;\n /**\n * The Git file hashes for all symbolic links in the repository, including uncommitted changes.\n */\n symlinks: Map<string, string>;\n /**\n * A boolean indicating whether the repository has submodules.\n */\n hasSubmodules: boolean;\n /**\n * A boolean indicating whether the repository has uncommitted changes.\n */\n hasUncommittedChanges: boolean;\n}\n\n/**\n * Gets the object hashes for all files in the Git repo, combining the current commit with working tree state.\n * Uses async operations and runs all primary Git calls in parallel.\n * @param rootDirectory - The root directory of the Git repository\n * @param additionalRelativePathsToHash - Root-relative file paths to have Git hash and include in the results\n * @param gitPath - The path to the Git executable\n * @beta\n */\nexport async function getDetailedRepoStateAsync(\n rootDirectory: string,\n additionalRelativePathsToHash?: string[],\n gitPath?: string,\n filterPath?: string[]\n): Promise<IDetailedRepoState> {\n const statePromise: Promise<IGitTreeState> = spawnGitAsync(\n gitPath,\n STANDARD_GIT_OPTIONS.concat([\n 'ls-files',\n // Read from the index only\n '--cached',\n // Use NUL as the separator\n '-z',\n // Specify the full path to files relative to the root\n '--full-name',\n // Match the format of \"git ls-tree\". The %(objecttype) placeholder requires git 2.51.0+, so not using yet.\n `--format=${GIT_LSTREE_FORMAT}`,\n '--',\n ...(filterPath ?? [])\n ]),\n rootDirectory\n ).then(parseGitLsTree);\n const locallyModifiedPromise: Promise<Map<string, boolean>> = spawnGitAsync(\n gitPath,\n STANDARD_GIT_OPTIONS.concat([\n 'status',\n // Use NUL as the separator\n '-z',\n // Include untracked files\n '-u',\n // Disable rename detection so that renames show up as add + delete\n '--no-renames',\n // Don't process submodules with this command; they'll be handled individually\n '--ignore-submodules',\n // Don't compare against the remote\n '--no-ahead-behind',\n '--',\n ...(filterPath ?? [])\n ]),\n rootDirectory\n ).then(parseGitStatus);\n\n async function* getFilesToHash(): AsyncIterableIterator<string> {\n if (additionalRelativePathsToHash) {\n for (const file of additionalRelativePathsToHash) {\n yield file;\n }\n }\n\n const [{ files, symlinks }, locallyModified] = await Promise.all([statePromise, locallyModifiedPromise]);\n\n const isWindows: boolean = process.platform === 'win32';\n for (const [filePath, exists] of locallyModified) {\n if (exists && !symlinks.has(filePath)) {\n // Skip Windows reserved device names. `git hash-object` cannot open them and would abort\n // the entire repo-state computation. These are almost always stray artifacts (e.g. a `nul`\n // file produced by a misdirected shell redirect) rather than meaningful inputs.\n if (isWindows && isWindowsReservedPath(filePath)) {\n continue;\n }\n yield filePath;\n } else {\n files.delete(filePath);\n symlinks.delete(filePath);\n }\n }\n }\n\n const hashObjectPromise: Promise<Iterable<[string, string]>> = hashFilesAsync(\n rootDirectory,\n getFilesToHash(),\n gitPath\n );\n\n const [{ files, symlinks, submodules }, locallyModifiedFiles] = await Promise.all([\n statePromise,\n locallyModifiedPromise\n ]);\n\n // The result of \"git hash-object\" will be a list of file hashes delimited by newlines\n for (const [filePath, hash] of await hashObjectPromise) {\n files.set(filePath, hash);\n }\n\n // Existence check for the .gitmodules file\n const hasSubmodules: boolean = submodules.size > 0 && FileSystem.exists(`${rootDirectory}/.gitmodules`);\n\n if (hasSubmodules) {\n // Submodules are not the normal critical path. Accept serial performance rather than investing in complexity.\n // Can revisit if submodules become more commonly used.\n for (const submodulePath of submodules.keys()) {\n const submoduleState: Map<string, string> = await getRepoStateAsync(\n `${rootDirectory}/${submodulePath}`,\n [],\n gitPath\n );\n for (const [filePath, hash] of submoduleState) {\n files.set(`${submodulePath}/${filePath}`, hash);\n }\n }\n }\n\n return {\n hasSubmodules,\n hasUncommittedChanges: locallyModifiedFiles.size > 0,\n files,\n symlinks\n };\n}\n\n/**\n * Find all changed files tracked by Git, their current hashes, and the nature of the change. Only useful if all changes are staged or committed.\n * @param currentWorkingDirectory - The working directory. Only used to find the repository root.\n * @param revision - The Git revision specifier to detect changes relative to. Defaults to HEAD (i.e. will compare staged vs. committed)\n * If comparing against a different branch, call `git merge-base` first to find the target commit.\n * @param gitPath - The path to the Git executable\n * @returns A map from the Git file path to the corresponding file change metadata\n * @beta\n */\nexport function getRepoChanges(\n currentWorkingDirectory: string,\n revision: string = 'HEAD',\n gitPath?: string\n): Map<string, IFileDiffStatus> {\n const rootDirectory: string = getRepoRoot(currentWorkingDirectory, gitPath);\n\n const result: child_process.SpawnSyncReturns<string> = Executable.spawnSync(\n gitPath || 'git',\n STANDARD_GIT_OPTIONS.concat([\n 'diff-index',\n '--color=never',\n '--no-renames',\n '--no-commit-id',\n '--cached',\n '-z',\n revision,\n '--'\n ]),\n {\n currentWorkingDirectory: rootDirectory\n }\n );\n\n if (result.status !== 0) {\n ensureGitMinimumVersion(gitPath);\n\n throw new Error(`git diff-index exited with status ${result.status}: ${result.stderr}`);\n }\n\n const changes: Map<string, IFileDiffStatus> = parseGitDiffIndex(result.stdout);\n\n return changes;\n}\n\n/**\n * Checks the git version and throws an error if it is less than the minimum required version.\n *\n * @public\n */\nexport function ensureGitMinimumVersion(gitPath?: string): void {\n const gitVersion: IGitVersion = getGitVersion(gitPath);\n if (\n gitVersion.major < MINIMUM_GIT_VERSION.major ||\n (gitVersion.major === MINIMUM_GIT_VERSION.major && gitVersion.minor < MINIMUM_GIT_VERSION.minor) ||\n (gitVersion.major === MINIMUM_GIT_VERSION.major &&\n gitVersion.minor === MINIMUM_GIT_VERSION.minor &&\n gitVersion.patch < MINIMUM_GIT_VERSION.patch)\n ) {\n throw new Error(\n `The minimum Git version required is ` +\n `${MINIMUM_GIT_VERSION.major}.${MINIMUM_GIT_VERSION.minor}.${MINIMUM_GIT_VERSION.patch}. ` +\n `Your version is ${gitVersion.major}.${gitVersion.minor}.${gitVersion.patch}.`\n );\n }\n}\n\nfunction getGitVersion(gitPath?: string): IGitVersion {\n const result: child_process.SpawnSyncReturns<string> = Executable.spawnSync(\n gitPath || 'git',\n STANDARD_GIT_OPTIONS.concat(['version'])\n );\n\n if (result.status !== 0) {\n throw new Error(\n `While validating the Git installation, the \"git version\" command failed with ` +\n `status ${result.status}: ${result.stderr}`\n );\n }\n\n return parseGitVersion(result.stdout);\n}\n\nexport function parseGitVersion(gitVersionOutput: string): IGitVersion {\n // This regexp matches output of \"git version\" that looks like `git version <number>.<number>.<number>(+whatever)`\n // Examples:\n // - git version 1.2.3\n // - git version 1.2.3.4.5\n // - git version 1.2.3windows.1\n // - git version 1.2.3.windows.1\n const versionRegex: RegExp = /^git version (\\d+)\\.(\\d+)\\.(\\d+)/;\n const match: RegExpMatchArray | null = versionRegex.exec(gitVersionOutput);\n if (!match) {\n throw new Error(\n `While validating the Git installation, the \"git version\" command produced ` +\n `unexpected output: \"${gitVersionOutput}\"`\n );\n }\n\n const major: number = parseInt(match[1], 10);\n const minor: number = parseInt(match[2], 10);\n const patch: number = parseInt(match[3], 10);\n\n return {\n major,\n minor,\n patch\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rushstack/package-deps-hash",
3
- "version": "4.7.17",
3
+ "version": "4.7.19",
4
4
  "description": "",
5
5
  "main": "./lib-commonjs/index.js",
6
6
  "module": "./lib-esm/index.js",
@@ -35,8 +35,8 @@
35
35
  },
36
36
  "devDependencies": {
37
37
  "eslint": "~9.37.0",
38
- "local-node-rig": "1.0.0",
39
- "@rushstack/heft": "1.2.17"
38
+ "@rushstack/heft": "1.2.18",
39
+ "local-node-rig": "1.0.0"
40
40
  },
41
41
  "dependencies": {
42
42
  "@rushstack/node-core-library": "5.23.1"