<?php echo "Updating old commit authors...\n"; $table = new PhabricatorRepositoryCommit(); $table->openTransaction(); $conn = $table->establishConnection('w'); $data = new PhabricatorRepositoryCommitData(); $commits = queryfx_all($conn, 'SELECT c.id id, c.authorPHID authorPHID, d.commitDetails details FROM %T c JOIN %T d ON d.commitID = c.id WHERE c.authorPHID IS NULL FOR UPDATE', $table->getTableName(), $data->getTableName()); foreach ($commits as $commit) { $id = $commit['id']; $details = json_decode($commit['details'], true); $author_phid = idx($details, 'authorPHID'); if ($author_phid) { queryfx($conn, 'UPDATE %T SET authorPHID = %s WHERE id = %d', $table->getTableName(), $author_phid, $id); echo "#{$id}\n"; } } $table->saveTransaction(); echo "Done.\n"; echo "Updating old commit mailKeys...\n"; $table->openTransaction(); $commits = queryfx_all($conn, 'SELECT id FROM %T WHERE mailKey = %s FOR UPDATE', $table->getTableName(), ''); foreach ($commits as $commit) { $id = $commit['id']; queryfx($conn, 'UPDATE %T SET mailKey = %s WHERE id = %d', $table->getTableName(), Filesystem::readRandomCharacters(20), $id); echo "#{$id}\n"; } $table->saveTransaction();
private function recordCommit(PhabricatorRepository $repository, $commit_identifier, $epoch, $close_immediately, array $parents) { $commit = new PhabricatorRepositoryCommit(); $commit->setRepositoryID($repository->getID()); $commit->setCommitIdentifier($commit_identifier); $commit->setEpoch($epoch); if ($close_immediately) { $commit->setImportStatus(PhabricatorRepositoryCommit::IMPORTED_CLOSEABLE); } $data = new PhabricatorRepositoryCommitData(); $conn_w = $repository->establishConnection('w'); try { // If this commit has parents, look up their IDs. The parent commits // should always exist already. $parent_ids = array(); if ($parents) { $parent_rows = queryfx_all($conn_w, 'SELECT id, commitIdentifier FROM %T WHERE commitIdentifier IN (%Ls) AND repositoryID = %d', $commit->getTableName(), $parents, $repository->getID()); $parent_map = ipull($parent_rows, 'id', 'commitIdentifier'); foreach ($parents as $parent) { if (empty($parent_map[$parent])) { throw new Exception(pht('Unable to identify parent "%s"!', $parent)); } $parent_ids[] = $parent_map[$parent]; } } else { // Write an explicit 0 so we can distinguish between "really no // parents" and "data not available". if (!$repository->isSVN()) { $parent_ids = array(0); } } $commit->openTransaction(); $commit->save(); $data->setCommitID($commit->getID()); $data->save(); foreach ($parent_ids as $parent_id) { queryfx($conn_w, 'INSERT IGNORE INTO %T (childCommitID, parentCommitID) VALUES (%d, %d)', PhabricatorRepository::TABLE_PARENTS, $commit->getID(), $parent_id); } $commit->saveTransaction(); $this->insertTask($repository, $commit); queryfx($conn_w, 'INSERT INTO %T (repositoryID, size, lastCommitID, epoch) VALUES (%d, 1, %d, %d) ON DUPLICATE KEY UPDATE size = size + 1, lastCommitID = IF(VALUES(epoch) > epoch, VALUES(lastCommitID), lastCommitID), epoch = IF(VALUES(epoch) > epoch, VALUES(epoch), epoch)', PhabricatorRepository::TABLE_SUMMARY, $repository->getID(), $commit->getID(), $epoch); if ($this->repairMode) { // Normally, the query should throw a duplicate key exception. If we // reach this in repair mode, we've actually performed a repair. $this->log(pht('Repaired commit "%s".', $commit_identifier)); } PhutilEventEngine::dispatchEvent(new PhabricatorEvent(PhabricatorEventType::TYPE_DIFFUSION_DIDDISCOVERCOMMIT, array('repository' => $repository, 'commit' => $commit))); } catch (AphrontDuplicateKeyQueryException $ex) { $commit->killTransaction(); // Ignore. This can happen because we discover the same new commit // more than once when looking at history, or because of races or // data inconsistency or cosmic radiation; in any case, we're still // in a good state if we ignore the failure. } }
private function recordCommit(PhabricatorRepository $repository, $commit_identifier, $epoch, $branch = null) { $commit = new PhabricatorRepositoryCommit(); $commit->setRepositoryID($repository->getID()); $commit->setCommitIdentifier($commit_identifier); $commit->setEpoch($epoch); $data = new PhabricatorRepositoryCommitData(); if ($branch) { $data->setCommitDetail('seenOnBranches', array($branch)); } try { $commit->openTransaction(); $commit->save(); $data->setCommitID($commit->getID()); $data->save(); $commit->saveTransaction(); $event = new PhabricatorTimelineEvent('cmit', array('id' => $commit->getID())); $event->recordEvent(); $this->insertTask($repository, $commit); queryfx($repository->establishConnection('w'), 'INSERT INTO %T (repositoryID, size, lastCommitID, epoch) VALUES (%d, 1, %d, %d) ON DUPLICATE KEY UPDATE size = size + 1, lastCommitID = IF(VALUES(epoch) > epoch, VALUES(lastCommitID), lastCommitID), epoch = IF(VALUES(epoch) > epoch, VALUES(epoch), epoch)', PhabricatorRepository::TABLE_SUMMARY, $repository->getID(), $commit->getID(), $epoch); if ($this->repair) { // Normally, the query should throw a duplicate key exception. If we // reach this in repair mode, we've actually performed a repair. $this->log("Repaired commit '{$commit_identifier}'."); } $this->setCache($repository, $commit_identifier); PhutilEventEngine::dispatchEvent(new PhabricatorEvent(PhabricatorEventType::TYPE_DIFFUSION_DIDDISCOVERCOMMIT, array('repository' => $repository, 'commit' => $commit))); } catch (AphrontQueryDuplicateKeyException $ex) { $commit->killTransaction(); // Ignore. This can happen because we discover the same new commit // more than once when looking at history, or because of races or // data inconsistency or cosmic radiation; in any case, we're still // in a good state if we ignore the failure. $this->setCache($repository, $commit_identifier); } }