Run git gc only when there is enough disk space
authorDmitry Neverov <dmitry.neverov@gmail.com>
Mon, 19 Jun 2017 13:51:51 +0000 (15:51 +0200)
committerDmitry Neverov <dmitry.neverov@gmail.com>
Mon, 19 Jun 2017 13:51:51 +0000 (15:51 +0200)
git-server/src/jetbrains/buildServer/buildTriggers/vcs/git/Cleanup.java

index 838515ce93dbab73dabddf75db2df335478c4cf2..c74becf98e33a962ba2cd6412067ca5204570fad 100644 (file)
@@ -152,18 +152,24 @@ public class Cleanup {
       LOG.info("Cannot find native git, skip running git gc");
       return;
     }
+    Long freeDiskSpace = FileUtil.getFreeSpace(myRepositoryManager.getBaseMirrorsDir());
     LOG.info("Use git at path '" + myConfig.getPathToGit() + "'");
     Collections.shuffle(allDirs);
     int runGCCounter = 0;
     LOG.info("Git garbage collection started");
     boolean runInPlace = myConfig.runInPlaceGc();
     for (File gitDir : allDirs) {
-      if (runInPlace) {
-        synchronized (myRepositoryManager.getWriteLock(gitDir)) {
-          runNativeGC(gitDir);
+      if (enoughDiskSpaceForGC(gitDir, freeDiskSpace)) {
+        if (runInPlace) {
+          synchronized (myRepositoryManager.getWriteLock(gitDir)) {
+            runNativeGC(gitDir);
+          }
+        } else {
+          runGcInCopy(gitDir);
         }
       } else {
-        runGcInCopy(gitDir);
+        myGcErrors.registerError(gitDir, "Not enough disk space to run git gc");
+        LOG.warn("[" + gitDir.getName() + "] not enough disk space to run git gc (" + String.valueOf(freeDiskSpace) + "byte(s))");
       }
       runGCCounter++;
       final long repositoryFinishNanos = System.nanoTime();
@@ -187,6 +193,7 @@ public class Cleanup {
     try {
       if (!isGcNeeded(originalRepo)) {
         LOG.info("[" + originalRepo.getName() + "] no git gc is needed");
+        myGcErrors.clearError(originalRepo);
         return;
       }
 
@@ -327,6 +334,14 @@ public class Cleanup {
     }
   }
 
+  private boolean enoughDiskSpaceForGC(@NotNull File gitDir, @Nullable Long freeDiskSpace) {
+    if (freeDiskSpace == null)
+      return true;
+    File objects = new File(gitDir, "objects");
+    File pack = new File(objects, "pack");
+    return FileUtil.getTotalDirectorySize(pack) < freeDiskSpace;
+  }
+
   private boolean tooManyPacks(@NotNull FileRepository repo) {
     int limit = repo.getConfig().getInt("gc", "autopacklimit", 50);
     if (limit <= 0)