diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -985,6 +985,7 @@ 'DiffusionRepositoryFunctionDatasource' => 'applications/diffusion/typeahead/DiffusionRepositoryFunctionDatasource.php', 'DiffusionRepositoryHistoryManagementPanel' => 'applications/diffusion/management/DiffusionRepositoryHistoryManagementPanel.php', 'DiffusionRepositoryIdentityEditor' => 'applications/diffusion/editor/DiffusionRepositoryIdentityEditor.php', + 'DiffusionRepositoryIdentityEngine' => 'applications/diffusion/identity/DiffusionRepositoryIdentityEngine.php', 'DiffusionRepositoryIdentitySearchEngine' => 'applications/diffusion/query/DiffusionRepositoryIdentitySearchEngine.php', 'DiffusionRepositoryLimitsManagementPanel' => 'applications/diffusion/management/DiffusionRepositoryLimitsManagementPanel.php', 'DiffusionRepositoryListController' => 'applications/diffusion/controller/DiffusionRepositoryListController.php', @@ -6966,6 +6967,7 @@ 'DiffusionRepositoryFunctionDatasource' => 'PhabricatorTypeaheadCompositeDatasource', 'DiffusionRepositoryHistoryManagementPanel' => 'DiffusionRepositoryManagementPanel', 'DiffusionRepositoryIdentityEditor' => 'PhabricatorApplicationTransactionEditor', + 'DiffusionRepositoryIdentityEngine' => 'Phobject', 'DiffusionRepositoryIdentitySearchEngine' => 'PhabricatorApplicationSearchEngine', 'DiffusionRepositoryLimitsManagementPanel' => 'DiffusionRepositoryManagementPanel', 'DiffusionRepositoryListController' => 'DiffusionController', diff --git a/src/applications/diffusion/identity/DiffusionRepositoryIdentityEngine.php b/src/applications/diffusion/identity/DiffusionRepositoryIdentityEngine.php new file mode 100644 --- /dev/null +++ b/src/applications/diffusion/identity/DiffusionRepositoryIdentityEngine.php @@ -0,0 +1,80 @@ +viewer = $viewer; + return $this; + } + + public function getViewer() { + return $this->viewer; + } + + public function setSourcePHID($source_phid) { + $this->sourcePHID = $source_phid; + return $this; + } + + public function getSourcePHID() { + if (!$this->sourcePHID) { + throw new PhutilInvalidStateException('setSourcePHID'); + } + + return $this->sourcePHID; + } + + public function newResolvedIdentity($raw_identity) { + $identity = $this->loadRawIdentity($raw_identity); + + if (!$identity) { + $identity = $this->newIdentity($raw_identity); + } + + return $this->updateIdentity($identity); + } + + public function newUpdatedIdentity(PhabricatorRepositoryIdentity $identity) { + return $this->updateIdentity($identity); + } + + private function loadRawIdentity($raw_identity) { + $viewer = $this->getViewer(); + + return id(new PhabricatorRepositoryIdentityQuery()) + ->setViewer($viewer) + ->withIdentityNames(array($raw_identity)) + ->executeOne(); + } + + private function newIdentity($raw_identity) { + $source_phid = $this->getSourcePHID(); + + return id(new PhabricatorRepositoryIdentity()) + ->setAuthorPHID($source_phid) + ->setIdentityName($raw_identity); + } + + private function resolveIdentity(PhabricatorRepositoryIdentity $identity) { + $raw_identity = $identity->getIdentityName(); + + return id(new DiffusionResolveUserQuery()) + ->withName($raw_identity) + ->execute(); + } + + private function updateIdentity(PhabricatorRepositoryIdentity $identity) { + $resolved_phid = $this->resolveIdentity($identity); + + $identity + ->setAutomaticGuessedUserPHID($resolved_phid) + ->save(); + + return $identity; + } + +} diff --git a/src/applications/repository/management/PhabricatorRepositoryManagementRebuildIdentitiesWorkflow.php b/src/applications/repository/management/PhabricatorRepositoryManagementRebuildIdentitiesWorkflow.php --- a/src/applications/repository/management/PhabricatorRepositoryManagementRebuildIdentitiesWorkflow.php +++ b/src/applications/repository/management/PhabricatorRepositoryManagementRebuildIdentitiesWorkflow.php @@ -3,6 +3,8 @@ final class PhabricatorRepositoryManagementRebuildIdentitiesWorkflow extends PhabricatorRepositoryManagementWorkflow { + private $identityCache = array(); + protected function didConstruct() { $this ->setName('rebuild-identities') @@ -94,31 +96,21 @@ } private function getIdentityForCommit( - PhabricatorRepositoryCommit $commit, $identity_name) { - - static $seen = array(); - $identity_key = PhabricatorHash::digestForIndex($identity_name); - if (empty($seen[$identity_key])) { - try { - $user_phid = id(new DiffusionResolveUserQuery()) - ->withName($identity_name) - ->execute(); - - $identity = id(new PhabricatorRepositoryIdentity()) - ->setAuthorPHID($commit->getPHID()) - ->setIdentityName($identity_name) - ->setAutomaticGuessedUserPHID($user_phid) - ->save(); - } catch (AphrontDuplicateKeyQueryException $ex) { - // Somehow this identity already exists? - $identity = id(new PhabricatorRepositoryIdentityQuery()) - ->setViewer(PhabricatorUser::getOmnipotentUser()) - ->withIdentityNames(array($identity_name)) - ->executeOne(); - } - $seen[$identity_key] = $identity; + PhabricatorRepositoryCommit $commit, + $raw_identity) { + + if (!isset($this->identityCache[$raw_identity])) { + $viewer = $this->getViewer(); + + $identity = id(new DiffusionRepositoryIdentityEngine()) + ->setViewer($viewer) + ->setSourcePHID($commit->getPHID()) + ->newResolvedIdentity($raw_identity); + + $this->identityCache[$raw_identity] = $identity; } - return $seen[$identity_key]; + return $this->identityCache[$raw_identity]; } + } diff --git a/src/applications/repository/worker/PhabricatorRepositoryIdentityChangeWorker.php b/src/applications/repository/worker/PhabricatorRepositoryIdentityChangeWorker.php --- a/src/applications/repository/worker/PhabricatorRepositoryIdentityChangeWorker.php +++ b/src/applications/repository/worker/PhabricatorRepositoryIdentityChangeWorker.php @@ -1,7 +1,7 @@ executeOne(); $emails = id(new PhabricatorUserEmail())->loadAllWhere( - 'userPHID = %s ORDER BY address', + 'userPHID = %s', $user->getPHID()); + $identity_engine = id(new DiffusionRepositoryIdentityEngine()) + ->setViewer($viewer); + foreach ($emails as $email) { $identities = id(new PhabricatorRepositoryIdentityQuery()) ->setViewer($viewer) - ->withEmailAddresses($email->getAddress()) + ->withEmailAddresses(array($email->getAddress())) ->execute(); foreach ($identities as $identity) { - $identity->setAutomaticGuessedUserPHID($user->getPHID()) - ->save(); + $identity_engine->newUpdatedIdentity($identity); } } } diff --git a/src/applications/repository/worker/commitmessageparser/PhabricatorRepositoryCommitMessageParserWorker.php b/src/applications/repository/worker/commitmessageparser/PhabricatorRepositoryCommitMessageParserWorker.php --- a/src/applications/repository/worker/commitmessageparser/PhabricatorRepositoryCommitMessageParserWorker.php +++ b/src/applications/repository/worker/commitmessageparser/PhabricatorRepositoryCommitMessageParserWorker.php @@ -65,37 +65,20 @@ $message = $ref->getMessage(); $committer = $ref->getCommitter(); $hashes = $ref->getHashes(); + $has_committer = (bool)strlen($committer); - $author_identity = id(new PhabricatorRepositoryIdentityQuery()) - ->setViewer(PhabricatorUser::getOmnipotentUser()) - ->withIdentityNames(array($author)) - ->executeOne(); + $viewer = PhabricatorUser::getOmnipotentUser(); - if (!$author_identity) { - $author_identity = id(new PhabricatorRepositoryIdentity()) - ->setAuthorPHID($commit->getPHID()) - ->setIdentityName($author) - ->setAutomaticGuessedUserPHID( - $this->resolveUserPHID($commit, $author)) - ->save(); - } + $identity_engine = id(new DiffusionRepositoryIdentityEngine()) + ->setViewer($viewer) + ->setSourcePHID($commit->getPHID()); - $committer_identity = null; - - if ($committer) { - $committer_identity = id(new PhabricatorRepositoryIdentityQuery()) - ->setViewer(PhabricatorUser::getOmnipotentUser()) - ->withIdentityNames(array($committer)) - ->executeOne(); - - if (!$committer_identity) { - $committer_identity = id(new PhabricatorRepositoryIdentity()) - ->setAuthorPHID($commit->getPHID()) - ->setIdentityName($committer) - ->setAutomaticGuessedUserPHID( - $this->resolveUserPHID($commit, $committer)) - ->save(); - } + $author_identity = $identity_engine->newResolvedIdentity($author); + + if ($has_committer) { + $committer_identity = $identity_engine->newResolvedIdentity($committer); + } else { + $committer_identity = null; } $data = id(new PhabricatorRepositoryCommitData())->loadOneWhere( @@ -117,11 +100,11 @@ 'authorIdentityPHID', $author_identity->getPHID()); $data->setCommitDetail( 'authorPHID', - $this->resolveUserPHID($commit, $author)); + $author_identity->getCurrentEffectiveUserPHID()); $data->setCommitMessage($message); - if (strlen($committer)) { + if ($has_committer) { $data->setCommitDetail('committer', $committer); $data->setCommitDetail('committerName', $ref->getCommitterName()); @@ -129,7 +112,8 @@ $data->setCommitDetail( 'committerPHID', - $this->resolveUserPHID($commit, $committer)); + $committer_identity->getCurrentEffectiveUserPHID()); + $data->setCommitDetail( 'committerIdentityPHID', $committer_identity->getPHID()); @@ -177,15 +161,6 @@ PhabricatorRepositoryCommit::IMPORTED_MESSAGE); } - private function resolveUserPHID( - PhabricatorRepositoryCommit $commit, - $user_name) { - - return id(new DiffusionResolveUserQuery()) - ->withName($user_name) - ->execute(); - } - private function closeRevisions( PhabricatorUser $actor, DiffusionCommitRef $ref,