[cache] Clear git cache if it is corrupted.
This patch adds a new feature to jiri. If a git cache was not
usable, it will be considered as corrupted and will be cleared.
Bug: INTK-1077
Test: Local
Change-Id: I01e37fd28027a9554b704968c0717ddf8cecf608
diff --git a/project/project.go b/project/project.go
index 00a79db..bc06367 100644
--- a/project/project.go
+++ b/project/project.go
@@ -1684,9 +1684,26 @@
// Shallow cache, fetch only manifest tracked remote branch
refspec = fmt.Sprintf("+refs/heads/%s:refs/heads/%s", branch, branch)
}
- if isPathDir(dir) {
- if err := gitutil.New(jirix, gitutil.RootDirOpt(dir)).SetRemoteUrl("origin", remote); err != nil {
- return err
+ errCacheCorruption := errors.New("git cache corrupted")
+ updateCache := func() error {
+ // Test if git cache is intact
+ objectsDir := filepath.Join(dir, "objects")
+ if _, err := os.Stat(objectsDir); err != nil {
+ jirix.Logger.Warningf("could not access objects directory under git cache directory %q due to error: %v", dir, err)
+ return errCacheCorruption
+ }
+ scm := gitutil.New(jirix, gitutil.RootDirOpt(dir))
+ if err := scm.Config("--remove-section", "remote.origin"); err != nil {
+ jirix.Logger.Warningf("purge git config failed under git cache directory %q due to error: %v", dir, err)
+ return errCacheCorruption
+ }
+ if err := scm.Config("remote.origin.url", remote); err != nil {
+ jirix.Logger.Warningf("set remote.origin.url failed under git cache directory %q due to error: %v", dir, err)
+ return errCacheCorruption
+ }
+ if err := scm.Config("--replace-all", "remote.origin.fetch", refspec); err != nil {
+ jirix.Logger.Warningf("set remote.origin.fetch failed under git cache directory %q due to error: %v", dir, err)
+ return errCacheCorruption
}
// Cache already present, update it
// TODO : update this after implementing FetchAll using g
@@ -1704,7 +1721,10 @@
retry.AttemptsOpt(jirix.Attempts)); err != nil {
return err
}
- } else {
+ return nil
+ }
+
+ createCache := func() error {
// Create cache
// TODO : If we in future need to support two projects with same remote url,
// one with shallow checkout and one with full, we should create two caches
@@ -1721,8 +1741,24 @@
if err := gitutil.New(jirix, gitutil.RootDirOpt(dir)).Config("remote.origin.fetch", refspec); err != nil {
return err
}
+ return nil
}
- return nil
+
+ if isPathDir(dir) {
+ if err := updateCache(); err != nil {
+ if err == errCacheCorruption {
+ jirix.Logger.Warningf("Updating git cache %q failed due to cache corruption, cache will be cleared", dir)
+ if err := os.RemoveAll(dir); err != nil {
+ return fmt.Errorf("failed to clear cache dir %q due to error: %v", dir, err)
+ }
+ return createCache()
+ }
+ return err
+ }
+ return nil
+ }
+
+ return createCache()
}
// updateCache creates the cache or updates it if already present.