public function testDetectSlowCopiedCode()
    {
        // This tests that the detector has a reasonable runtime when a diff
        // contains a very large number of identical lines. See T5041.
        $parser = new ArcanistDiffParser();
        $line = str_repeat('x', 60);
        $oline = '-' . $line . "\n";
        $nline = '+' . $line . "\n";
        $n = 1000;
        $oblock = str_repeat($oline, $n);
        $nblock = str_repeat($nline, $n);
        $raw_diff = <<<EODIFF
diff --git a/dst b/dst
new file mode 100644
index 0000000..1234567
--- /dev/null
+++ b/dst
@@ -0,0 +1,{$n} @@
{$nblock}
diff --git a/src b/src
deleted file mode 100644
index 123457..0000000
--- a/src
+++ /dev/null
@@ -1,{$n} +0,0 @@
{$oblock}
EODIFF;
        $diff = DifferentialDiff::newFromRawChanges($parser->parseDiff($raw_diff));
        $this->assertTrue(true);
    }
 private function buildChangesetParser($type, $data, $file)
 {
     $parser = new ArcanistDiffParser();
     $changes = $parser->parseDiff($data);
     $diff = DifferentialDiff::newFromRawChanges($changes);
     if (count($diff->getChangesets()) !== 1) {
         throw new Exception("Expected one changeset: {$file}");
     }
     $changeset = head($diff->getChangesets());
     $engine = new PhabricatorMarkupEngine();
     $engine->setViewer(new PhabricatorUser());
     $cparser = new DifferentialChangesetParser();
     $cparser->setDisableCache(true);
     $cparser->setChangeset($changeset);
     $cparser->setMarkupEngine($engine);
     if ($type == 'one') {
         $cparser->setRenderer(new DifferentialChangesetOneUpTestRenderer());
     } else {
         if ($type == 'two') {
             $cparser->setRenderer(new DifferentialChangesetTwoUpTestRenderer());
         } else {
             throw new Exception("Unknown renderer type '{$type}'!");
         }
     }
     return $cparser;
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $viewer = $request->getUser();
     $raw_diff = $request->getValue('diff');
     $repository_phid = $request->getValue('repositoryPHID');
     if ($repository_phid) {
         $repository = id(new PhabricatorRepositoryQuery())->setViewer($viewer)->withPHIDs(array($repository_phid))->executeOne();
         if (!$repository) {
             throw new Exception(pht('No such repository "%s"!', $repository_phid));
         }
     } else {
         $repository = null;
     }
     $parser = new ArcanistDiffParser();
     $changes = $parser->parseDiff($raw_diff);
     $diff = DifferentialDiff::newFromRawChanges($changes);
     $diff->setLintStatus(DifferentialLintStatus::LINT_SKIP);
     $diff->setUnitStatus(DifferentialUnitStatus::UNIT_SKIP);
     $diff->setAuthorPHID($viewer->getPHID());
     $diff->setCreationMethod('web');
     if ($repository) {
         $diff->setRepositoryPHID($repository->getPHID());
     }
     id(new DifferentialDiffEditor())->setActor($viewer)->setContentSource(PhabricatorContentSource::newFromConduitRequest($request))->saveDiff($diff);
     return $this->buildDiffInfoDictionary($diff);
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     if ($request->isFormPost()) {
         $parser = new ArcanistDiffParser();
         $diff = null;
         try {
             $diff = PhabricatorFile::readUploadedFileData($_FILES['diff-file']);
         } catch (Exception $ex) {
             $diff = $request->getStr('diff');
         }
         $changes = $parser->parseDiff($diff);
         $diff = DifferentialDiff::newFromRawChanges($changes);
         $diff->setLintStatus(DifferentialLintStatus::LINT_SKIP);
         $diff->setUnitStatus(DifferentialLintStatus::LINT_SKIP);
         $diff->setAuthorPHID($request->getUser()->getPHID());
         $diff->setCreationMethod('web');
         $diff->save();
         return id(new AphrontRedirectResponse())->setURI('/differential/diff/' . $diff->getID() . '/');
     }
     $form = new AphrontFormView();
     $arcanist_href = PhabricatorEnv::getDoclink('article/Arcanist_User_Guide.html');
     $arcanist_link = phutil_render_tag('a', array('href' => $arcanist_href, 'target' => '_blank'), 'Arcanist');
     $form->setAction('/differential/diff/create/')->setEncType('multipart/form-data')->setUser($request->getUser())->appendChild('<p class="aphront-form-instructions">The best way to create a ' . "Differential diff is by using {$arcanist_link}, but you " . 'can also just paste a diff (e.g., from <tt>svn diff</tt> or ' . '<tt>git diff</tt>) into this box or upload it as a file if you ' . 'really want.</p>')->appendChild(id(new AphrontFormTextAreaControl())->setLabel('Raw Diff')->setName('diff')->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL))->appendChild(id(new AphrontFormFileControl())->setLabel('Raw Diff from file')->setName('diff-file'))->appendChild(id(new AphrontFormSubmitControl())->setValue("Create Diff »"));
     $panel = new AphrontPanelView();
     $panel->setHeader('Create New Diff');
     $panel->appendChild($form);
     $panel->setWidth(AphrontPanelView::WIDTH_FORM);
     return $this->buildStandardPageResponse($panel, array('title' => 'Create Diff', 'tab' => 'create'));
 }
 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);
     $path = $drequest->getPath();
     list($raw_diff) = $repository->execxLocalCommand('diff -U %d --git --change %s -- %s', 65535, $effective_commit, $path);
     $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->getBranchURIComponent($drequest->getBranch()) . $drequest->getPath() . ';' . $drequest->getCommit();
     return $changeset;
 }
 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;
 }
    public function testGenerateHarbormasterAutotargets()
    {
        $viewer = $this->generateNewTestUser();
        $raw_diff = <<<EODIFF
diff --git a/fruit b/fruit
new file mode 100644
index 0000000..1c0f49d
--- /dev/null
+++ b/fruit
@@ -0,0 +1,2 @@
+apal
+banan
EODIFF;
        $parser = new ArcanistDiffParser();
        $changes = $parser->parseDiff($raw_diff);
        $diff = DifferentialDiff::newFromRawChanges($viewer, $changes)->setLintStatus(DifferentialLintStatus::LINT_AUTO_SKIP)->setUnitStatus(DifferentialUnitStatus::UNIT_AUTO_SKIP)->attachRevision(null)->save();
        $params = array('objectPHID' => $diff->getPHID(), 'targetKeys' => array(HarbormasterArcLintBuildStepImplementation::STEPKEY, HarbormasterArcUnitBuildStepImplementation::STEPKEY));
        // Creation of autotargets should work from an empty state.
        $result = id(new ConduitCall('harbormaster.queryautotargets', $params))->setUser($viewer)->execute();
        $targets = idx($result, 'targetMap');
        foreach ($params['targetKeys'] as $target_key) {
            $this->assertTrue((bool) $result['targetMap'][$target_key]);
        }
        // Querying the same autotargets again should produce the same results,
        // not make new ones.
        $retry = id(new ConduitCall('harbormaster.queryautotargets', $params))->setUser($viewer)->execute();
        $this->assertEqual($result, $retry);
    }
 protected function executeQuery()
 {
     $drequest = $this->getRequest();
     $repository = $drequest->getRepository();
     if (!$drequest->getRawCommit()) {
         $effective_commit = $this->getEffectiveCommit();
         if (!$effective_commit) {
             return null;
         }
         // TODO: This side effect is kind of skethcy.
         $drequest->setCommit($effective_commit);
     } else {
         $effective_commit = $drequest->getCommit();
     }
     $options = array('-M', '-C', '--no-ext-diff', '--no-color', '--src-prefix=a/', '--dst-prefix=b/', '-U65535');
     $options = implode(' ', $options);
     list($raw_diff) = execx("(cd %s && git diff {$options} %s^ %s -- %s)", $repository->getDetail('local-path'), $effective_commit, $effective_commit, $drequest->getPath());
     $parser = new ArcanistDiffParser();
     $parser->setDetectBinaryFiles(true);
     $changes = $parser->parseDiff($raw_diff);
     $diff = DifferentialDiff::newFromRawChanges($changes);
     $changesets = $diff->getChangesets();
     $changeset = reset($changesets);
     $this->renderingReference = $drequest->getBranchURIComponent($drequest->getBranch()) . $drequest->getPath() . ';' . $drequest->getCommit();
     return $changeset;
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $viewer = $request->getUser();
     $raw_diff = $request->getValue('diff');
     $repository_phid = $request->getValue('repositoryPHID');
     if ($repository_phid) {
         $repository = id(new PhabricatorRepositoryQuery())->setViewer($viewer)->withPHIDs(array($repository_phid))->executeOne();
         if (!$repository) {
             throw new Exception(pht('No such repository "%s"!', $repository_phid));
         }
     }
     $parser = new ArcanistDiffParser();
     $changes = $parser->parseDiff($raw_diff);
     $diff = DifferentialDiff::newFromRawChanges($viewer, $changes);
     // We're bounded by doing INSERTs for all the hunks and changesets, so
     // estimate the number of inserts we'll require.
     $size = 0;
     foreach ($diff->getChangesets() as $changeset) {
         $hunks = $changeset->getHunks();
         $size += 1 + count($hunks);
     }
     $raw_limit = 10000;
     if ($size > $raw_limit) {
         throw new Exception(pht('The raw diff you have submitted is too large to parse (it affects ' . 'more than %s paths and hunks). Differential should only be used ' . 'for changes which are small enough to receive detailed human ' . 'review. See "Differential User Guide: Large Changes" in the ' . 'documentation for more information.', new PhutilNumber($raw_limit)));
     }
     $diff_data_dict = array('creationMethod' => 'web', 'authorPHID' => $viewer->getPHID(), 'repositoryPHID' => $repository_phid, 'lintStatus' => DifferentialLintStatus::LINT_SKIP, 'unitStatus' => DifferentialUnitStatus::UNIT_SKIP);
     $xactions = array(id(new DifferentialDiffTransaction())->setTransactionType(DifferentialDiffTransaction::TYPE_DIFF_CREATE)->setNewValue($diff_data_dict));
     if ($request->getValue('viewPolicy')) {
         $xactions[] = id(new DifferentialDiffTransaction())->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)->setNewValue($request->getValue('viewPolicy'));
     }
     id(new DifferentialDiffEditor())->setActor($viewer)->setContentSource($request->newContentSource())->setContinueOnNoEffect(true)->setLookupRepository(false)->applyTransactions($diff, $xactions);
     return $this->buildDiffInfoDictionary($diff);
 }
 private function buildChangesetParsers($type, $data, $file)
 {
     $parser = new ArcanistDiffParser();
     $changes = $parser->parseDiff($data);
     $diff = DifferentialDiff::newFromRawChanges(PhabricatorUser::getOmnipotentUser(), $changes);
     $changesets = $diff->getChangesets();
     $engine = new PhabricatorMarkupEngine();
     $engine->setViewer(new PhabricatorUser());
     $parsers = array();
     foreach ($changesets as $changeset) {
         $cparser = new DifferentialChangesetParser();
         $cparser->setUser(new PhabricatorUser());
         $cparser->setDisableCache(true);
         $cparser->setChangeset($changeset);
         $cparser->setMarkupEngine($engine);
         if ($type == 'one') {
             $cparser->setRenderer(new DifferentialChangesetOneUpTestRenderer());
         } else {
             if ($type == 'two') {
                 $cparser->setRenderer(new DifferentialChangesetTwoUpTestRenderer());
             } else {
                 throw new Exception(pht('Unknown renderer type "%s"!', $type));
             }
         }
         $parsers[] = $cparser;
     }
     return $parsers;
 }
 private function createHunksFromFile($name)
 {
     $data = Filesystem::readFile(dirname(__FILE__) . '/data/' . $name);
     $parser = new ArcanistDiffParser();
     $changes = $parser->parseDiff($data);
     if (count($changes) !== 1) {
         throw new Exception("Expected 1 changeset for '{$name}'!");
     }
     $diff = DifferentialDiff::newFromRawChanges($changes);
     return head($diff->getChangesets())->getHunks();
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $raw_diff = $request->getValue('diff');
     $parser = new ArcanistDiffParser();
     $changes = $parser->parseDiff($raw_diff);
     $diff = DifferentialDiff::newFromRawChanges($changes);
     $diff->setLintStatus(DifferentialLintStatus::LINT_SKIP);
     $diff->setUnitStatus(DifferentialLintStatus::LINT_SKIP);
     $diff->setAuthorPHID($request->getUser()->getPHID());
     $diff->setCreationMethod('web');
     $diff->save();
     return $this->buildDiffInfoDictionary($diff);
 }
 public function run()
 {
     $working_copy = $this->getWorkingCopy();
     if (!$working_copy->getProjectID()) {
         throw new ArcanistUsageException("You have installed a git pre-receive hook in a remote without an " . ".arcconfig.");
     }
     // Git repositories have special rules in pre-receive hooks. We need to
     // construct the API against the .git directory instead of the project
     // root or commands don't work properly.
     $repository_api = ArcanistGitAPI::newHookAPI($_SERVER['PWD']);
     $root = $working_copy->getProjectRoot();
     $parser = new ArcanistDiffParser();
     $mark_revisions = array();
     $stdin = file_get_contents('php://stdin');
     $commits = array_filter(explode("\n", $stdin));
     foreach ($commits as $commit) {
         list($old_ref, $new_ref, $refname) = explode(' ', $commit);
         list($log) = execx('(cd %s && git log -n1 %s)', $repository_api->getPath(), $new_ref);
         $message_log = reset($parser->parseDiff($log));
         $message = ArcanistDifferentialCommitMessage::newFromRawCorpus($message_log->getMetadata('message'));
         $revision_id = $message->getRevisionID();
         if ($revision_id) {
             $mark_revisions[] = $revision_id;
         }
         // TODO: Do commit message junk.
         $info = $repository_api->getPreReceiveHookStatus($old_ref, $new_ref);
         $paths = ipull($info, 'mask');
         $frefs = ipull($info, 'ref');
         $data = array();
         foreach ($paths as $path => $mask) {
             list($stdout) = execx('(cd %s && git cat-file blob %s)', $repository_api->getPath(), $frefs[$path]);
             $data[$path] = $stdout;
         }
         // TODO: Do commit content junk.
         $commit_name = $new_ref;
         if ($revision_id) {
             $commit_name = 'D' . $revision_id . ' (' . $commit_name . ')';
         }
         echo "[arc pre-receive] {$commit_name} OK...\n";
     }
     $conduit = $this->getConduit();
     $futures = array();
     foreach ($mark_revisions as $revision_id) {
         $futures[] = $conduit->callMethod('differential.close', array('revisionID' => $revision_id));
     }
     Futures($futures)->resolveAll();
     return 0;
 }
 protected function executeQuery()
 {
     $drequest = $this->getRequest();
     $repository = $drequest->getRepository();
     if (!$drequest->getRawCommit()) {
         $effective_commit = $this->getEffectiveCommit();
         if (!$effective_commit) {
             return null;
         }
         // TODO: This side effect is kind of skethcy.
         $drequest->setCommit($effective_commit);
     } else {
         $effective_commit = $drequest->getCommit();
     }
     $options = array('-M', '-C', '--no-ext-diff', '--no-color', '--src-prefix=a/', '--dst-prefix=b/', '-U65535');
     $options = implode(' ', $options);
     try {
         list($raw_diff) = $repository->execxLocalCommand('diff %C %s^ %s -- %s', $options, $effective_commit, $effective_commit, $drequest->getPath());
     } catch (CommandException $ex) {
         // Check if this is the root commit by seeing if it has parents.
         list($parents) = $repository->execxLocalCommand('log --format=%s %s --', '%P', $effective_commit);
         if (!strlen(trim($parents))) {
             // No parents means we're looking at the root revision. Diff against
             // the empty tree hash instead, since there is no parent so "^" does
             // not work. See ArcanistGitAPI for more discussion.
             list($raw_diff) = $repository->execxLocalCommand('diff %C %s %s -- %s', $options, ArcanistGitAPI::GIT_MAGIC_ROOT_COMMIT, $effective_commit, $drequest->getPath());
         } else {
             throw $ex;
         }
     }
     $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->getBranchURIComponent($drequest->getBranch()) . $drequest->getPath() . ';' . $drequest->getCommit();
     return $changeset;
 }
 private function loadHunk($name)
 {
     $root = dirname(__FILE__) . '/hunk/';
     $data = Filesystem::readFile($root . $name);
     $parser = new ArcanistDiffParser();
     $changes = $parser->parseDiff($data);
     $viewer = PhabricatorUser::getOmnipotentUser();
     $diff = DifferentialDiff::newFromRawChanges($viewer, $changes);
     $changesets = $diff->getChangesets();
     if (count($changesets) !== 1) {
         throw new Exception(pht('Expected exactly one changeset from "%s".', $name));
     }
     $changeset = head($changesets);
     $hunks = $changeset->getHunks();
     if (count($hunks) !== 1) {
         throw new Exception(pht('Expected exactly one hunk from "%s".', $name));
     }
     $hunk = head($hunks);
     return $hunk;
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $viewer = $request->getUser();
     $raw_diff = $request->getValue('diff');
     $repository_phid = $request->getValue('repositoryPHID');
     if ($repository_phid) {
         $repository = id(new PhabricatorRepositoryQuery())->setViewer($viewer)->withPHIDs(array($repository_phid))->executeOne();
         if (!$repository) {
             throw new Exception(pht('No such repository "%s"!', $repository_phid));
         }
     }
     $parser = new ArcanistDiffParser();
     $changes = $parser->parseDiff($raw_diff);
     $diff = DifferentialDiff::newFromRawChanges($viewer, $changes);
     $diff_data_dict = array('creationMethod' => 'web', 'authorPHID' => $viewer->getPHID(), 'repositoryPHID' => $repository_phid, 'lintStatus' => DifferentialLintStatus::LINT_SKIP, 'unitStatus' => DifferentialUnitStatus::UNIT_SKIP);
     $xactions = array(id(new DifferentialTransaction())->setTransactionType(DifferentialDiffTransaction::TYPE_DIFF_CREATE)->setNewValue($diff_data_dict));
     if ($request->getValue('viewPolicy')) {
         $xactions[] = id(new DifferentialTransaction())->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)->setNewValue($request->getValue('viewPolicy'));
     }
     id(new DifferentialDiffEditor())->setActor($viewer)->setContentSourceFromConduitRequest($request)->setContinueOnNoEffect(true)->setLookupRepository(false)->applyTransactions($diff, $xactions);
     return $this->buildDiffInfoDictionary($diff);
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     if ($request->isFormPost()) {
         $parser = new ArcanistDiffParser();
         $diff = $request->getStr('diff');
         $changes = $parser->parseDiff($diff);
         $diff = DifferentialDiff::newFromRawChanges($changes);
         $diff->setLintStatus(DifferentialLintStatus::LINT_SKIP);
         $diff->setUnitStatus(DifferentialLintStatus::LINT_SKIP);
         $diff->setAuthorPHID($request->getUser()->getPHID());
         $diff->setCreationMethod('web');
         $diff->save();
         return id(new AphrontRedirectResponse())->setURI('/differential/diff/' . $diff->getID() . '/');
     }
     $form = new AphrontFormView();
     $form->setAction('/differential/diff/create/')->setUser($request->getUser())->appendChild('<p class="aphront-form-instructions">The best way to create a ' . 'Differential diff is by using <strong>Arcanist</strong>, but you ' . 'can also just paste a diff (e.g., from <tt>svn diff</tt> or ' . '<tt>git diff</tt>) into this box if you really want.</p>')->appendChild(id(new AphrontFormTextAreaControl())->setLabel('Raw Diff')->setName('diff')->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL))->appendChild(id(new AphrontFormSubmitControl())->setValue("Create Diff »"));
     $panel = new AphrontPanelView();
     $panel->setHeader('Create New Diff');
     $panel->appendChild($form);
     $panel->setWidth(AphrontPanelView::WIDTH_FORM);
     return $this->buildStandardPageResponse($panel, array('title' => 'Create Diff', 'tab' => 'create'));
 }
 public function testGitPathSplitting()
 {
     static $tests = array('a/old.c b/new.c' => array('old.c', 'new.c'), "a/old.c b/new.c\n" => array('old.c', 'new.c'), "a/old.c b/new.c\r\n" => array('old.c', 'new.c'), 'old.c new.c' => array('old.c', 'new.c'), '1/old.c 2/new.c' => array('old.c', 'new.c'), '"a/\\"quotes1\\"" "b/\\"quotes2\\""' => array('"quotes1"', '"quotes2"'), '"a/\\"quotes and spaces1\\"" "b/\\"quotes and spaces2\\""' => array('"quotes and spaces1"', '"quotes and spaces2"'), '"a/\\342\\230\\2031" "b/\\342\\230\\2032"' => array("☃1", "☃2"), 'a/Core Data/old.c b/Core Data/new.c' => array('Core Data/old.c', 'Core Data/new.c'), 'some file with spaces.c some file with spaces.c' => array('some file with spaces.c', 'some file with spaces.c'));
     foreach ($tests as $input => $expect) {
         $result = ArcanistDiffParser::splitGitDiffPaths($input);
         $this->assertEqual($expect, $result, pht('Split: %s', $input));
     }
     static $ambiguous = array('old file with spaces.c new file with spaces.c');
     foreach ($ambiguous as $input) {
         $caught = null;
         try {
             ArcanistDiffParser::splitGitDiffPaths($input);
         } catch (Exception $ex) {
             $caught = $ex;
         }
         $this->assertTrue($caught instanceof Exception, pht('Ambiguous: %s', $input));
     }
 }
 private function getDefaultParser()
 {
     $drequest = $this->getDiffusionRequest();
     $repository = $drequest->getRepository();
     $parser = new ArcanistDiffParser();
     $try_encoding = $repository->getDetail('encoding');
     if ($try_encoding) {
         $parser->setTryEncoding($try_encoding);
     }
     $parser->setDetectBinaryFiles(true);
     return $parser;
 }
 protected function newDiffParser()
 {
     $parser = new ArcanistDiffParser();
     if ($this->repositoryAPI) {
         $parser->setRepositoryAPI($this->getRepositoryAPI());
     }
     $parser->setWriteDiffOnFailure(true);
     return $parser;
 }
 protected function executeQuery()
 {
     $drequest = $this->getRequest();
     if (!$drequest->getRawCommit()) {
         $effective_commit = $this->getEffectiveCommit();
         if (!$effective_commit) {
             return null;
         }
         // TODO: Sketchy side effect.
         $drequest->setCommit($effective_commit);
     }
     $path_change_query = DiffusionPathChangeQuery::newFromDiffusionRequest($drequest);
     $path_changes = $path_change_query->loadChanges();
     $path = null;
     foreach ($path_changes as $change) {
         if ($change->getPath() == $drequest->getPath()) {
             $path = $change;
         }
     }
     if (!$path) {
         return null;
     }
     $change_type = $path->getChangeType();
     switch ($change_type) {
         case DifferentialChangeType::TYPE_MULTICOPY:
         case DifferentialChangeType::TYPE_DELETE:
             if ($path->getTargetPath()) {
                 $old = array($path->getTargetPath(), $path->getTargetCommitIdentifier());
             } else {
                 $old = array($path->getPath(), $path->getCommitIdentifier() - 1);
             }
             $old_name = $path->getPath();
             $new_name = '';
             $new = null;
             break;
         case DifferentialChangeType::TYPE_ADD:
             $old = null;
             $new = array($path->getPath(), $path->getCommitIdentifier());
             $old_name = '';
             $new_name = $path->getPath();
             break;
         case DifferentialChangeType::TYPE_MOVE_HERE:
         case DifferentialChangeType::TYPE_COPY_HERE:
             $old = array($path->getTargetPath(), $path->getTargetCommitIdentifier());
             $new = array($path->getPath(), $path->getCommitIdentifier());
             $old_name = $path->getTargetPath();
             $new_name = $path->getPath();
             break;
         case DifferentialChangeType::TYPE_MOVE_AWAY:
             $old = array($path->getPath(), $path->getCommitIdentifier() - 1);
             $old_name = $path->getPath();
             $new_name = null;
             $new = null;
             break;
         default:
             $old = array($path->getPath(), $path->getCommitIdentifier() - 1);
             $new = array($path->getPath(), $path->getCommitIdentifier());
             $old_name = $path->getPath();
             $new_name = $path->getPath();
             break;
     }
     $futures = array('old' => $this->buildContentFuture($old), 'new' => $this->buildContentFuture($new));
     $futures = array_filter($futures);
     foreach (Futures($futures) as $key => $future) {
         list($stdout) = $future->resolvex();
         $futures[$key] = $stdout;
     }
     $old_data = idx($futures, 'old', '');
     $new_data = idx($futures, 'new', '');
     $engine = new PhabricatorDifferenceEngine();
     $engine->setOldName($old_name);
     $engine->setNewName($new_name);
     $raw_diff = $engine->generateRawDiffFromFileContent($old_data, $new_data);
     $parser = new ArcanistDiffParser();
     $parser->setDetectBinaryFiles(true);
     $arcanist_changes = DiffusionPathChange::convertToArcanistChanges($path_changes);
     $parser->setChanges($arcanist_changes);
     $parser->forcePath($path->getPath());
     $changes = $parser->parseDiff($raw_diff);
     $change = $changes[$path->getPath()];
     $diff = DifferentialDiff::newFromRawChanges(array($change));
     $changesets = $diff->getChangesets();
     $changeset = reset($changesets);
     $this->renderingReference = $drequest->getPath() . ';' . $drequest->getCommit();
     return $changeset;
 }
 public function run()
 {
     $source = $this->getSource();
     switch ($source) {
         case self::SOURCE_LOCAL:
             $repository_api = $this->getRepositoryAPI();
             $parser = new ArcanistDiffParser();
             $parser->setRepositoryAPI($repository_api);
             if ($repository_api instanceof ArcanistGitAPI) {
                 $this->parseBaseCommitArgument($this->getArgument('paths'));
                 $diff = $repository_api->getFullGitDiff($repository_api->getBaseCommit(), $repository_api->getHeadCommit());
                 $changes = $parser->parseDiff($diff);
                 $authors = $this->getConduit()->callMethodSynchronous('user.query', array('phids' => array($this->getUserPHID())));
                 $author_dict = reset($authors);
                 list($email) = $repository_api->execxLocal('config user.email');
                 $author = sprintf('%s <%s>', $author_dict['realName'], $email);
             } else {
                 if ($repository_api instanceof ArcanistMercurialAPI) {
                     $this->parseBaseCommitArgument($this->getArgument('paths'));
                     $diff = $repository_api->getFullMercurialDiff();
                     $changes = $parser->parseDiff($diff);
                     $authors = $this->getConduit()->callMethodSynchronous('user.query', array('phids' => array($this->getUserPHID())));
                     list($author) = $repository_api->execxLocal('showconfig ui.username');
                 } else {
                     // TODO: paths support
                     $paths = $repository_api->getWorkingCopyStatus();
                     $changes = $parser->parseSubversionDiff($repository_api, $paths);
                     $author = $this->getUserName();
                 }
             }
             $bundle = ArcanistBundle::newFromChanges($changes);
             $bundle->setProjectID($this->getWorkingCopy()->getProjectID());
             $bundle->setBaseRevision($repository_api->getSourceControlBaseRevision());
             // NOTE: we can't get a revision ID for SOURCE_LOCAL
             $parser = new PhutilEmailAddress($author);
             $bundle->setAuthorName($parser->getDisplayName());
             $bundle->setAuthorEmail($parser->getAddress());
             break;
         case self::SOURCE_REVISION:
             $bundle = $this->loadRevisionBundleFromConduit($this->getConduit(), $this->getSourceID());
             break;
         case self::SOURCE_DIFF:
             $bundle = $this->loadDiffBundleFromConduit($this->getConduit(), $this->getSourceID());
             break;
     }
     $try_encoding = nonempty($this->getArgument('encoding'), null);
     if (!$try_encoding) {
         try {
             $project_info = $this->getConduit()->callMethodSynchronous('arcanist.projectinfo', array('name' => $bundle->getProjectID()));
             $try_encoding = $project_info['encoding'];
         } catch (ConduitClientException $e) {
             $try_encoding = null;
         }
     }
     if ($try_encoding) {
         $bundle->setEncoding($try_encoding);
     }
     $format = $this->getFormat();
     switch ($format) {
         case self::FORMAT_GIT:
             echo $bundle->toGitPatch();
             break;
         case self::FORMAT_UNIFIED:
             echo $bundle->toUnifiedDiff();
             break;
         case self::FORMAT_BUNDLE:
             $path = $this->getArgument('arcbundle');
             echo "Writing bundle to '{$path}'...\n";
             $bundle->writeToDisk($path);
             echo "done.\n";
             break;
     }
     return 0;
 }
Esempio n. 23
0
 protected function newDiffParser()
 {
     $parser = new ArcanistDiffParser();
     $parser->setWriteDiffOnFailure(true);
     return $parser;
 }
Esempio n. 24
0
 public function getAllLocalChanges()
 {
     $diff = $this->getFullMercurialDiff();
     if (!strlen(trim($diff))) {
         return array();
     }
     $parser = new ArcanistDiffParser();
     return $parser->parseDiff($diff);
 }
Esempio n. 25
0
 public function run()
 {
     $source = $this->getSource();
     switch ($source) {
         case self::SOURCE_LOCAL:
             $repository_api = $this->getRepositoryAPI();
             $parser = new ArcanistDiffParser();
             if ($repository_api instanceof ArcanistGitAPI) {
                 $repository_api->parseRelativeLocalCommit($this->getArgument('paths'));
                 $diff = $repository_api->getFullGitDiff();
                 $changes = $parser->parseDiff($diff);
             } else {
                 // TODO: paths support
                 $paths = $repository_api->getWorkingCopyStatus();
                 $changes = $parser->parseSubversionDiff($repository_api, $paths);
             }
             $bundle = ArcanistBundle::newFromChanges($changes);
             $bundle->setProjectID($this->getWorkingCopy()->getProjectID());
             $bundle->setBaseRevision($repository_api->getSourceControlBaseRevision());
             // note we can't get a revision ID for SOURCE_LOCAL
             break;
         case self::SOURCE_REVISION:
             $bundle = $this->loadRevisionBundleFromConduit($this->getConduit(), $this->getSourceID());
             break;
         case self::SOURCE_DIFF:
             $bundle = $this->loadDiffBundleFromConduit($this->getConduit(), $this->getSourceID());
             break;
     }
     $try_encoding = nonempty($this->getArgument('encoding'), null);
     if (!$try_encoding) {
         try {
             $try_encoding = $this->getRepositoryEncoding();
         } catch (ConduitClientException $e) {
             $try_encoding = null;
         }
     }
     if ($try_encoding) {
         $bundle->setEncoding($try_encoding);
     }
     $format = $this->getFormat();
     switch ($format) {
         case self::FORMAT_GIT:
             echo $bundle->toGitPatch();
             break;
         case self::FORMAT_UNIFIED:
             echo $bundle->toUnifiedDiff();
             break;
         case self::FORMAT_BUNDLE:
             $path = $this->getArgument('arcbundle');
             echo "Writing bundle to '{$path}'...\n";
             $bundle->writeToDisk($path);
             echo "done.\n";
             break;
     }
     return 0;
 }
    private function parseDiff($diff_file)
    {
        $contents = Filesystem::readFile($diff_file);
        $file = basename($diff_file);
        $parser = new ArcanistDiffParser();
        $changes = $parser->parseDiff($contents);
        switch ($file) {
            case 'colorized.hggitdiff':
                $this->assertEqual(1, count($changes));
                break;
            case 'basic-missing-both-newlines-plus.udiff':
            case 'basic-missing-both-newlines.udiff':
            case 'basic-missing-new-newline-plus.udiff':
            case 'basic-missing-new-newline.udiff':
            case 'basic-missing-old-newline-plus.udiff':
            case 'basic-missing-old-newline.udiff':
                $expect_old = strpos($file, '-old-') || strpos($file, '-both-');
                $expect_new = strpos($file, '-new-') || strpos($file, '-both-');
                $expect_two = strpos($file, '-plus');
                $this->assertEqual(count($changes), $expect_two ? 2 : 1);
                $change = reset($changes);
                $this->assertEqual(true, $change !== null);
                $hunks = $change->getHunks();
                $this->assertEqual(1, count($hunks));
                $hunk = reset($hunks);
                $this->assertEqual((bool) $expect_old, $hunk->getIsMissingOldNewline());
                $this->assertEqual((bool) $expect_new, $hunk->getIsMissingNewNewline());
                break;
            case 'basic-binary.udiff':
                $this->assertEqual(1, count($changes));
                $change = reset($changes);
                $this->assertEqual(ArcanistDiffChangeType::FILE_BINARY, $change->getFileType());
                break;
            case 'basic-multi-hunk.udiff':
                $this->assertEqual(1, count($changes));
                $change = reset($changes);
                $hunks = $change->getHunks();
                $this->assertEqual(4, count($hunks));
                $this->assertEqual('right', $change->getCurrentPath());
                $this->assertEqual('left', $change->getOldPath());
                break;
            case 'basic-multi-hunk-content.svndiff':
                $this->assertEqual(1, count($changes));
                $change = reset($changes);
                $hunks = $change->getHunks();
                $this->assertEqual(2, count($hunks));
                $there_is_a_literal_trailing_space_here = ' ';
                $corpus_0 = <<<EOCORPUS
 asdfasdf
+% quack
 %
-%
 %%
 %%
 %%%
EOCORPUS;
                $corpus_1 = <<<EOCORPUS
 %%%%%
 %%%%%
{$there_is_a_literal_trailing_space_here}
-!
+! quack
EOCORPUS;
                $this->assertEqual($corpus_0, $hunks[0]->getCorpus());
                $this->assertEqual($corpus_1, $hunks[1]->getCorpus());
                break;
            case 'svn-ignore-whitespace-only.svndiff':
                $this->assertEqual(2, count($changes));
                $hunks = reset($changes)->getHunks();
                $this->assertEqual(0, count($hunks));
                break;
            case 'svn-property-add.svndiff':
                $this->assertEqual(1, count($changes));
                $change = reset($changes);
                $hunks = reset($changes)->getHunks();
                $this->assertEqual(1, count($hunks));
                $this->assertEqual(array('duck' => 'quack'), $change->getNewProperties());
                break;
            case 'svn-property-modify.svndiff':
                $this->assertEqual(2, count($changes));
                $change = array_shift($changes);
                $this->assertEqual(0, count($change->getHunks()));
                $this->assertEqual(array('svn:ignore' => '*.phpz'), $change->getOldProperties());
                $this->assertEqual(array('svn:ignore' => '*.php'), $change->getNewProperties());
                $change = array_shift($changes);
                $this->assertEqual(0, count($change->getHunks()));
                $this->assertEqual(array('svn:special' => '*'), $change->getOldProperties());
                $this->assertEqual(array('svn:special' => 'moo'), $change->getNewProperties());
                break;
            case 'svn-property-delete.svndiff':
                $this->assertEqual(1, count($changes));
                $change = reset($changes);
                $this->assertEqual(0, count($change->getHunks()));
                $this->assertEqual($change->getOldProperties(), array('svn:special' => '*'));
                $this->assertEqual(array(), $change->getNewProperties());
                break;
            case 'svn-property-merged.svndiff':
                $this->assertEqual(1, count($changes));
                $change = reset($changes);
                $this->assertEqual(count($change->getHunks()), 0);
                $this->assertEqual($change->getOldProperties(), array());
                $this->assertEqual($change->getNewProperties(), array());
                break;
            case 'svn-property-merge.svndiff':
                $this->assertEqual(1, count($changes));
                $change = reset($changes);
                $this->assertEqual(count($change->getHunks()), 0);
                $this->assertEqual($change->getOldProperties(), array());
                $this->assertEqual($change->getNewProperties(), array('svn:mergeinfo' => <<<EOTEXT
Merged /tfb/branches/internmove/www/html/js/help/UIFaq.js:r83462-126155
Merged /tfb/branches/ads-create-v3/www/html/js/help/UIFaq.js:r140558-142418
EOTEXT
));
                break;
            case 'svn-binary-add.svndiff':
                $this->assertEqual(1, count($changes));
                $change = reset($changes);
                $this->assertEqual(ArcanistDiffChangeType::FILE_BINARY, $change->getFileType());
                $this->assertEqual(0, count($change->getHunks()));
                $this->assertEqual(array('svn:mime-type' => 'application/octet-stream'), $change->getNewProperties());
                break;
            case 'svn-binary-diff.svndiff':
                $this->assertEqual(1, count($changes));
                $change = reset($changes);
                $this->assertEqual(ArcanistDiffChangeType::FILE_BINARY, $change->getFileType());
                $this->assertEqual(count($change->getHunks()), 0);
                break;
            case 'git-delete-file.gitdiff':
                $this->assertEqual(1, count($changes));
                $change = reset($changes);
                $this->assertEqual(ArcanistDiffChangeType::TYPE_DELETE, $change->getType());
                $this->assertEqual('scripts/intern/test/testfile2', $change->getCurrentPath());
                $this->assertEqual(1, count($change->getHunks()));
                break;
            case 'git-binary-change.gitdiff':
                $this->assertEqual(1, count($changes));
                $change = reset($changes);
                $this->assertEqual(ArcanistDiffChangeType::FILE_BINARY, $change->getFileType());
                $this->assertEqual(0, count($change->getHunks()));
                break;
            case 'git-filemode-change.gitdiff':
                $this->assertEqual(1, count($changes));
                $change = reset($changes);
                $this->assertEqual(1, count($change->getHunks()));
                $this->assertEqual(array('unix:filemode' => '100644'), $change->getOldProperties());
                $this->assertEqual(array('unix:filemode' => '100755'), $change->getNewProperties());
                break;
            case 'git-filemode-change-only.gitdiff':
                $this->assertEqual(count($changes), 2);
                $change = reset($changes);
                $this->assertEqual(count($change->getHunks()), 0);
                $this->assertEqual(array('unix:filemode' => '100644'), $change->getOldProperties());
                $this->assertEqual(array('unix:filemode' => '100755'), $change->getNewProperties());
                break;
            case 'svn-empty-file.svndiff':
                $this->assertEqual(2, count($changes));
                $change = array_shift($changes);
                $this->assertEqual(0, count($change->getHunks()));
                break;
            case 'git-ignore-whitespace-only.gitdiff':
                $this->assertEqual(count($changes), 2);
                $change = array_shift($changes);
                $this->assertEqual(count($change->getHunks()), 0);
                $this->assertEqual($change->getOldPath(), 'scripts/intern/test/testfile2');
                $this->assertEqual($change->getCurrentPath(), 'scripts/intern/test/testfile2');
                $change = array_shift($changes);
                $this->assertEqual(count($change->getHunks()), 1);
                $this->assertEqual($change->getOldPath(), 'scripts/intern/test/testfile3');
                $this->assertEqual($change->getCurrentPath(), 'scripts/intern/test/testfile3');
                break;
            case 'git-move.gitdiff':
            case 'git-move-edit.gitdiff':
            case 'git-move-plus.gitdiff':
                $extra_changeset = (bool) strpos($file, '-plus');
                $has_hunk = (bool) strpos($file, '-edit');
                $this->assertEqual($extra_changeset ? 3 : 2, count($changes));
                $change = array_shift($changes);
                $this->assertEqual($has_hunk ? 1 : 0, count($change->getHunks()));
                $this->assertEqual($change->getType(), ArcanistDiffChangeType::TYPE_MOVE_HERE);
                $target = $change;
                $change = array_shift($changes);
                $this->assertEqual(0, count($change->getHunks()));
                $this->assertEqual(ArcanistDiffChangeType::TYPE_MOVE_AWAY, $change->getType());
                $this->assertEqual($change->getCurrentPath(), $target->getOldPath());
                $this->assertEqual(true, in_array($target->getCurrentPath(), $change->getAwayPaths()));
                break;
            case 'git-merge-header.gitdiff':
                $this->assertEqual(1, count($changes));
                $change = reset($changes);
                $this->assertEqual(ArcanistDiffChangeType::TYPE_MESSAGE, $change->getType());
                $this->assertEqual('501f6d519703458471dbea6284ec5f49d1408598', $change->getCommitHash());
                break;
            case 'git-new-file.gitdiff':
                $this->assertEqual(1, count($changes));
                $change = reset($changes);
                $this->assertEqual(ArcanistDiffChangeType::TYPE_ADD, $change->getType());
                break;
            case 'git-copy.gitdiff':
                $this->assertEqual(2, count($changes));
                $change = array_shift($changes);
                $this->assertEqual(0, count($change->getHunks()));
                $this->assertEqual(ArcanistDiffChangeType::TYPE_COPY_HERE, $change->getType());
                $this->assertEqual('flib/intern/widgets/ui/UIWidgetRSSBox.php', $change->getCurrentPath());
                $change = array_shift($changes);
                $this->assertEqual(0, count($change->getHunks()));
                $this->assertEqual(ArcanistDiffChangeType::TYPE_COPY_AWAY, $change->getType());
                $this->assertEqual('lib/display/intern/ui/widget/UIWidgetRSSBox.php', $change->getCurrentPath());
                break;
            case 'git-copy-plus.gitdiff':
                $this->assertEqual(2, count($changes));
                $change = array_shift($changes);
                $this->assertEqual(3, count($change->getHunks()));
                $this->assertEqual(ArcanistDiffChangeType::TYPE_COPY_HERE, $change->getType());
                $this->assertEqual('flib/intern/widgets/ui/UIWidgetGraphConnect.php', $change->getCurrentPath());
                $change = array_shift($changes);
                $this->assertEqual(0, count($change->getHunks()));
                $this->assertEqual(ArcanistDiffChangeType::TYPE_COPY_AWAY, $change->getType());
                $this->assertEqual('lib/display/intern/ui/widget/UIWidgetLunchtime.php', $change->getCurrentPath());
                break;
            case 'svn-property-multiline.svndiff':
                $this->assertEqual(1, count($changes));
                $change = array_shift($changes);
                $this->assertEqual(0, count($change->getHunks()));
                $this->assertEqual(array('svn:ignore' => 'tags'), $change->getOldProperties());
                $this->assertEqual(array('svn:ignore' => "tags\nasdf\nlol\nwhat"), $change->getNewProperties());
                break;
            case 'git-empty-files.gitdiff':
                $this->assertEqual(2, count($changes));
                while ($change = array_shift($changes)) {
                    $this->assertEqual(0, count($change->getHunks()));
                }
                break;
            case 'git-mnemonicprefix.gitdiff':
                // Check parsing of diffs created with `diff.mnemonicprefix`
                // configuration option set to `true`.
                $this->assertEqual(1, count($changes));
                $this->assertEqual(1, count(reset($changes)->getHunks()));
                break;
            case 'git-commit.gitdiff':
                $this->assertEqual(1, count($changes));
                $change = reset($changes);
                $this->assertEqual(ArcanistDiffChangeType::TYPE_MESSAGE, $change->getType());
                $this->assertEqual('76e2f1339c298c748aa0b52030799ed202a6537b', $change->getCommitHash());
                $this->assertEqual(<<<EOTEXT

Deprecating UIActionButton (Part 1)

Summary: Replaces calls to UIActionButton with <ui:button>.  I tested most
         of these calls, but there were some that I didn't know how to
         reach, so if you are one of the owners of this code, please test
         your feature in my sandbox: www.ngao.devrs013.facebook.com

         @brosenthal, I removed some logic that was setting a disabled state
         on a UIActionButton, which is actually a no-op.

Reviewed By: brosenthal

Other Commenters: sparker, egiovanola

Test Plan: www.ngao.devrs013.facebook.com

           Explicitly tested:
           * ads creation flow (add keyword)
           * ads manager (conversion tracking)
           * help center (create a discussion)
           * new user wizard (next step button)

Revert: OK

DiffCamp Revision: 94064

git-svn-id: svn+ssh://tubbs/svnroot/tfb/trunk/www@223593 2c7ba8d8
EOTEXT
, $change->getMetadata('message'));
                break;
            case 'git-binary.gitdiff':
                $this->assertEqual(1, count($changes));
                $change = reset($changes);
                $this->assertEqual(ArcanistDiffChangeType::TYPE_CHANGE, $change->getType());
                $this->assertEqual(ArcanistDiffChangeType::FILE_BINARY, $change->getFileType());
                break;
            case 'git-odd-filename.gitdiff':
                $this->assertEqual(2, count($changes));
                $change = reset($changes);
                $this->assertEqual('old/' . "∆" . '.jpg', $change->getOldPath());
                $this->assertEqual('new/' . "∆" . '.jpg', $change->getCurrentPath());
                break;
            case 'hg-binary-change.hgdiff':
            case 'hg-solo-binary-change.hgdiff':
                $this->assertEqual(1, count($changes));
                $change = reset($changes);
                $this->assertEqual(ArcanistDiffChangeType::TYPE_ADD, $change->getType());
                $this->assertEqual(ArcanistDiffChangeType::FILE_BINARY, $change->getFileType());
                break;
            case 'hg-binary-delete.hgdiff':
                $this->assertEqual(1, count($changes));
                $change = reset($changes);
                $this->assertEqual(ArcanistDiffChangeType::TYPE_DELETE, $change->getType());
                $this->assertEqual(ArcanistDiffChangeType::FILE_BINARY, $change->getFileType());
                break;
            case 'git-replace-symlink.gitdiff':
                $this->assertEqual(1, count($changes));
                $change = array_shift($changes);
                $this->assertEqual(ArcanistDiffChangeType::TYPE_CHANGE, $change->getType());
                break;
            case 'svn-1.7-property-added.svndiff':
                $this->assertEqual(1, count($changes));
                $change = head($changes);
                $new_properties = $change->getNewProperties();
                $this->assertEqual(2, count($new_properties));
                $this->assertEqual('*', idx($new_properties, 'svn:executable'));
                $this->assertEqual('text/html', idx($new_properties, 'svn:mime-type'));
                break;
            default:
                throw new Exception("No test block for diff file {$diff_file}.");
                break;
        }
    }
Esempio n. 27
0
 public function loadWorkingCopyDifferentialRevisions(ConduitClient $conduit, array $query)
 {
     $messages = $this->getGitCommitLog();
     if (!strlen($messages)) {
         return array();
     }
     $parser = new ArcanistDiffParser();
     $messages = $parser->parseDiff($messages);
     // First, try to find revisions by explicit revision IDs in commit messages.
     $reason_map = array();
     $revision_ids = array();
     foreach ($messages as $message) {
         $object = ArcanistDifferentialCommitMessage::newFromRawCorpus($message->getMetadata('message'));
         if ($object->getRevisionID()) {
             $revision_ids[] = $object->getRevisionID();
             $reason_map[$object->getRevisionID()] = $message->getCommitHash();
         }
     }
     if ($revision_ids) {
         $results = $conduit->callMethodSynchronous('differential.query', $query + array('ids' => $revision_ids));
         foreach ($results as $key => $result) {
             $hash = substr($reason_map[$result['id']], 0, 16);
             $results[$key]['why'] = "Commit message for '{$hash}' has explicit 'Differential Revision'.";
         }
         return $results;
     }
     // If we didn't succeed, try to find revisions by hash.
     $hashes = array();
     foreach ($this->getLocalCommitInformation() as $commit) {
         $hashes[] = array('gtcm', $commit['commit']);
         $hashes[] = array('gttr', $commit['tree']);
     }
     $results = $conduit->callMethodSynchronous('differential.query', $query + array('commitHashes' => $hashes));
     foreach ($results as $key => $result) {
         $results[$key]['why'] = 'A git commit or tree hash in the commit range is already attached ' . 'to the Differential revision.';
     }
     return $results;
 }
Esempio n. 28
0
 public static function newFromDiff($data)
 {
     $obj = new ArcanistBundle();
     $parser = new ArcanistDiffParser();
     $obj->changes = $parser->parseDiff($data);
     return $obj;
 }
 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 loadCommitDiff()
 {
     $drequest = DiffusionRequest::newFromDictionary(array('user' => PhabricatorUser::getOmnipotentUser(), 'repository' => $this->repository, 'commit' => $this->commit->getCommitIdentifier()));
     $byte_limit = self::getEnormousByteLimit();
     $raw = DiffusionQuery::callConduitWithDiffusionRequest(PhabricatorUser::getOmnipotentUser(), $drequest, 'diffusion.rawdiffquery', array('commit' => $this->commit->getCommitIdentifier(), 'timeout' => self::getEnormousTimeLimit(), 'byteLimit' => $byte_limit, 'linesOfContext' => 0));
     if (strlen($raw) >= $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));
     }
     $parser = new ArcanistDiffParser();
     $changes = $parser->parseDiff($raw);
     $diff = DifferentialDiff::newEphemeralFromRawChanges($changes);
     return $diff;
 }