protected function executeQuery()
 {
     $drequest = $this->getRequest();
     $repository = $drequest->getRepository();
     $effective_commit = $this->getEffectiveCommit();
     if (!$effective_commit) {
         return null;
     }
     // TODO: This side effect is kind of skethcy.
     $drequest->setCommit($effective_commit);
     $query = DiffusionRawDiffQuery::newFromDiffusionRequest($drequest);
     $raw_diff = $query->loadRawDiff();
     $parser = new ArcanistDiffParser();
     $try_encoding = $repository->getDetail('encoding');
     if ($try_encoding) {
         $parser->setTryEncoding($try_encoding);
     }
     $parser->setDetectBinaryFiles(true);
     $changes = $parser->parseDiff($raw_diff);
     $diff = DifferentialDiff::newFromRawChanges($changes);
     $changesets = $diff->getChangesets();
     $changeset = reset($changesets);
     $this->renderingReference = $drequest->generateURI(array('action' => 'rendering-ref'));
     return $changeset;
 }
 protected function getResult(ConduitAPIRequest $request)
 {
     $drequest = $this->getDiffusionRequest();
     $query = DiffusionRawDiffQuery::newFromDiffusionRequest($drequest);
     $lines_of_context = $request->getValue('linesOfContext');
     if ($lines_of_context !== null) {
         $query->setLinesOfContext($lines_of_context);
     }
     $against_commit = $request->getValue('againstCommit');
     if ($against_commit !== null) {
         $query->setAgainstCommit($against_commit);
     }
     return $query->respondToConduitRequest($request);
 }
 private function loadRawPatchText(PhabricatorRepository $repository, PhabricatorRepositoryCommit $commit)
 {
     $drequest = DiffusionRequest::newFromDictionary(array('user' => PhabricatorUser::getOmnipotentUser(), 'repository' => $repository, 'commit' => $commit->getCommitIdentifier()));
     $raw_query = DiffusionRawDiffQuery::newFromDiffusionRequest($drequest);
     $raw_query->setLinesOfContext(3);
     $time_key = 'metamta.diffusion.time-limit';
     $byte_key = 'metamta.diffusion.byte-limit';
     $time_limit = PhabricatorEnv::getEnvConfig($time_key);
     $byte_limit = PhabricatorEnv::getEnvConfig($byte_key);
     if ($time_limit) {
         $raw_query->setTimeout($time_limit);
     }
     $raw_diff = $raw_query->loadRawDiff();
     $size = strlen($raw_diff);
     if ($byte_limit && $size > $byte_limit) {
         $pretty_size = phutil_format_bytes($size);
         $pretty_limit = phutil_format_bytes($byte_limit);
         throw new Exception(pht('Patch size of %s exceeds configured byte size limit (%s) of %s.', $pretty_size, $byte_key, $pretty_limit));
     }
     return $raw_diff;
 }
 protected function getResult(ConduitAPIRequest $request)
 {
     $drequest = $this->getDiffusionRequest();
     $raw_query = DiffusionRawDiffQuery::newFromDiffusionRequest($drequest);
     $timeout = $request->getValue('timeout');
     if ($timeout !== null) {
         $raw_query->setTimeout($timeout);
     }
     $lines_of_context = $request->getValue('linesOfContext');
     if ($lines_of_context !== null) {
         $raw_query->setLinesOfContext($lines_of_context);
     }
     $against_commit = $request->getValue('againstCommit');
     if ($against_commit !== null) {
         $raw_query->setAgainstCommit($against_commit);
     }
     $byte_limit = $request->getValue('byteLimit');
     if ($byte_limit !== null) {
         $raw_query->setByteLimit($byte_limit);
     }
     return $raw_query->loadRawDiff();
 }
 public function loadChangesetsForCommit($identifier)
 {
     $byte_limit = HeraldCommitAdapter::getEnormousByteLimit();
     $time_limit = HeraldCommitAdapter::getEnormousTimeLimit();
     $vcs = $this->getRepository()->getVersionControlSystem();
     switch ($vcs) {
         case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
         case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
             // For git and hg, we can use normal commands.
             $drequest = DiffusionRequest::newFromDictionary(array('repository' => $this->getRepository(), 'user' => $this->getViewer(), 'commit' => $identifier));
             $raw_diff = DiffusionRawDiffQuery::newFromDiffusionRequest($drequest)->setTimeout($time_limit)->setByteLimit($byte_limit)->setLinesOfContext(0)->loadRawDiff();
             break;
         case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
             // TODO: This diff has 3 lines of context, which produces slightly
             // incorrect "added file content" and "removed file content" results.
             // This may also choke on binaries, but "svnlook diff" does not support
             // the "--diff-cmd" flag.
             // For subversion, we need to use `svnlook`.
             $future = new ExecFuture('svnlook diff -t %s %s', $this->subversionTransaction, $this->subversionRepository);
             $future->setTimeout($time_limit);
             $future->setStdoutSizeLimit($byte_limit);
             $future->setStderrSizeLimit($byte_limit);
             list($raw_diff) = $future->resolvex();
             break;
         default:
             throw new Exception(pht("Unknown VCS '%s!'", $vcs));
     }
     if (strlen($raw_diff) >= $byte_limit) {
         throw new Exception(pht('The raw text of this change is enormous (larger than %d ' . 'bytes). Herald can not process it.', $byte_limit));
     }
     if (!strlen($raw_diff)) {
         // If the commit is actually empty, just return no changesets.
         return array();
     }
     $parser = new ArcanistDiffParser();
     $changes = $parser->parseDiff($raw_diff);
     $diff = DifferentialDiff::newEphemeralFromRawChanges($changes);
     return $diff->getChangesets();
 }
 private function attachToRevision(DifferentialRevision $revision, $actor_phid)
 {
     $drequest = DiffusionRequest::newFromDictionary(array('repository' => $this->repository, 'commit' => $this->commit->getCommitIdentifier()));
     $raw_diff = DiffusionRawDiffQuery::newFromDiffusionRequest($drequest)->loadRawDiff();
     $changes = id(new ArcanistDiffParser())->parseDiff($raw_diff);
     $diff = DifferentialDiff::newFromRawChanges($changes)->setRevisionID($revision->getID())->setAuthorPHID($actor_phid)->setCreationMethod('commit')->setSourceControlSystem($this->repository->getVersionControlSystem())->setLintStatus(DifferentialLintStatus::LINT_SKIP)->setUnitStatus(DifferentialUnitStatus::UNIT_SKIP)->setDateCreated($this->commit->getEpoch())->setDescription('Commit r' . $this->repository->getCallsign() . $this->commit->getCommitIdentifier());
     // TODO: This is not correct in SVN where one repository can have multiple
     // Arcanist projects.
     $arcanist_project = id(new PhabricatorRepositoryArcanistProject())->loadOneWhere('repositoryID = %d LIMIT 1', $this->repository->getID());
     if ($arcanist_project) {
         $diff->setArcanistProjectPHID($arcanist_project->getPHID());
     }
     $parents = DiffusionCommitParentsQuery::newFromDiffusionRequest($drequest)->loadParents();
     if ($parents) {
         $diff->setSourceControlBaseRevision(head_key($parents));
     }
     // TODO: Attach binary files.
     $revision->setLineCount($diff->getLineCount());
     return $diff->save();
 }
 private function getBeforeLineNumber($target_commit)
 {
     $drequest = $this->getDiffusionRequest();
     $line = $drequest->getLine();
     if (!$line) {
         return null;
     }
     $diff_query = DiffusionRawDiffQuery::newFromDiffusionRequest($drequest);
     $diff_query->setAgainstCommit($target_commit);
     try {
         $raw_diff = $diff_query->loadRawDiff();
         $old_line = 0;
         $new_line = 0;
         foreach (explode("\n", $raw_diff) as $text) {
             if ($text[0] == '-' || $text[0] == ' ') {
                 $old_line++;
             }
             if ($text[0] == '+' || $text[0] == ' ') {
                 $new_line++;
             }
             if ($new_line == $line) {
                 return $old_line;
             }
         }
         // We didn't find the target line.
         return $line;
     } catch (Exception $ex) {
         return $line;
     }
 }
 private function getGitOrMercurialResult(ConduitAPIRequest $request)
 {
     $drequest = $this->getDiffusionRequest();
     $repository = $drequest->getRepository();
     $effective_commit = $this->getEffectiveCommit($request);
     if (!$effective_commit) {
         return $this->getEmptyResult(1);
     }
     $raw_query = DiffusionRawDiffQuery::newFromDiffusionRequest($drequest)->setAnchorCommit($effective_commit);
     $raw_diff = $raw_query->executeInline();
     if (!$raw_diff) {
         return $this->getEmptyResult(2);
     }
     $parser = $this->getDefaultParser();
     $changes = $parser->parseDiff($raw_diff);
     return $changes;
 }
 private function buildRawDiffResponse(DiffusionRequest $drequest)
 {
     $raw_query = DiffusionRawDiffQuery::newFromDiffusionRequest($drequest);
     $raw_diff = $raw_query->loadRawDiff();
     $file = PhabricatorFile::buildFromFileDataOrHash($raw_diff, array('name' => $drequest->getCommit() . '.diff'));
     return id(new AphrontRedirectResponse())->setURI($file->getBestURI());
 }