Merge "Extend FileUtils.rename to common git semantics"
This commit is contained in:
commit
b1d191a155
|
@ -45,6 +45,7 @@
|
|||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.endsWith;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
@ -52,6 +53,7 @@
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.jgit.junit.JGitTestUtil;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
@ -321,4 +323,71 @@ public void testDeleteNotEmptyTreeNotOkButIgnoreFail() throws IOException {
|
|||
assertTrue(f.exists());
|
||||
assertFalse(e.exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRenameOverNonExistingFile() throws IOException {
|
||||
File d = new File(trash, "d");
|
||||
FileUtils.mkdirs(d);
|
||||
File f1 = new File(trash, "d/f");
|
||||
File f2 = new File(trash, "d/g");
|
||||
JGitTestUtil.write(f1, "f1");
|
||||
// test
|
||||
FileUtils.rename(f1, f2);
|
||||
assertFalse(f1.exists());
|
||||
assertTrue(f2.exists());
|
||||
assertEquals("f1", JGitTestUtil.read(f2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRenameOverExistingFile() throws IOException {
|
||||
File d = new File(trash, "d");
|
||||
FileUtils.mkdirs(d);
|
||||
File f1 = new File(trash, "d/f");
|
||||
File f2 = new File(trash, "d/g");
|
||||
JGitTestUtil.write(f1, "f1");
|
||||
JGitTestUtil.write(f2, "f2");
|
||||
// test
|
||||
FileUtils.rename(f1, f2);
|
||||
assertFalse(f1.exists());
|
||||
assertTrue(f2.exists());
|
||||
assertEquals("f1", JGitTestUtil.read(f2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRenameOverExistingNonEmptyDirectory() throws IOException {
|
||||
File d = new File(trash, "d");
|
||||
FileUtils.mkdirs(d);
|
||||
File f1 = new File(trash, "d/f");
|
||||
File f2 = new File(trash, "d/g");
|
||||
File d1 = new File(trash, "d/g/h/i");
|
||||
File f3 = new File(trash, "d/g/h/f");
|
||||
FileUtils.mkdirs(d1);
|
||||
JGitTestUtil.write(f1, "f1");
|
||||
JGitTestUtil.write(f3, "f3");
|
||||
// test
|
||||
try {
|
||||
FileUtils.rename(f1, f2);
|
||||
fail("rename to non-empty directory should fail");
|
||||
} catch (IOException e) {
|
||||
assertEquals("f1", JGitTestUtil.read(f1)); // untouched source
|
||||
assertEquals("f3", JGitTestUtil.read(f3)); // untouched
|
||||
// empty directories within f2 may or may not have been deleted
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRenameOverExistingEmptyDirectory() throws IOException {
|
||||
File d = new File(trash, "d");
|
||||
FileUtils.mkdirs(d);
|
||||
File f1 = new File(trash, "d/f");
|
||||
File f2 = new File(trash, "d/g");
|
||||
File d1 = new File(trash, "d/g/h/i");
|
||||
FileUtils.mkdirs(d1);
|
||||
JGitTestUtil.write(f1, "f1");
|
||||
// test
|
||||
FileUtils.rename(f1, f2);
|
||||
assertFalse(f1.exists());
|
||||
assertTrue(f2.exists());
|
||||
assertEquals("f1", JGitTestUtil.read(f2));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -171,7 +171,14 @@ public static void delete(final File f, int options) throws IOException {
|
|||
* 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
|
||||
* calls. Furthermore if the destination exists and is directory hierarchy
|
||||
* with only directories in it, the whole directory hierarchy will be
|
||||
* deleted. If the target represents a non-empty directory structure, empty
|
||||
* subdirectories within that structure may or may not be deleted even if
|
||||
* the method fails. Furthermore if the destination exists and is a file
|
||||
* then the file will be deleted and then the rename is retried.
|
||||
* <p>
|
||||
* This operation is <em>not</me> atomic.
|
||||
*
|
||||
* @see FS#retryFailedLockFileCommit()
|
||||
* @param src
|
||||
|
@ -188,6 +195,15 @@ public static void rename(final File src, final File dst)
|
|||
while (--attempts >= 0) {
|
||||
if (src.renameTo(dst))
|
||||
return;
|
||||
try {
|
||||
if (!dst.delete())
|
||||
delete(dst, EMPTY_DIRECTORIES_ONLY | RECURSIVE);
|
||||
// On *nix there is no try, you do or do not
|
||||
if (src.renameTo(dst))
|
||||
return;
|
||||
} catch (IOException e) {
|
||||
// ignore and continue retry
|
||||
}
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
|
|
Loading…
Reference in New Issue