From ae045a9cf2668094bda56ae8e7b1afd981257ee8 Mon Sep 17 00:00:00 2001 From: epriestley Date: Sun, 4 Sep 2011 10:34:53 -0700 Subject: [PATCH] When doing partial subdirectory parses in Subversion, stub out foreign commit references Summary: See T325. We tentatively support doing partial subdirectory parses in Phabricator for Subversion, so you can elect to import only "trunk/local/" or similar. We do this by importing only some of the commits (those commits which affected that directory). In Subversion, you can also "svn cp svn+ssh://example.com/svnroot/trunk/foreign/example.c@13 local.c". This means that commits which reference "trunk/local/" may themselves reference foreign commits. Currently, we break in this case and can't find the commit reference. Instead, generate a foreign commit stub so we can at least point at some reasonable object. Test Plan: Successfully imported trunk/a/ of the test repo in T325 without errors. Verified commit 3 in that repo is imported as a foreign stub. Reviewers: jungejason, nh, tuomaspelkonen, aran Reviewed By: jungejason CC: aran, jungejason, epriestley Differential Revision: 892 --- ...rRepositorySvnCommitChangeParserWorker.php | 48 ++++++++++++++++++- .../commitchangeparser/svn/__init__.php | 1 + 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/applications/repository/worker/commitchangeparser/svn/PhabricatorRepositorySvnCommitChangeParserWorker.php b/src/applications/repository/worker/commitchangeparser/svn/PhabricatorRepositorySvnCommitChangeParserWorker.php index bb92e0e9c0..0965aaef9d 100644 --- a/src/applications/repository/worker/commitchangeparser/svn/PhabricatorRepositorySvnCommitChangeParserWorker.php +++ b/src/applications/repository/worker/commitchangeparser/svn/PhabricatorRepositorySvnCommitChangeParserWorker.php @@ -502,7 +502,53 @@ class PhabricatorRepositorySvnCommitChangeParserWorker $repository->getID(), $commits); - return ipull($commit_data, 'id', 'commitIdentifier'); + $commit_map = ipull($commit_data, 'id', 'commitIdentifier'); + + $need = array(); + foreach ($commits as $commit) { + if (empty($commit_map[$commit])) { + $need[] = $commit; + } + } + + // If we are parsing a Subversion repository and have been configured to + // import only some subdirectory of it, we may find commits which reference + // other foreign commits outside of the directory (for instance, because of + // a move or copy). Rather than trying to execute full parses on them, just + // create stub commits and identify the stubs as foreign commits. + if ($need) { + $subpath = $repository->getDetail('svn-subpath'); + if (!$subpath) { + $commits = implode(', ', $need); + throw new Exception( + "Missing commits ({$need}) in a SVN repository which is not ". + "configured for subdirectory-only parsing!"); + } + foreach ($need as $foreign_commit) { + $commit = new PhabricatorRepositoryCommit(); + $commit->setRepositoryID($repository->getID()); + $commit->setCommitIdentifier($foreign_commit); + $commit->setEpoch(0); + $commit->save(); + + $data = new PhabricatorRepositoryCommitData(); + $data->setCommitID($commit->getID()); + $data->setAuthorName(''); + $data->setCommitMessage(''); + $data->setCommitDetails( + array( + 'foreign-svn-stub' => true, + // Denormalize this to make it easier to debug cases where someone + // did half a parse and then changed the subdirectory or something + // like that. + 'svn-subpath' => $subpath, + )); + $data->save(); + $commit_map[$foreign_commit] = $commit->getID(); + } + } + + return $commit_map; } private function lookupPathFileType( diff --git a/src/applications/repository/worker/commitchangeparser/svn/__init__.php b/src/applications/repository/worker/commitchangeparser/svn/__init__.php index 27bd1250dc..88eb272294 100644 --- a/src/applications/repository/worker/commitchangeparser/svn/__init__.php +++ b/src/applications/repository/worker/commitchangeparser/svn/__init__.php @@ -8,6 +8,7 @@ phutil_require_module('phabricator', 'applications/differential/constants/changetype'); phutil_require_module('phabricator', 'applications/repository/storage/commit'); +phutil_require_module('phabricator', 'applications/repository/storage/commitdata'); phutil_require_module('phabricator', 'applications/repository/storage/repository'); phutil_require_module('phabricator', 'applications/repository/worker/commitchangeparser/base'); phutil_require_module('phabricator', 'storage/qsprintf');