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>
This commit is contained in:
Jack Wickham 2020-04-17 18:33:39 +01:00 committed by Matthias Sohn
parent 0a2a094fea
commit d69c0ef5bd
5 changed files with 11 additions and 0 deletions

View File

@ -250,6 +250,16 @@ public void testNonASCIIDel() throws Exception {
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) {

View File

@ -114,6 +114,7 @@ public ApplyResult call() throws GitAPIException, PatchFormatException,
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) {