Преглед на файлове

Merge "Fix GC for FileRepo in case packfile renames fail"

tags/v3.0.0.201305080800-m7
Matthias Sohn преди 11 години
родител
ревизия
509c0b58ee

+ 7
- 0
org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GCTest.java Целия файл

@@ -435,6 +435,13 @@ public class GCTest extends LocalDiskRepositoryTestCase {
assertEquals(0, stats.numberOfLooseObjects);
assertEquals(4, stats.numberOfPackedObjects);
assertEquals(1, stats.numberOfPackFiles);

// Do the gc again and check that it hasn't changed anything
gc.gc();
stats = gc.getStatistics();
assertEquals(0, stats.numberOfLooseObjects);
assertEquals(4, stats.numberOfPackedObjects);
assertEquals(1, stats.numberOfPackFiles);
}

@Test

+ 15
- 3
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java Целия файл

@@ -735,11 +735,21 @@ public class GC {

// rename the temporary files to real files
File realPack = nameFor(id, ".pack"); //$NON-NLS-1$

// if the packfile already exists (because we are rewriting a
// packfile for the same set of objects maybe with different
// PackConfig) then make sure we get rid of all handles on the file.
// Windows will not allow for rename otherwise.
if (realPack.exists())
for (PackFile p : repo.getObjectDatabase().getPacks())
if (realPack.getPath().equals(p.getPackFile().getPath())) {
p.close();
break;
}
tmpPack.setReadOnly();
boolean delete = true;
try {
if (!tmpPack.renameTo(realPack))
return null;
FileUtils.rename(tmpPack, realPack);
delete = false;
for (Map.Entry<PackExt, File> tmpEntry : tmpExts.entrySet()) {
File tmpExt = tmpEntry.getValue();
@@ -747,7 +757,9 @@ public class GC {

File realExt = nameFor(
id, "." + tmpEntry.getKey().getExtension()); //$NON-NLS-1$
if (!tmpExt.renameTo(realExt)) {
try {
FileUtils.rename(tmpExt, realExt);
} catch (IOException e) {
File newExt = new File(realExt.getParentFile(),
realExt.getName() + ".new"); //$NON-NLS-1$
if (!tmpExt.renameTo(newExt))

+ 33
- 0
org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java Целия файл

@@ -167,6 +167,39 @@ public class FileUtils {
}
}

/**
* Rename a file or folder. If the rename fails and if we are running on a
* filesystem where it makes sense to repeat a failing rename then repeat
* the rename operation up to 9 times with 100ms sleep time between two
* calls
*
* @see FS#retryFailedLockFileCommit()
* @param src
* the old {@code File}
* @param dst
* the new {@code File}
* @throws IOException
* if the rename has failed
*/
public static void rename(final File src, final File dst)
throws IOException {
int attempts = FS.DETECTED.retryFailedLockFileCommit() ? 10 : 1;
while (--attempts >= 0) {
if (src.renameTo(dst))
return;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new IOException(MessageFormat.format(
JGitText.get().renameFileFailed, src.getAbsolutePath(),
dst.getAbsolutePath()));
}
}
throw new IOException(MessageFormat.format(
JGitText.get().renameFileFailed, src.getAbsolutePath(),
dst.getAbsolutePath()));
}

/**
* Creates the directory named by this abstract pathname.
*

Loading…
Отказ
Запис