Merge branch 'stable-5.2' into stable-5.3
* stable-5.2: Fix error log message in ObjectDirectory.handlePackError() Properly format pack checksums in PackFile.idx() Cancel gc if thread was interrupted PackFile: report correct message for checksum mismatch ObjectDirectory: Clean up logging Bazel: Stop using native.git_repository ObjectDirectory: extra logging on packfile exceptions Change-Id: I81cf1cdc9d8dcd54536a79e522274fd244fa1d00
This commit is contained in:
commit
e502d7640f
|
@ -47,27 +47,35 @@
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotEquals;
|
import static org.junit.Assert.assertNotEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.concurrent.BrokenBarrierException;
|
import java.util.concurrent.BrokenBarrierException;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.CyclicBarrier;
|
import java.util.concurrent.CyclicBarrier;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.eclipse.jgit.errors.CancelledException;
|
||||||
import org.eclipse.jgit.internal.JGitText;
|
import org.eclipse.jgit.internal.JGitText;
|
||||||
import org.eclipse.jgit.internal.storage.pack.PackWriter;
|
import org.eclipse.jgit.internal.storage.pack.PackWriter;
|
||||||
import org.eclipse.jgit.junit.TestRepository;
|
import org.eclipse.jgit.junit.TestRepository;
|
||||||
|
import org.eclipse.jgit.lib.ConfigConstants;
|
||||||
import org.eclipse.jgit.lib.EmptyProgressMonitor;
|
import org.eclipse.jgit.lib.EmptyProgressMonitor;
|
||||||
import org.eclipse.jgit.lib.NullProgressMonitor;
|
import org.eclipse.jgit.lib.NullProgressMonitor;
|
||||||
import org.eclipse.jgit.lib.ObjectId;
|
import org.eclipse.jgit.lib.ObjectId;
|
||||||
import org.eclipse.jgit.lib.Sets;
|
import org.eclipse.jgit.lib.Sets;
|
||||||
import org.eclipse.jgit.revwalk.RevBlob;
|
import org.eclipse.jgit.revwalk.RevBlob;
|
||||||
import org.eclipse.jgit.revwalk.RevCommit;
|
import org.eclipse.jgit.revwalk.RevCommit;
|
||||||
|
import org.eclipse.jgit.storage.file.FileBasedConfig;
|
||||||
|
import org.eclipse.jgit.test.resources.SampleDataRepositoryTestCase;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class GcConcurrentTest extends GcTestCase {
|
public class GcConcurrentTest extends GcTestCase {
|
||||||
|
@ -221,4 +229,48 @@ public void repackAndCheckBitmapUsage() throws Exception {
|
||||||
assertEquals(getSinglePack(repository).getPackName(), newPackName);
|
assertEquals(getSinglePack(repository).getPackName(), newPackName);
|
||||||
assertNotNull(getSinglePack(repository).getBitmapIndex());
|
assertNotNull(getSinglePack(repository).getBitmapIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInterruptGc() throws Exception {
|
||||||
|
FileBasedConfig c = repo.getConfig();
|
||||||
|
c.setInt(ConfigConstants.CONFIG_GC_SECTION, null,
|
||||||
|
ConfigConstants.CONFIG_KEY_AUTOPACKLIMIT, 1);
|
||||||
|
c.save();
|
||||||
|
SampleDataRepositoryTestCase.copyCGitTestPacks(repo);
|
||||||
|
ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||||
|
final CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
Future<Collection<PackFile>> result = executor
|
||||||
|
.submit(new Callable<Collection<PackFile>>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<PackFile> call() throws Exception {
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
System.out.println("starting gc");
|
||||||
|
latch.countDown();
|
||||||
|
Collection<PackFile> r = gc.gc();
|
||||||
|
System.out.println("gc took "
|
||||||
|
+ (System.currentTimeMillis() - start) + " ms");
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
latch.await();
|
||||||
|
Thread.sleep(5);
|
||||||
|
executor.shutdownNow();
|
||||||
|
result.get();
|
||||||
|
fail("thread wasn't interrupted");
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
Throwable cause = e.getCause();
|
||||||
|
if (cause instanceof CancelledException) {
|
||||||
|
assertEquals(JGitText.get().operationCanceled,
|
||||||
|
cause.getMessage());
|
||||||
|
} else if (cause instanceof IOException) {
|
||||||
|
Throwable cause2 = cause.getCause();
|
||||||
|
assertTrue(cause2 instanceof InterruptedException
|
||||||
|
|| cause2 instanceof ExecutionException);
|
||||||
|
} else {
|
||||||
|
fail("unexpected exception " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -290,7 +290,7 @@ exceptionCaughtDuringExecutionOfTagCommand=Exception caught during execution of
|
||||||
exceptionHookExecutionInterrupted=Execution of "{0}" hook interrupted.
|
exceptionHookExecutionInterrupted=Execution of "{0}" hook interrupted.
|
||||||
exceptionOccurredDuringAddingOfOptionToALogCommand=Exception occurred during adding of {0} as option to a Log command
|
exceptionOccurredDuringAddingOfOptionToALogCommand=Exception occurred during adding of {0} as option to a Log command
|
||||||
exceptionOccurredDuringReadingOfGIT_DIR=Exception occurred during reading of $GIT_DIR/{0}. {1}
|
exceptionOccurredDuringReadingOfGIT_DIR=Exception occurred during reading of $GIT_DIR/{0}. {1}
|
||||||
exceptionWhileReadingPack=ERROR: Exception caught while accessing pack file {0}, the pack file might be corrupt, {1}. Caught {2} consecutive errors while trying to read this pack.
|
exceptionWhileReadingPack=Exception caught while accessing pack file {0}, the pack file might be corrupt. Caught {1} consecutive errors while trying to read this pack.
|
||||||
expectedACKNAKFoundEOF=Expected ACK/NAK, found EOF
|
expectedACKNAKFoundEOF=Expected ACK/NAK, found EOF
|
||||||
expectedACKNAKGot=Expected ACK/NAK, got: {0}
|
expectedACKNAKGot=Expected ACK/NAK, got: {0}
|
||||||
expectedBooleanStringValue=Expected boolean string value
|
expectedBooleanStringValue=Expected boolean string value
|
||||||
|
@ -520,7 +520,7 @@ openingConnection=Opening connection
|
||||||
operationCanceled=Operation {0} was canceled
|
operationCanceled=Operation {0} was canceled
|
||||||
outputHasAlreadyBeenStarted=Output has already been started.
|
outputHasAlreadyBeenStarted=Output has already been started.
|
||||||
overflowedReftableBlock=Overflowed reftable block
|
overflowedReftableBlock=Overflowed reftable block
|
||||||
packChecksumMismatch=Pack checksum mismatch detected for pack file {0}
|
packChecksumMismatch=Pack checksum mismatch detected for pack file {0}: .pack has {1} whilst .idx has {2}
|
||||||
packCorruptedWhileWritingToFilesystem=Pack corrupted while writing to filesystem
|
packCorruptedWhileWritingToFilesystem=Pack corrupted while writing to filesystem
|
||||||
packDoesNotMatchIndex=Pack {0} does not match index
|
packDoesNotMatchIndex=Pack {0} does not match index
|
||||||
packedRefsHandleIsStale=packed-refs handle is stale, {0}. retry
|
packedRefsHandleIsStale=packed-refs handle is stale, {0}. retry
|
||||||
|
@ -722,6 +722,7 @@ truncatedHunkOldLinesMissing=Truncated hunk, at least {0} old lines is missing
|
||||||
tSizeMustBeGreaterOrEqual1=tSize must be >= 1
|
tSizeMustBeGreaterOrEqual1=tSize must be >= 1
|
||||||
unableToCheckConnectivity=Unable to check connectivity.
|
unableToCheckConnectivity=Unable to check connectivity.
|
||||||
unableToCreateNewObject=Unable to create new object: {0}
|
unableToCreateNewObject=Unable to create new object: {0}
|
||||||
|
unableToReadPackfile=Unable to read packfile {0}
|
||||||
unableToRemovePath=Unable to remove path ''{0}''
|
unableToRemovePath=Unable to remove path ''{0}''
|
||||||
unableToStore=Unable to store {0}.
|
unableToStore=Unable to store {0}.
|
||||||
unableToWrite=Unable to write {0}
|
unableToWrite=Unable to write {0}
|
||||||
|
|
|
@ -782,6 +782,7 @@ public static JGitText get() {
|
||||||
/***/ public String tSizeMustBeGreaterOrEqual1;
|
/***/ public String tSizeMustBeGreaterOrEqual1;
|
||||||
/***/ public String unableToCheckConnectivity;
|
/***/ public String unableToCheckConnectivity;
|
||||||
/***/ public String unableToCreateNewObject;
|
/***/ public String unableToCreateNewObject;
|
||||||
|
/***/ public String unableToReadPackfile;
|
||||||
/***/ public String unableToRemovePath;
|
/***/ public String unableToRemovePath;
|
||||||
/***/ public String unableToStore;
|
/***/ public String unableToStore;
|
||||||
/***/ public String unableToWrite;
|
/***/ public String unableToWrite;
|
||||||
|
|
|
@ -1269,7 +1269,7 @@ private File nameFor(String name, String ext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkCancelled() throws CancelledException {
|
private void checkCancelled() throws CancelledException {
|
||||||
if (pm.isCancelled()) {
|
if (pm.isCancelled() || Thread.currentThread().isInterrupted()) {
|
||||||
throw new CancelledException(JGitText.get().operationCanceled);
|
throw new CancelledException(JGitText.get().operationCanceled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -359,7 +359,9 @@ boolean hasPackedObject(AnyObjectId objectId) {
|
||||||
// The hasObject call should have only touched the index,
|
// The hasObject call should have only touched the index,
|
||||||
// so any failure here indicates the index is unreadable
|
// so any failure here indicates the index is unreadable
|
||||||
// by this process, and the pack is likewise not readable.
|
// by this process, and the pack is likewise not readable.
|
||||||
LOG.warn("Unable to read packfile " + p.getPackFile(), e);
|
LOG.warn(MessageFormat.format(
|
||||||
|
JGitText.get().unableToReadPackfile,
|
||||||
|
p.getPackFile().getAbsolutePath()), e);
|
||||||
removePack(p);
|
removePack(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -652,7 +654,8 @@ private void handlePackError(IOException e, PackFile p) {
|
||||||
if ((e instanceof CorruptObjectException)
|
if ((e instanceof CorruptObjectException)
|
||||||
|| (e instanceof PackInvalidException)) {
|
|| (e instanceof PackInvalidException)) {
|
||||||
warnTmpl = JGitText.get().corruptPack;
|
warnTmpl = JGitText.get().corruptPack;
|
||||||
LOG.warn("Packfile " + p.getPackFile() + " is corrupted", e);
|
LOG.warn(MessageFormat.format(warnTmpl,
|
||||||
|
p.getPackFile().getAbsolutePath()), e);
|
||||||
// Assume the pack is corrupted, and remove it from the list.
|
// Assume the pack is corrupted, and remove it from the list.
|
||||||
removePack(p);
|
removePack(p);
|
||||||
} else if (e instanceof FileNotFoundException) {
|
} else if (e instanceof FileNotFoundException) {
|
||||||
|
@ -682,8 +685,8 @@ private void handlePackError(IOException e, PackFile p) {
|
||||||
// Don't remove the pack from the list, as the error may be
|
// Don't remove the pack from the list, as the error may be
|
||||||
// transient.
|
// transient.
|
||||||
LOG.error(MessageFormat.format(errTmpl,
|
LOG.error(MessageFormat.format(errTmpl,
|
||||||
p.getPackFile().getAbsolutePath()),
|
p.getPackFile().getAbsolutePath(),
|
||||||
Integer.valueOf(transientErrorCount), e);
|
Integer.valueOf(transientErrorCount)), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,7 +187,9 @@ private synchronized PackIndex idx() throws IOException {
|
||||||
} else if (!Arrays.equals(packChecksum, idx.packChecksum)) {
|
} else if (!Arrays.equals(packChecksum, idx.packChecksum)) {
|
||||||
throw new PackMismatchException(MessageFormat.format(
|
throw new PackMismatchException(MessageFormat.format(
|
||||||
JGitText.get().packChecksumMismatch,
|
JGitText.get().packChecksumMismatch,
|
||||||
packFile.getPath()));
|
packFile.getPath(),
|
||||||
|
ObjectId.fromRaw(packChecksum).name(),
|
||||||
|
ObjectId.fromRaw(idx.packChecksum).name()));
|
||||||
}
|
}
|
||||||
loadedIdx = idx;
|
loadedIdx = idx;
|
||||||
} catch (InterruptedIOException e) {
|
} catch (InterruptedIOException e) {
|
||||||
|
@ -753,10 +755,10 @@ private void onOpenPack() throws IOException {
|
||||||
fd.readFully(buf, 0, 20);
|
fd.readFully(buf, 0, 20);
|
||||||
if (!Arrays.equals(buf, packChecksum)) {
|
if (!Arrays.equals(buf, packChecksum)) {
|
||||||
throw new PackMismatchException(MessageFormat.format(
|
throw new PackMismatchException(MessageFormat.format(
|
||||||
JGitText.get().packObjectCountMismatch
|
JGitText.get().packChecksumMismatch,
|
||||||
, ObjectId.fromRaw(buf).name()
|
getPackFile(),
|
||||||
, ObjectId.fromRaw(idx.packChecksum).name()
|
ObjectId.fromRaw(buf).name(),
|
||||||
, getPackFile()));
|
ObjectId.fromRaw(idx.packChecksum).name()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue