summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHector Oswaldo Caballero <hector.caballero@ericsson.com>2016-12-13 07:38:39 -0500
committerhcaballero <hector.caballero@ericsson.com>2016-12-13 10:47:05 -0500
commit4ddd4a3d1b38ecf908978d596531ac9cdc7544dd (patch)
treebddc5a417cb4c71b4c2166a7d73f5226675de35f
parent8f6029786144b1d96e48d789c187cd8138ce8256 (diff)
downloadjgit-4ddd4a3d1b38ecf908978d596531ac9cdc7544dd.tar.gz
jgit-4ddd4a3d1b38ecf908978d596531ac9cdc7544dd.zip
Fix one case of missing object
When a repository is being GCed and a concurrent push is received, there is the possibility of having a missing object. This is due to the fact that after the list of objects to delete is built, there is a window of time when an unreferenced and ready to delete object can be referenced by the incoming push. In that case, the object would be deleted because there is no way to know it is no longer unreferenced. This will leave the repository in an inconsistent state and most of the operations fail with a missing tree/object error. Given the incoming push change the last modified date for the now referenced object, verify this one is still a candidate to delete before actually performing the delete operation. Change-Id: Iadcb29b8eb24b0cb4bb9335b670443c138a60787 Signed-off-by: Hector Oswaldo Caballero <hector.caballero@ericsson.com>
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java11
1 files changed, 8 insertions, 3 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java
index 2e8da8fc9b..a3e9430b13 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java
@@ -430,9 +430,14 @@ public class GC {
return;
// delete all candidates which have survived: these are unreferenced
- // loose objects
- for (File f : deletionCandidates.values())
- f.delete();
+ // loose objects. Make a last check, though, to avoid deleting objects
+ // that could have been referenced while the candidates list was being
+ // built (by an incoming push, for example).
+ for (File f : deletionCandidates.values()) {
+ if (f.lastModified() < expireDate) {
+ f.delete();
+ }
+ }
repo.getObjectDatabase().close();
}