Apply hunks when renaming or copying from patch files

When applying a patch that contains renames or copies using ApplyCommand,
also apply all hunks that apply to the renamed or copied file.

Change-Id: I9f3fa4370458bd7c14beeb2e2b49e846d70203cb
Signed-off-by: Jack Wickham <jwickham@palantir.com>
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/CopyWithHunks.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/CopyWithHunks.patch
new file mode 100644
index 0000000..44cb309
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/CopyWithHunks.patch
@@ -0,0 +1,13 @@
+diff --git a/CopyWithHunks b/CopyResult
+similarity index 75%
+copy from CopyWithHunks
+copy to CopyResult
+index 0000000..de98044
+--- a/CopyWithHunks
++++ b/CopyResult
+@@ -1,4 +1,4 @@
+ line1
+-line2
++lineB
+ line3
+ line4
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/CopyWithHunks_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/CopyWithHunks_PostImage
new file mode 100644
index 0000000..58d8046
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/CopyWithHunks_PostImage
@@ -0,0 +1,4 @@
+line1
+lineB
+line3
+line4
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/CopyWithHunks_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/CopyWithHunks_PreImage
new file mode 100644
index 0000000..84275f9
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/CopyWithHunks_PreImage
@@ -0,0 +1,4 @@
+line1
+line2
+line3
+line4
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameWithHunks.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameWithHunks.patch
new file mode 100644
index 0000000..06b166f
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameWithHunks.patch
@@ -0,0 +1,13 @@
+diff --git a/RenameWithHunks b/nested/subdir/Renamed
+similarity index 75%
+rename from RenameWithHunks
+rename to nested/subdir/Renamed
+index 0000000..de98044
+--- a/RenameWithHunks
++++ b/nested/subdir/Renamed
+@@ -1,4 +1,4 @@
+ line1
+-line2
++lineB
+ line3
+ line4
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameWithHunks_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameWithHunks_PostImage
new file mode 100644
index 0000000..58d8046
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameWithHunks_PostImage
@@ -0,0 +1,4 @@
+line1
+lineB
+line3
+line4
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameWithHunks_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameWithHunks_PreImage
new file mode 100644
index 0000000..84275f9
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameWithHunks_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 fb320cb..63cd21f 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
@@ -260,6 +260,26 @@
 				b.getString(0, b.size(), false));
 	}
 
+	@Test
+	public void testRenameWithHunks() throws Exception {
+		ApplyResult result = init("RenameWithHunks", true, true);
+		assertEquals(1, result.getUpdatedFiles().size());
+		assertEquals(new File(db.getWorkTree(), "RenameWithHunks"), result.getUpdatedFiles()
+				.get(0));
+		checkFile(new File(db.getWorkTree(), "nested/subdir/Renamed"),
+				b.getString(0, b.size(), false));
+	}
+
+	@Test
+	public void testCopyWithHunks() throws Exception {
+		ApplyResult result = init("CopyWithHunks", true, true);
+		assertEquals(1, result.getUpdatedFiles().size());
+		assertEquals(new File(db.getWorkTree(), "CopyWithHunks"), result.getUpdatedFiles()
+				.get(0));
+		checkFile(new File(db.getWorkTree(), "CopyResult"),
+				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 0c106ab..e11e683 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java
@@ -121,18 +121,19 @@
 						throw new PatchApplyException(MessageFormat.format(
 								JGitText.get().renameFileFailed, f, dest), e);
 					}
+					apply(dest, fh);
 					break;
 				case COPY:
 					f = getFile(fh.getOldPath(), false);
 					byte[] bs = IO.readFully(f);
-					FileOutputStream fos = new FileOutputStream(getFile(
-							fh.getNewPath(),
-							true));
+					File target = getFile(fh.getNewPath(), true);
+					FileOutputStream fos = new FileOutputStream(target);
 					try {
 						fos.write(bs);
 					} finally {
 						fos.close();
 					}
+					apply(target, fh);
 				}
 				r.addUpdatedFile(f);
 			}