@vibe-validate/git 0.18.4 → 0.19.0-rc.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/tree-hash.js CHANGED
@@ -124,23 +124,68 @@ function cleanupStaleIndexes(gitDir) {
124
124
  * 2. Copy current index to temporary index
125
125
  * 3. Mark untracked files with --intent-to-add in temp index
126
126
  * 4. Calculate tree hash with git write-tree using temp index
127
- * 5. Clean up temp index file
127
+ * 5. Detect and process git submodules (recursive)
128
+ * 6. Return parent hash + optional submodule hashes
129
+ * 7. Clean up temp index file
128
130
  *
129
131
  * Why this is better than git stash create:
130
132
  * - git stash create: includes timestamps in commit → different hash each time
131
133
  * - git write-tree: content-based only → same content = same hash (deterministic)
132
134
  *
135
+ * Submodule Support (Issue #120):
136
+ * - Detects submodules via `git submodule status`
137
+ * - Recursively calculates tree hash for each submodule
138
+ * - Returns TreeHashResult with parent hash + submodule hashes
139
+ * - Working tree changes in submodules invalidate cache
140
+ * - Git notes store full result for state reconstruction
141
+ *
142
+ * IMPORTANT: This function returns a structured result object, NOT a composite hash.
143
+ * Git notes store the TreeHashResult as-is. The hash field is the parent repo's
144
+ * standard Git SHA-1 hash (40 hex characters). The optional submoduleHashes field
145
+ * records each submodule's tree hash separately.
146
+ *
147
+ * Cache key format in git notes (v0.19.0+):
148
+ * - Parent-only repos: Use parent hash directly (backward compatible)
149
+ * - Repos with submodules: Use parent hash + submodule metadata
150
+ * - Result structure stored in git notes for state reconstruction
151
+ *
133
152
  * CRITICAL: Uses GIT_INDEX_FILE to avoid corrupting real index during git commit hooks
134
153
  *
135
- * @returns Git tree SHA-1 hash (40 hex characters) as branded TreeHash type
154
+ * @returns TreeHashResult containing:
155
+ * - hash: Parent repository tree hash (Git SHA-1, 40 hex chars)
156
+ * - submoduleHashes: Optional record of submodule paths to tree hashes
157
+ *
158
+ * @example
159
+ * // Repository without submodules (0.18.x compatible)
160
+ * const result = await getGitTreeHash();
161
+ * // { hash: 'abc123...' }
162
+ *
163
+ * @example
164
+ * // Repository with submodules (v0.19.0+)
165
+ * const result = await getGitTreeHash();
166
+ * // {
167
+ * // hash: 'abc123...', // Parent repo hash
168
+ * // submoduleHashes: {
169
+ * // 'libs/auth': 'xyz789...'
170
+ * // }
171
+ * // }
172
+ *
136
173
  * @throws Error if not in a git repository or git command fails
137
174
  */
175
+ // eslint-disable-next-line sonarjs/cognitive-complexity -- Complexity 18 acceptable for main orchestration function (git operations + submodule handling + cleanup + error handling)
138
176
  export async function getGitTreeHash() {
139
177
  try {
140
178
  // Check if we're in a git repository
141
179
  executeGitCommand(['rev-parse', '--is-inside-work-tree'], { timeout: GIT_TIMEOUT });
142
- // Get git directory and create temp index path
143
- const gitDir = executeGitCommand(['rev-parse', '--git-dir'], { timeout: GIT_TIMEOUT }).stdout.trim();
180
+ // Get git directory and repository root
181
+ // CRITICAL: Use --absolute-git-dir instead of --git-dir for cross-platform consistency
182
+ // --git-dir returns relative paths (.git vs ../.git) on Windows depending on cwd
183
+ // --absolute-git-dir ensures same path regardless of subdirectory (Issue #127)
184
+ const gitDir = executeGitCommand(['rev-parse', '--absolute-git-dir'], { timeout: GIT_TIMEOUT }).stdout.trim();
185
+ // Get repository root (working tree top level)
186
+ // CRITICAL: git add --all must run from repo root, not subdirectory
187
+ // Running from subdirectory only stages files in that subdirectory (Issue #127)
188
+ const repoRoot = executeGitCommand(['rev-parse', '--show-toplevel'], { timeout: GIT_TIMEOUT }).stdout.trim();
144
189
  cleanupStaleIndexes(gitDir);
145
190
  const tempIndexFile = `${gitDir}/vibe-validate-temp-index-${process.pid}`;
146
191
  try {
@@ -172,10 +217,13 @@ export async function getGitTreeHash() {
172
217
  // - Non-deterministic: different devs have different ignored files
173
218
  // - Breaks cache sharing: same code produces different hashes
174
219
  //
220
+ // CRITICAL: Run from repo root, not subdirectory (Issue #127)
221
+ // Running from subdirectory only stages files in that subdirectory on Windows
175
222
  // We need actual content staged so git write-tree includes working directory changes
176
223
  const addResult = executeGitCommand(['add', '--all'], {
177
224
  timeout: GIT_TIMEOUT,
178
225
  env: tempIndexEnv,
226
+ cwd: repoRoot,
179
227
  ignoreErrors: true
180
228
  });
181
229
  // If git add fails and it's not "nothing to add", throw error
@@ -184,11 +232,44 @@ export async function getGitTreeHash() {
184
232
  throw new Error(`git add failed: ${addResult.stderr}`);
185
233
  }
186
234
  // Step 4: Get tree hash using temp index (content-based, no timestamps)
235
+ // Run from repo root for consistency with git add --all
187
236
  const treeHash = executeGitCommand(['write-tree'], {
188
237
  timeout: GIT_TIMEOUT,
189
- env: tempIndexEnv
238
+ env: tempIndexEnv,
239
+ cwd: repoRoot
190
240
  }).stdout.trim();
191
- return treeHash;
241
+ // Calculate main repo tree hash
242
+ const parentHash = treeHash;
243
+ // Detect submodules
244
+ const submodules = getSubmodules();
245
+ // No submodules - simple case (0.18.x compatible)
246
+ if (submodules.length === 0) {
247
+ return { hash: parentHash };
248
+ }
249
+ // Build submodule hashes record
250
+ const submoduleHashes = {};
251
+ // Add submodule hashes (sorted by path for determinism)
252
+ const sortedSubmodules = submodules.toSorted((a, b) => a.path.localeCompare(b.path));
253
+ for (const sub of sortedSubmodules) {
254
+ // Skip uninitialized submodules (status '-')
255
+ if (sub.status === '-') {
256
+ continue;
257
+ }
258
+ try {
259
+ const subResult = await getSubmoduleTreeHash(sub.path);
260
+ // Store the submodule's hash in the record
261
+ submoduleHashes[sub.path] = subResult.hash;
262
+ }
263
+ catch (error) {
264
+ // Log warning but continue with other submodules
265
+ const errorMsg = error instanceof Error ? error.message : String(error);
266
+ console.warn(`⚠️ Failed to hash submodule ${sub.path}: ${errorMsg}`);
267
+ }
268
+ }
269
+ return {
270
+ hash: parentHash,
271
+ submoduleHashes,
272
+ };
192
273
  }
193
274
  finally {
194
275
  // Step 5: Always clean up temp index file
@@ -208,7 +289,9 @@ export async function getGitTreeHash() {
208
289
  const errorMessage = error instanceof Error ? error.message : String(error);
209
290
  if (errorMessage.includes('not a git repository')) {
210
291
  // Not in git repo - return "unknown" (caller should skip caching)
211
- return 'unknown';
292
+ return {
293
+ hash: 'unknown'
294
+ };
212
295
  }
213
296
  // Other git errors
214
297
  throw new Error(`Failed to calculate git tree hash: ${errorMessage}`);
@@ -243,11 +326,100 @@ export async function hasWorkingTreeChanges() {
243
326
  try {
244
327
  const workingTreeHash = await getGitTreeHash();
245
328
  const headTreeHash = await getHeadTreeHash();
246
- return workingTreeHash !== headTreeHash;
329
+ return workingTreeHash.hash !== headTreeHash;
247
330
  }
248
331
  catch {
249
332
  // If we can't determine, assume there are changes (safe default)
250
333
  return true;
251
334
  }
252
335
  }
336
+ /**
337
+ * Get list of git submodules in current repository
338
+ *
339
+ * Parses output of `git submodule status` to detect submodules.
340
+ * Returns empty array if no submodules or command fails.
341
+ *
342
+ * Output format: " abc123 libs/auth (heads/main)"
343
+ * ^^^^^^ ^^^^^^^^^ (description)
344
+ * hash path
345
+ *
346
+ * @returns Array of submodule information
347
+ *
348
+ * @example
349
+ * const submodules = getSubmodules();
350
+ * // [{ path: 'libs/auth', status: ' ' }, { path: 'vendor/foo', status: '+' }]
351
+ *
352
+ * @internal Exported for testing
353
+ */
354
+ export function getSubmodules() {
355
+ // Fast path: if .gitmodules doesn't exist, there are no submodules
356
+ // Avoids 684ms git submodule status call in repos without submodules
357
+ try {
358
+ const repoRoot = executeGitCommand(['rev-parse', '--show-toplevel'], {
359
+ timeout: 5000,
360
+ ignoreErrors: true,
361
+ });
362
+ if (repoRoot.success) {
363
+ const gitmodulesPath = join(repoRoot.stdout.trim(), '.gitmodules');
364
+ if (!existsSync(gitmodulesPath)) {
365
+ return [];
366
+ }
367
+ }
368
+ }
369
+ catch (error) {
370
+ // Fall through to git submodule status
371
+ // Only log in debug mode to avoid noise
372
+ if (process.env.VV_DEBUG === '1') {
373
+ console.error('[vv debug] .gitmodules fast-path check failed:', error instanceof Error ? error.message : String(error));
374
+ }
375
+ }
376
+ const result = executeGitCommand(['submodule', 'status'], {
377
+ ignoreErrors: true,
378
+ timeout: GIT_TIMEOUT
379
+ });
380
+ if (!result.success) {
381
+ return []; // No submodules or error
382
+ }
383
+ const submodules = [];
384
+ for (const line of result.stdout.split('\n')) {
385
+ if (!line.trim())
386
+ continue;
387
+ // Parse: " abc123 libs/auth (heads/main)"
388
+ // Group 1: commit hash, Group 2: path
389
+ const match = /^\s*[+-]?([a-f0-9]+)\s+(\S+)/.exec(line);
390
+ if (!match)
391
+ continue;
392
+ submodules.push({
393
+ path: match[2],
394
+ status: line[0] || ' ' // First char is status
395
+ });
396
+ }
397
+ return submodules;
398
+ }
399
+ /**
400
+ * Calculate tree hash for a git submodule (recursive)
401
+ *
402
+ * Changes to submodule directory, calculates tree hash, then returns to original directory.
403
+ * This is recursive - if the submodule has its own submodules, they will be included.
404
+ *
405
+ * @param submodulePath - Path to submodule relative to current directory
406
+ * @returns Tree hash result for the submodule
407
+ *
408
+ * @example
409
+ * const result = await getSubmoduleTreeHash('libs/auth');
410
+ * // Returns TreeHashResult for libs/auth submodule
411
+ *
412
+ * @internal Exported for testing
413
+ */
414
+ export async function getSubmoduleTreeHash(submodulePath) {
415
+ const originalCwd = process.cwd();
416
+ try {
417
+ process.chdir(submodulePath);
418
+ // Recursive! If submodule has submodules, they'll be included
419
+ return await getGitTreeHash();
420
+ }
421
+ finally {
422
+ process.chdir(originalCwd);
423
+ }
424
+ }
253
425
  //# sourceMappingURL=tree-hash.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tree-hash.js","sourceRoot":"","sources":["../src/tree-hash.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tree-hash.js","sourceRoot":"","sources":["../src/tree-hash.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -42,4 +42,27 @@ export type CommitSha = string & {
42
42
  export type NotesRef = string & {
43
43
  readonly __brand: 'NotesRef';
44
44
  };
45
+ /**
46
+ * Result of git tree hash calculation with submodule support
47
+ *
48
+ * @example
49
+ * // Single repo (no submodules)
50
+ * { hash: 'abc123...' }
51
+ *
52
+ * @example
53
+ * // Repo with submodules
54
+ * {
55
+ * hash: 'abc123...',
56
+ * submoduleHashes: {
57
+ * 'libs/auth': 'def456...',
58
+ * 'vendor/foo': '789ghi...'
59
+ * }
60
+ * }
61
+ */
62
+ export interface TreeHashResult {
63
+ /** Root repository tree hash (40-char SHA-1, git object) */
64
+ hash: TreeHash;
65
+ /** Submodule tree hashes (path → tree hash mapping). Only present when submodules exist. */
66
+ submoduleHashes?: Record<string, TreeHash>;
67
+ }
45
68
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;GAOG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAA;CAAE,CAAC;AAEjE;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;CAAE,CAAC;AAEnE;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAA;CAAE,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;GAOG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAA;CAAE,CAAC;AAEjE;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;CAAE,CAAC;AAEnE;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAA;CAAE,CAAC;AAEjE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,cAAc;IAC7B,4DAA4D;IAC5D,IAAI,EAAE,QAAQ,CAAC;IAEf,4FAA4F;IAC5F,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;CAC5C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibe-validate/git",
3
- "version": "0.18.4",
3
+ "version": "0.19.0-rc.10",
4
4
  "description": "Git utilities for vibe-validate - tree hash calculation, branch sync, and post-merge cleanup",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -39,7 +39,7 @@
39
39
  },
40
40
  "dependencies": {
41
41
  "yaml": "^2.8.2",
42
- "@vibe-validate/utils": "0.18.4"
42
+ "@vibe-validate/utils": "0.19.0-rc.10"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@types/node": "^22.19.2",
@@ -48,7 +48,6 @@
48
48
  },
49
49
  "scripts": {
50
50
  "build": "tsc",
51
- "clean": "rm -rf dist",
52
51
  "test": "vitest run",
53
52
  "test:watch": "vitest"
54
53
  }