Create parent directories when renaming a file in ApplyCommand

Before this change, applying a patch will fail if the destination directory
doesn't exist; after, the necessary parent directories are created.

If renaming the file fails, the directories won't be deleted, so this change
isn't atomic. However, ApplyCommand is already not atomic - if one hunk fails
to apply, other hunks still get applied - so I don't think that is a blocker.

Change-Id: Iea36138b806d4e7012176615bcc673756a82f365
Signed-off-by: Jack Wickham <jwickham@palantir.com>
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameNoHunks.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameNoHunks.patch
new file mode 100644
index 0000000..db543ab
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameNoHunks.patch
@@ -0,0 +1,4 @@
+diff --git a/RenameNoHunks b/nested/subdir/Renamed
+similarity index 100%
+rename from RenameNoHunks
+rename to nested/subdir/Renamed
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameNoHunks_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameNoHunks_PostImage
new file mode 100644
index 0000000..84275f9
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameNoHunks_PostImage
@@ -0,0 +1,4 @@
+line1
+line2
+line3
+line4
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameNoHunks_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameNoHunks_PreImage
new file mode 100644
index 0000000..84275f9
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameNoHunks_PreImage
@@ -0,0 +1,4 @@
+line1
+line2
+line3
+line4
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java
index 80bcb19..fb320cb 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java
@@ -250,6 +250,16 @@
 		assertFalse(new File(db.getWorkTree(), "NonASCIIDel").exists());
 	}
 
+	@Test
+	public void testRenameNoHunks() throws Exception {
+		ApplyResult result = init("RenameNoHunks", true, true);
+		assertEquals(1, result.getUpdatedFiles().size());
+		assertEquals(new File(db.getWorkTree(), "RenameNoHunks"), result.getUpdatedFiles()
+				.get(0));
+		checkFile(new File(db.getWorkTree(), "nested/subdir/Renamed"),
+				b.getString(0, b.size(), false));
+	}
+
 	private static byte[] readFile(String patchFile) throws IOException {
 		final InputStream in = getTestResource(patchFile);
 		if (in == null) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java
index 680f2ba..0c106ab 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java
@@ -114,6 +114,7 @@
 					f = getFile(fh.getOldPath(), false);
 					File dest = getFile(fh.getNewPath(), false);
 					try {
+						FileUtils.mkdirs(dest.getParentFile(), true);
 						FileUtils.rename(f, dest,
 								StandardCopyOption.ATOMIC_MOVE);
 					} catch (IOException e) {