import static java.lang.Integer.valueOf; | import static java.lang.Integer.valueOf; | ||||
import static org.junit.Assert.assertEquals; | import static org.junit.Assert.assertEquals; | ||||
import static org.junit.Assert.assertFalse; | |||||
import static org.junit.Assert.assertNull; | import static org.junit.Assert.assertNull; | ||||
import static org.junit.Assert.assertSame; | import static org.junit.Assert.assertSame; | ||||
import java.io.File; | import java.io.File; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.nio.file.Files; | |||||
import java.nio.file.Path; | |||||
import java.util.concurrent.BrokenBarrierException; | import java.util.concurrent.BrokenBarrierException; | ||||
import java.util.concurrent.Callable; | import java.util.concurrent.Callable; | ||||
import java.util.concurrent.CyclicBarrier; | import java.util.concurrent.CyclicBarrier; | ||||
assertSame(repo.exactRef("refs/tags/t").getStorage(), Storage.PACKED); | assertSame(repo.exactRef("refs/tags/t").getStorage(), Storage.PACKED); | ||||
} | } | ||||
@Test | |||||
public void emptyRefDirectoryDeleted() throws Exception { | |||||
String ref = "dir/ref"; | |||||
tr.branch(ref).commit().create(); | |||||
String name = repo.findRef(ref).getName(); | |||||
Path dir = repo.getDirectory().toPath().resolve(name).getParent(); | |||||
gc.packRefs(); | |||||
assertFalse(Files.exists(dir)); | |||||
} | |||||
@Test | @Test | ||||
public void concurrentOnlyOneWritesPackedRefs() throws Exception { | public void concurrentOnlyOneWritesPackedRefs() throws Exception { | ||||
RevBlob a = tr.blob("a"); | RevBlob a = tr.blob("a"); |
newLoose = curLoose.remove(idx); | newLoose = curLoose.remove(idx); | ||||
} while (!looseRefs.compareAndSet(curLoose, newLoose)); | } while (!looseRefs.compareAndSet(curLoose, newLoose)); | ||||
int levels = levelsIn(refName) - 2; | int levels = levelsIn(refName) - 2; | ||||
delete(fileFor(refName), levels); | |||||
delete(refFile, levels, rLck); | |||||
} | } | ||||
} finally { | } finally { | ||||
rLck.unlock(); | rLck.unlock(); | ||||
} | } | ||||
static void delete(final File file, final int depth) throws IOException { | static void delete(final File file, final int depth) throws IOException { | ||||
if (!file.delete() && file.isFile()) | |||||
throw new IOException(MessageFormat.format(JGitText.get().fileCannotBeDeleted, file)); | |||||
delete(file, depth, null); | |||||
} | |||||
private static void delete(final File file, final int depth, LockFile rLck) | |||||
throws IOException { | |||||
if (!file.delete() && file.isFile()) { | |||||
throw new IOException(MessageFormat.format( | |||||
JGitText.get().fileCannotBeDeleted, file)); | |||||
} | |||||
if (rLck != null) { | |||||
rLck.unlock(); // otherwise cannot delete dir below | |||||
} | |||||
File dir = file.getParentFile(); | File dir = file.getParentFile(); | ||||
for (int i = 0; i < depth; ++i) { | for (int i = 0; i < depth; ++i) { | ||||
if (!dir.delete()) | |||||
if (!dir.delete()) { | |||||
break; // ignore problem here | break; // ignore problem here | ||||
} | |||||
dir = dir.getParentFile(); | dir = dir.getParentFile(); | ||||
} | } | ||||
} | } |