protected function recordCommit($commit_identifier, $epoch)
 {
     $repository = $this->getRepository();
     $commit = new PhabricatorRepositoryCommit();
     $commit->setRepositoryID($repository->getID());
     $commit->setCommitIdentifier($commit_identifier);
     $commit->setEpoch($epoch);
     try {
         $commit->save();
         $event = new PhabricatorTimelineEvent('cmit', array('id' => $commit->getID()));
         $event->recordEvent();
         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);
         $this->commitCache[$commit_identifier] = true;
     } catch (AphrontQueryDuplicateKeyException $ex) {
         // 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->commitCache[$commit_identifier] = true;
     }
     $this->stillWorking();
 }
Пример #2
0
 protected final function loadCommitsByIdentifiers(array $identifiers)
 {
     if (!$identifiers) {
         return array();
     }
     $commits = array();
     $commit_data = array();
     $drequest = $this->getRequest();
     $repository = $drequest->getRepository();
     $commits = id(new PhabricatorRepositoryCommit())->loadAllWhere('repositoryID = %d AND commitIdentifier IN (%Ls)', $repository->getID(), $identifiers);
     $commits = mpull($commits, null, 'getCommitIdentifier');
     // Build empty commit objects for every commit, so we can show unparsed
     // commits in history views as "unparsed" instead of not showing them. This
     // makes the process of importing and parsing commits much clearer to the
     // user.
     $commit_list = array();
     foreach ($identifiers as $identifier) {
         $commit_obj = idx($commits, $identifier);
         if (!$commit_obj) {
             $commit_obj = new PhabricatorRepositoryCommit();
             $commit_obj->setRepositoryID($repository->getID());
             $commit_obj->setCommitIdentifier($identifier);
             $commit_obj->setIsUnparsed(true);
             $commit_obj->makeEphemeral();
         }
         $commit_list[$identifier] = $commit_obj;
     }
     $commits = $commit_list;
     $commit_ids = array_filter(mpull($commits, 'getID'));
     if ($commit_ids) {
         $commit_data = id(new PhabricatorRepositoryCommitData())->loadAllWhere('commitID in (%Ld)', $commit_ids);
         $commit_data = mpull($commit_data, null, 'getCommitID');
     }
     foreach ($commits as $commit) {
         if (!$commit->getID()) {
             continue;
         }
         if (idx($commit_data, $commit->getID())) {
             $commit->attachCommitData($commit_data[$commit->getID()]);
         }
     }
     return $commits;
 }
 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 lookupSvnCommits(PhabricatorRepository $repository, array $commits)
 {
     if (!$commits) {
         return array();
     }
     $commit_table = new PhabricatorRepositoryCommit();
     $commit_data = queryfx_all($commit_table->establishConnection('w'), 'SELECT id, commitIdentifier FROM %T
     WHERE repositoryID = %d AND commitIdentifier in (%Ls)', $commit_table->getTableName(), $repository->getID(), $commits);
     $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);
             // Mark this commit as imported so it doesn't prevent the repository
             // from transitioning into the "Imported" state.
             $commit->setImportStatus(PhabricatorRepositoryCommit::IMPORTED_ALL);
             $commit->save();
             $data = new PhabricatorRepositoryCommitData();
             $data->setCommitID($commit->getID());
             $data->setAuthorName('');
             $data->setCommitMessage('');
             $data->setCommitDetails(array('foreign-svn-stub' => true, 'svn-subpath' => $subpath));
             $data->save();
             $commit_map[$foreign_commit] = $commit->getID();
         }
     }
     return $commit_map;
 }
 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);
     }
 }