[cache] Make automatic cache clean up works again

This change address the issue that jiri failed to detect git cache
corruptions in CQ.

Bug: 35119
Change-Id: Icb21505f7538b9a2fd6e1d5f6816e292367cc1cd
diff --git a/gitutil/git.go b/gitutil/git.go
index ffbe85c..900720f 100644
--- a/gitutil/git.go
+++ b/gitutil/git.go
@@ -11,6 +11,7 @@
 	"os"
 	"os/exec"
 	"path/filepath"
+	"runtime"
 	"strconv"
 	"strings"
 
@@ -215,9 +216,19 @@
 	return branches, nil
 }
 
-// CheckRevAvailable runs cat-file on a commit or tag is available locally.
-func (g *Git) CheckRevAvailable(rev string) error {
-	return g.run("cat-file", "-e", rev)
+// IsRevAvailable runs cat-file on a commit or tag is available locally.
+func (g *Git) IsRevAvailable(rev string) bool {
+	// TODO: (haowei@)(11517) We are having issues with corrupted
+	// cache data on mac builders. Return a non-nil error
+	// to force the mac builders fetch from remote to avoid
+	// jiri checkout failures.
+	if runtime.GOOS == "darwin" {
+		return false
+	}
+	if err := g.run("cat-file", "-e", rev); err != nil {
+		return false
+	}
+	return true
 }
 
 // CheckoutBranch checks out the given branch.
@@ -1268,7 +1279,13 @@
 		}
 	}
 	err := command.Run()
-	g.jirix.Logger.Tracef("Run: git %s (%s), \nstdout: %s\nstderr: %s\n", strings.Join(args, " "), dir, outbuf.String(), errbuf.String())
+	exitCode := 0
+	if err != nil {
+		if exitError, ok := err.(*exec.ExitError); ok {
+			exitCode = exitError.ExitCode()
+		}
+	}
+	g.jirix.Logger.Tracef("Run: git %s (%s), \nstdout: %s\nstderr: %s\nexit code: %v\n", strings.Join(args, " "), dir, outbuf.String(), errbuf.String(), exitCode)
 	return err
 }
 
diff --git a/project/project.go b/project/project.go
index 80f5e89..c3ac0f7 100644
--- a/project/project.go
+++ b/project/project.go
@@ -1875,6 +1875,10 @@
 		}
 		// Cache already present, update it
 		// TODO : update this after implementing FetchAll using g
+		if scm.IsRevAvailable(revision) {
+			jirix.Logger.Infof("%s(%s) cache up-to-date; skipping\n", remote, dir)
+			return nil
+		}
 		msg := fmt.Sprintf("Updating cache: %q", dir)
 		task := jirix.Logger.AddTaskMsg(msg)
 		defer task.Done()
@@ -2008,11 +2012,6 @@
 				errs <- err
 				continue
 			}
-			scm := gitutil.New(jirix, gitutil.RootDirOpt(cacheDirPath))
-			if err := scm.CheckRevAvailable(project.Revision); err == nil {
-				jirix.Logger.Infof("%s cache up-to-date; skipping\n", project.Name)
-				continue
-			}
 			wg.Add(1)
 			fetchLimit <- struct{}{}
 			go func(dir, remote string, depth int, branch, revision string, cacheMutex *sync.Mutex) {