Skip to content

Commit a3b782f

Browse files
committed
fixup: do not cache unclean repos
1 parent 63f66d2 commit a3b782f

1 file changed

Lines changed: 23 additions & 83 deletions

File tree

pkg/target_determinator.go

Lines changed: 23 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,25 @@ func fullyProcessRevision(context *Context, rev LabelledGitRev, targets TargetsL
189189
}()
190190

191191
var treeSha string
192-
if context.CacheDirectory != "" && !context.NoCacheResults {
192+
cacheEnabled := context.CacheDirectory != "" && !context.NoCacheResults
193+
if cacheEnabled && rev.GitRevision == CurrentWorkingCopyState {
194+
uncleanStatuses, err := GitStatusFiltered(context.WorkspacePath, context.IgnoredFiles)
195+
if err != nil {
196+
return nil, fmt.Errorf("failed to check git status for caching: %w", err)
197+
}
198+
if len(uncleanStatuses) > 0 {
199+
log.Println("Skipping cache: working copy is unclean")
200+
cacheEnabled = false
201+
}
202+
}
203+
if cacheEnabled {
204+
gitRev := rev.GitRevision.Sha
205+
if gitRev == "" {
206+
// We checked the working copy and index are clean above.
207+
gitRev = "HEAD"
208+
}
193209
var treeErr error
194-
treeSha, treeErr = GitTreeSHA(context, rev.GitRevision.Sha)
210+
treeSha, treeErr = GitTreeSHA(context, gitRev)
195211
if treeErr != nil {
196212
return nil, fmt.Errorf("failed to compute tree SHA for %s: %w", rev, treeErr)
197213
}
@@ -221,7 +237,7 @@ func fullyProcessRevision(context *Context, rev LabelledGitRev, targets TargetsL
221237
}
222238

223239
// Save to cache if caching is enabled
224-
if context.CacheDirectory != "" && !context.NoCacheResults {
240+
if cacheEnabled {
225241
if saveErr := SaveToCache(context, treeSha, targets.String(), queryInfo); saveErr != nil {
226242
log.Printf("Warning: failed to save to cache: %v", saveErr)
227243
}
@@ -358,93 +374,17 @@ func GitRevParse(workingDirectory string, rev string, isAbbrevRef bool) (string,
358374
return strings.Trim(stdoutBuf.String(), "\n"), nil
359375
}
360376

361-
// GitTreeSHA returns the git tree SHA for commit sha. For the current working copy state it
362-
// computes a synthetic tree from the index and working copy; for a specific commit it returns
363-
// the tree SHA of that commit. The result is suitable for use as a cache key.
364-
func GitTreeSHA(context *Context, sha string) (string, error) {
365-
// If the sha is empty, it means we're working with the current working copy state.
366-
if sha == "" {
367-
return WorkingCopyTreeSHA(context)
368-
}
377+
// GitTreeSHA returns the git tree SHA for the given commit-ish (e.g. a commit SHA or "HEAD").
378+
func GitTreeSHA(context *Context, gitRev string) (string, error) {
369379
var stdoutBuf, stderrBuf bytes.Buffer
370-
gitCmd := exec.Command("git", "rev-parse", fmt.Sprintf("%s^{tree}", sha))
380+
gitCmd := exec.Command("git", "rev-parse", fmt.Sprintf("%s^{tree}", gitRev))
371381
gitCmd.Dir = context.WorkspacePath
372382
gitCmd.Stdout = &stdoutBuf
373383
gitCmd.Stderr = &stderrBuf
374384
err := gitCmd.Run()
375385
if err != nil {
376-
return "", fmt.Errorf("could not get tree digest of revision '%v': %w. Stderr: %v", sha, err, stderrBuf.String())
377-
}
378-
return strings.TrimSpace(stdoutBuf.String()), nil
379-
380-
}
381-
382-
// WorkingCopyTreeSHA computes the git tree SHA of the current working copy,
383-
// considering all tracked files including staged and unstaged modifications, but
384-
// excluding untracked files. It does this without modifying the real git index
385-
// by using a temporary index file.
386-
func WorkingCopyTreeSHA(context *Context) (string, error) {
387-
tmpIndex, err := os.CreateTemp("", "td-index-*")
388-
if err != nil {
389-
return "", fmt.Errorf("failed to create temp index file: %w", err)
386+
return "", fmt.Errorf("could not get tree digest of revision '%v': %w. Stderr: %v", gitRev, err, stderrBuf.String())
390387
}
391-
tmpIndex.Close()
392-
defer os.Remove(tmpIndex.Name())
393-
394-
indexEnv := "GIT_INDEX_FILE=" + tmpIndex.Name()
395-
396-
// Capture the current real index as a tree object
397-
var indexTreeBuf, indexTreeErr bytes.Buffer
398-
indexTreeCmd := exec.Command("git", "write-tree")
399-
indexTreeCmd.Dir = context.WorkspacePath
400-
indexTreeCmd.Stdout = &indexTreeBuf
401-
indexTreeCmd.Stderr = &indexTreeErr
402-
if err := indexTreeCmd.Run(); err != nil {
403-
return "", fmt.Errorf("failed to write tree from real index: %w. Stderr: %s", err, indexTreeErr.String())
404-
}
405-
indexTreeSHA := strings.TrimSpace(indexTreeBuf.String())
406-
407-
// Seed the temp index from the real index's tree
408-
seedCmd := exec.Command("git", "read-tree", indexTreeSHA)
409-
seedCmd.Dir = context.WorkspacePath
410-
seedCmd.Env = append(os.Environ(), indexEnv)
411-
if out, err := seedCmd.CombinedOutput(); err != nil {
412-
return "", fmt.Errorf("failed to seed temp index from real index tree: %w. Output: %s", err, out)
413-
}
414-
415-
// Stage tracked modifications (not untracked files)
416-
addCmd := exec.Command("git", "add", "-u")
417-
addCmd.Dir = context.WorkspacePath
418-
addCmd.Env = append(os.Environ(), indexEnv)
419-
if out, err := addCmd.CombinedOutput(); err != nil {
420-
return "", fmt.Errorf("failed to stage tracked changes into temp index: %w. Output: %s", err, out)
421-
}
422-
423-
// Remove ignored files from the temp index so they don't affect the tree SHA.
424-
if len(context.IgnoredFiles) > 0 {
425-
rmArgs := []string{"rm", "--cached", "-r", "--ignore-unmatch", "--"}
426-
for _, f := range context.IgnoredFiles {
427-
rmArgs = append(rmArgs, f.String())
428-
}
429-
rmCmd := exec.Command("git", rmArgs...)
430-
rmCmd.Dir = context.WorkspacePath
431-
rmCmd.Env = append(os.Environ(), indexEnv)
432-
if out, err := rmCmd.CombinedOutput(); err != nil {
433-
return "", fmt.Errorf("failed to remove ignored files from temp index: %w. Output: %s", err, out)
434-
}
435-
}
436-
437-
// Write the tree and capture its SHA
438-
var stdoutBuf, stderrBuf bytes.Buffer
439-
writeCmd := exec.Command("git", "write-tree")
440-
writeCmd.Dir = context.WorkspacePath
441-
writeCmd.Env = append(os.Environ(), indexEnv)
442-
writeCmd.Stdout = &stdoutBuf
443-
writeCmd.Stderr = &stderrBuf
444-
if err := writeCmd.Run(); err != nil {
445-
return "", fmt.Errorf("failed to write tree from temp index: %w. Stderr: %s", err, stderrBuf.String())
446-
}
447-
448388
return strings.TrimSpace(stdoutBuf.String()), nil
449389
}
450390

0 commit comments

Comments
 (0)