From 02627b17622d42187195fb912fc2bf905e0036d9 Mon Sep 17 00:00:00 2001 From: epriestley Date: Mon, 7 Mar 2011 20:21:16 -0800 Subject: [PATCH] Fix 'arc patch' when adding files in new directories Summary: If you apply an arcbundle to a subversion working copy which adds files in new subdirectories, we fail to create and add the parent directories so the whole operation fails. Make sure we create and add any missing parent directories before apply patches. Test Plan: Applied Facebook diff #542056 to www@rE349795 cleanly, while it failed previously. Reviewed By: aran Reviewers: aran CC: aran Differential Revision: 62 --- src/workflow/patch/ArcanistPatchWorkflow.php | 39 ++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/workflow/patch/ArcanistPatchWorkflow.php b/src/workflow/patch/ArcanistPatchWorkflow.php index 241684d5..71ec07e7 100644 --- a/src/workflow/patch/ArcanistPatchWorkflow.php +++ b/src/workflow/patch/ArcanistPatchWorkflow.php @@ -237,6 +237,21 @@ EOTEXT } } + // Before we start doing anything, create all the directories we're going + // to add files to if they don't already exist. + foreach ($copies as $copy) { + list($src, $dst) = $copy; + $this->createParentDirectoryOf($dst); + } + + foreach ($patches as $path => $patch) { + $this->createParentDirectoryOf($path); + } + + foreach ($adds as $add) { + $this->createParentDirectoryOf($add); + } + foreach ($copies as $copy) { list($src, $dst) = $copy; passthru( @@ -336,4 +351,28 @@ EOTEXT // TODO: Pull open diffs from 'arc list'? return array('ARGUMENT'); } + + /** + * Create parent directories one at a time, since we need to "svn add" each + * one. (Technically we could "svn add" just the topmost new directory.) + */ + private function createParentDirectoryOf($path) { + $repository_api = $this->getRepositoryAPI(); + $dir = dirname($path); + if (Filesystem::pathExists($dir)) { + return; + } else { + // Make sure the parent directory exists before we make this one. + $this->createParentDirectoryOf($dir); + execx( + '(cd %s && mkdir %s)', + $repository_api->getPath(), + $dir); + passthru( + csprintf( + '(cd %s && svn add %s)', + $repository_api->getPath(), + $dir)); + } + } }