コード例 #1
0
 public function newDiffFromCommit(PhabricatorRepositoryCommit $commit)
 {
     $viewer = $this->getViewer();
     $repository = $commit->getRepository();
     $identifier = $commit->getCommitIdentifier();
     $monogram = $commit->getMonogram();
     $drequest = DiffusionRequest::newFromDictionary(array('user' => $viewer, 'repository' => $repository));
     $raw_diff = DiffusionQuery::callConduitWithDiffusionRequest($viewer, $drequest, 'diffusion.rawdiffquery', array('commit' => $identifier));
     // TODO: Support adds, deletes and moves under SVN.
     if (strlen($raw_diff)) {
         $changes = id(new ArcanistDiffParser())->parseDiff($raw_diff);
     } else {
         // This is an empty diff, maybe made with `git commit --allow-empty`.
         // NOTE: These diffs have the same tree hash as their ancestors, so
         // they may attach to revisions in an unexpected way. Just let this
         // happen for now, although it might make sense to special case it
         // eventually.
         $changes = array();
     }
     $diff = DifferentialDiff::newFromRawChanges($viewer, $changes)->setRepositoryPHID($repository->getPHID())->setCreationMethod('commit')->setSourceControlSystem($repository->getVersionControlSystem())->setLintStatus(DifferentialLintStatus::LINT_AUTO_SKIP)->setUnitStatus(DifferentialUnitStatus::UNIT_AUTO_SKIP)->setDateCreated($commit->getEpoch())->setDescription($monogram);
     $author_phid = $this->getAuthorPHID();
     if ($author_phid !== null) {
         $diff->setAuthorPHID($author_phid);
     }
     $parents = DiffusionQuery::callConduitWithDiffusionRequest($viewer, $drequest, 'diffusion.commitparentsquery', array('commit' => $identifier));
     if ($parents) {
         $diff->setSourceControlBaseRevision(head($parents));
     }
     // TODO: Attach binary files.
     return $diff->save();
 }
コード例 #2
0
 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);
 }
コード例 #3
0
 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;
 }
コード例 #4
0
 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;
 }
コード例 #5
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);
     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;
 }
コード例 #6
0
 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'));
 }
コード例 #7
0
    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);
    }
コード例 #8
0
 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;
 }
コード例 #9
0
 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;
 }
 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);
 }
コード例 #11
0
    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);
    }
コード例 #12
0
 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);
 }
コード例 #14
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;
 }
コード例 #15
0
 public function processRequest()
 {
     $drequest = $this->diffusionRequest;
     $viewer = $this->getRequest()->getUser();
     $content = array();
     $data = $this->callConduitWithDiffusionRequest('diffusion.diffquery', array('commit' => $drequest->getCommit(), 'path' => $drequest->getPath()));
     $drequest->updateSymbolicCommit($data['effectiveCommit']);
     $raw_changes = ArcanistDiffChange::newFromConduit($data['changes']);
     $diff = DifferentialDiff::newFromRawChanges($raw_changes);
     $changesets = $diff->getChangesets();
     $changeset = reset($changesets);
     if (!$changeset) {
         // TODO: Refine this.
         return new Aphront404Response();
     }
     $repository = $drequest->getRepository();
     $callsign = $repository->getCallsign();
     $changesets = array(0 => $changeset);
     $changeset_view = new DifferentialChangesetListView();
     $changeset_view->setTitle(pht('Change'));
     $changeset_view->setChangesets($changesets);
     $changeset_view->setVisibleChangesets($changesets);
     $changeset_view->setRenderingReferences(array(0 => $drequest->generateURI(array('action' => 'rendering-ref'))));
     $raw_params = array('action' => 'browse', 'params' => array('view' => 'raw'));
     $right_uri = $drequest->generateURI($raw_params);
     $raw_params['params']['before'] = $drequest->getStableCommit();
     $left_uri = $drequest->generateURI($raw_params);
     $changeset_view->setRawFileURIs($left_uri, $right_uri);
     $changeset_view->setRenderURI('/diffusion/' . $callsign . '/diff/');
     $changeset_view->setWhitespace(DifferentialChangesetParser::WHITESPACE_SHOW_ALL);
     $changeset_view->setUser($this->getRequest()->getUser());
     // TODO: This is pretty awkward, unify the CSS between Diffusion and
     // Differential better.
     require_celerity_resource('differential-core-view-css');
     $content[] = $changeset_view->render();
     $crumbs = $this->buildCrumbs(array('branch' => true, 'path' => true, 'view' => 'change'));
     $links = $this->renderPathLinks($drequest, $mode = 'browse');
     $header = id(new PHUIHeaderView())->setHeader($links)->setUser($viewer)->setPolicyObject($drequest->getRepository());
     $actions = $this->buildActionView($drequest);
     $properties = $this->buildPropertyView($drequest, $actions);
     $object_box = id(new PHUIObjectBoxView())->setHeader($header)->addPropertyList($properties);
     return $this->buildApplicationPage(array($crumbs, $object_box, $content), array('title' => pht('Change'), 'device' => false));
 }
コード例 #16
0
 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;
 }
コード例 #17
0
 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);
 }
コード例 #18
0
 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'));
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $change_data = $request->getValue('changes');
     $changes = array();
     foreach ($change_data as $dict) {
         $changes[] = ArcanistDiffChange::newFromDictionary($dict);
     }
     $diff = DifferentialDiff::newFromRawChanges($changes);
     $diff->setSourcePath($request->getValue('sourcePath'));
     $diff->setSourceMachine($request->getValue('sourceMachine'));
     $diff->setBranch($request->getValue('branch'));
     $diff->setCreationMethod($request->getValue('creationMethod'));
     $diff->setAuthorPHID($request->getValue('authorPHID'));
     $parent_id = $request->getValue('parentRevisionID');
     if ($parent_id) {
         $parent_rev = id(new DifferentialRevision())->load($parent_id);
         if ($parent_rev) {
             if ($parent_rev->getStatus() != DifferentialRevisionStatus::COMMITTED) {
                 $diff->setParentRevisionID($parent_id);
             }
         }
     }
     $system = $request->getValue('sourceControlSystem');
     $diff->setSourceControlSystem($system);
     $diff->setSourceControlPath($request->getValue('sourceControlPath'));
     $diff->setSourceControlBaseRevision($request->getValue('sourceControlBaseRevision'));
     $project_name = $request->getValue('arcanistProject');
     $project_phid = null;
     if ($project_name) {
         $arcanist_project = id(new PhabricatorRepositoryArcanistProject())->loadOneWhere('name = %s', $project_name);
         if (!$arcanist_project) {
             $arcanist_project = new PhabricatorRepositoryArcanistProject();
             $arcanist_project->setName($project_name);
             $arcanist_project->save();
         }
         $project_phid = $arcanist_project->getPHID();
     }
     $diff->setArcanistProjectPHID($project_phid);
     $diff->setRepositoryUUID($request->getValue('repositoryUUID'));
     switch ($request->getValue('lintStatus')) {
         case 'skip':
             $diff->setLintStatus(DifferentialLintStatus::LINT_SKIP);
             break;
         case 'okay':
             $diff->setLintStatus(DifferentialLintStatus::LINT_OKAY);
             break;
         case 'warn':
             $diff->setLintStatus(DifferentialLintStatus::LINT_WARN);
             break;
         case 'fail':
             $diff->setLintStatus(DifferentialLintStatus::LINT_FAIL);
             break;
         case 'none':
         default:
             $diff->setLintStatus(DifferentialLintStatus::LINT_NONE);
             break;
     }
     switch ($request->getValue('unitStatus')) {
         case 'skip':
             $diff->setUnitStatus(DifferentialUnitStatus::UNIT_SKIP);
             break;
         case 'okay':
             $diff->setUnitStatus(DifferentialUnitStatus::UNIT_OKAY);
             break;
         case 'warn':
             $diff->setUnitStatus(DifferentialUnitStatus::UNIT_WARN);
             break;
         case 'fail':
             $diff->setUnitStatus(DifferentialUnitStatus::UNIT_FAIL);
             break;
         case 'postponed':
             $diff->setUnitStatus(DifferentialUnitStatus::UNIT_POSTPONED);
             break;
         case 'none':
         default:
             $diff->setUnitStatus(DifferentialUnitStatus::UNIT_NONE);
             break;
     }
     $diff->save();
     $path = '/differential/diff/' . $diff->getID() . '/';
     $uri = PhabricatorEnv::getURI($path);
     return array('diffid' => $diff->getID(), 'uri' => $uri);
 }
コード例 #20
0
 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::newFromRawChanges($changes);
     return $diff;
 }
 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();
 }
コード例 #22
0
 public static final function convertToDifferentialChangesets(array $changes)
 {
     assert_instances_of($changes, 'DiffusionPathChange');
     $arcanist_changes = self::convertToArcanistChanges($changes);
     $diff = DifferentialDiff::newFromRawChanges($arcanist_changes);
     return $diff->getChangesets();
 }
コード例 #23
0
 public function processRequest()
 {
     $drequest = $this->getDiffusionRequest();
     $request = $this->getRequest();
     $user = $request->getUser();
     if (!$request->isAjax()) {
         // This request came out of the dropdown menu, either "View Standalone"
         // or "View Raw File".
         $view = $request->getStr('view');
         if ($view == 'r') {
             $uri = $drequest->generateURI(array('action' => 'browse', 'params' => array('view' => 'raw')));
         } else {
             $uri = $drequest->generateURI(array('action' => 'change'));
         }
         return id(new AphrontRedirectResponse())->setURI($uri);
     }
     $data = $this->callConduitWithDiffusionRequest('diffusion.diffquery', array('commit' => $drequest->getCommit(), 'path' => $drequest->getPath()));
     $drequest->updateSymbolicCommit($data['effectiveCommit']);
     $raw_changes = ArcanistDiffChange::newFromConduit($data['changes']);
     $diff = DifferentialDiff::newFromRawChanges($raw_changes);
     $changesets = $diff->getChangesets();
     $changeset = reset($changesets);
     if (!$changeset) {
         return new Aphront404Response();
     }
     $parser = new DifferentialChangesetParser();
     $parser->setUser($user);
     $parser->setChangeset($changeset);
     $parser->setRenderingReference($drequest->generateURI(array('action' => 'rendering-ref')));
     $parser->setCharacterEncoding($request->getStr('encoding'));
     $parser->setHighlightAs($request->getStr('highlight'));
     $coverage = $drequest->loadCoverage();
     if ($coverage) {
         $parser->setCoverage($coverage);
     }
     $pquery = new DiffusionPathIDQuery(array($changeset->getFilename()));
     $ids = $pquery->loadPathIDs();
     $path_id = $ids[$changeset->getFilename()];
     $parser->setLeftSideCommentMapping($path_id, false);
     $parser->setRightSideCommentMapping($path_id, true);
     $parser->setWhitespaceMode(DifferentialChangesetParser::WHITESPACE_SHOW_ALL);
     $inlines = PhabricatorAuditInlineComment::loadDraftAndPublishedComments($user, $drequest->loadCommit()->getPHID(), $path_id);
     if ($inlines) {
         foreach ($inlines as $inline) {
             $parser->parseInlineComment($inline);
         }
         $phids = mpull($inlines, 'getAuthorPHID');
         $handles = $this->loadViewerHandles($phids);
         $parser->setHandles($handles);
     }
     $engine = new PhabricatorMarkupEngine();
     $engine->setViewer($user);
     foreach ($inlines as $inline) {
         $engine->addObject($inline, PhabricatorInlineCommentInterface::MARKUP_FIELD_BODY);
     }
     $engine->process();
     $parser->setMarkupEngine($engine);
     $spec = $request->getStr('range');
     list($range_s, $range_e, $mask) = DifferentialChangesetParser::parseRangeSpecification($spec);
     $output = $parser->render($range_s, $range_e, $mask);
     return id(new PhabricatorChangesetResponse())->setRenderedChangeset($output);
 }
コード例 #24
0
 protected function execute(ConduitAPIRequest $request)
 {
     $viewer = $request->getUser();
     $change_data = $request->getValue('changes');
     $changes = array();
     foreach ($change_data as $dict) {
         $changes[] = ArcanistDiffChange::newFromDictionary($dict);
     }
     $diff = DifferentialDiff::newFromRawChanges($viewer, $changes);
     // TODO: Remove repository UUID eventually; for now continue writing
     // the UUID. Note that we'll overwrite it below if we identify a
     // repository, and `arc` no longer sends it. This stuff is retained for
     // backward compatibility.
     $repository_uuid = $request->getValue('repositoryUUID');
     $repository_phid = $request->getValue('repositoryPHID');
     if ($repository_phid) {
         $repository = id(new PhabricatorRepositoryQuery())->setViewer($viewer)->withPHIDs(array($repository_phid))->executeOne();
         if ($repository) {
             $repository_phid = $repository->getPHID();
             $repository_uuid = $repository->getUUID();
         }
     }
     switch ($request->getValue('lintStatus')) {
         case 'skip':
             $lint_status = DifferentialLintStatus::LINT_SKIP;
             break;
         case 'okay':
             $lint_status = DifferentialLintStatus::LINT_OKAY;
             break;
         case 'warn':
             $lint_status = DifferentialLintStatus::LINT_WARN;
             break;
         case 'fail':
             $lint_status = DifferentialLintStatus::LINT_FAIL;
             break;
         case 'postponed':
             $lint_status = DifferentialLintStatus::LINT_POSTPONED;
             break;
         case 'none':
         default:
             $lint_status = DifferentialLintStatus::LINT_NONE;
             break;
     }
     switch ($request->getValue('unitStatus')) {
         case 'skip':
             $unit_status = DifferentialUnitStatus::UNIT_SKIP;
             break;
         case 'okay':
             $unit_status = DifferentialUnitStatus::UNIT_OKAY;
             break;
         case 'warn':
             $unit_status = DifferentialUnitStatus::UNIT_WARN;
             break;
         case 'fail':
             $unit_status = DifferentialUnitStatus::UNIT_FAIL;
             break;
         case 'postponed':
             $unit_status = DifferentialUnitStatus::UNIT_POSTPONED;
             break;
         case 'none':
         default:
             $unit_status = DifferentialUnitStatus::UNIT_NONE;
             break;
     }
     $diff_data_dict = array('sourcePath' => $request->getValue('sourcePath'), 'sourceMachine' => $request->getValue('sourceMachine'), 'branch' => $request->getValue('branch'), 'creationMethod' => $request->getValue('creationMethod'), 'authorPHID' => $viewer->getPHID(), 'bookmark' => $request->getValue('bookmark'), 'repositoryUUID' => $repository_uuid, 'repositoryPHID' => $repository_phid, 'sourceControlSystem' => $request->getValue('sourceControlSystem'), 'sourceControlPath' => $request->getValue('sourceControlPath'), 'sourceControlBaseRevision' => $request->getValue('sourceControlBaseRevision'), 'lintStatus' => $lint_status, 'unitStatus' => $unit_status);
     $xactions = array(id(new DifferentialTransaction())->setTransactionType(DifferentialDiffTransaction::TYPE_DIFF_CREATE)->setNewValue($diff_data_dict));
     id(new DifferentialDiffEditor())->setActor($viewer)->setContentSourceFromConduitRequest($request)->setContinueOnNoEffect(true)->applyTransactions($diff, $xactions);
     $path = '/differential/diff/' . $diff->getID() . '/';
     $uri = PhabricatorEnv::getURI($path);
     return array('diffid' => $diff->getID(), 'phid' => $diff->getPHID(), 'uri' => $uri);
 }
コード例 #25
0
 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::newFromRawChanges($changes);
     return $diff->getChangesets();
 }
コード例 #26
0
 public static final function convertToDifferentialChangesets(array $changes)
 {
     $arcanist_changes = self::convertToArcanistChanges($changes);
     $diff = DifferentialDiff::newFromRawChanges($arcanist_changes);
     return $diff->getChangesets();
 }
コード例 #27
0
 /**
  * Generate an @{class:DifferentialChangeset} from two raw files. This is
  * principally useful because you can feed the output to
  * @{class:DifferentialChangesetParser} in order to render it.
  *
  * @param string Entire previous file content.
  * @param string Entire current file content.
  * @return @{class:DifferentialChangeset} Synthetic changeset.
  * @task diff
  */
 public function generateChangesetFromFileContent($old, $new)
 {
     $diff = $this->generateRawDiffFromFileContent($old, $new);
     $changes = id(new ArcanistDiffParser())->parseDiff($diff);
     $diff = DifferentialDiff::newFromRawChanges($changes);
     return head($diff->getChangesets());
 }
 private function generateFinalDiff(DifferentialRevision $revision, $actor_phid)
 {
     $viewer = PhabricatorUser::getOmnipotentUser();
     $drequest = DiffusionRequest::newFromDictionary(array('user' => $viewer, 'repository' => $this->repository));
     $raw_diff = DiffusionQuery::callConduitWithDiffusionRequest($viewer, $drequest, 'diffusion.rawdiffquery', array('commit' => $this->commit->getCommitIdentifier()));
     // TODO: Support adds, deletes and moves under SVN.
     if (strlen($raw_diff)) {
         $changes = id(new ArcanistDiffParser())->parseDiff($raw_diff);
     } else {
         // This is an empty diff, maybe made with `git commit --allow-empty`.
         // NOTE: These diffs have the same tree hash as their ancestors, so
         // they may attach to revisions in an unexpected way. Just let this
         // happen for now, although it might make sense to special case it
         // eventually.
         $changes = array();
     }
     $diff = DifferentialDiff::newFromRawChanges($changes)->setRepositoryPHID($this->repository->getPHID())->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 = DiffusionQuery::callConduitWithDiffusionRequest($viewer, $drequest, 'diffusion.commitparentsquery', array('commit' => $this->commit->getCommitIdentifier()));
     if ($parents) {
         $diff->setSourceControlBaseRevision(head($parents));
     }
     // TODO: Attach binary files.
     return $diff->save();
 }
コード例 #29
0
 protected function execute(ConduitAPIRequest $request)
 {
     $viewer = $request->getUser();
     $change_data = $request->getValue('changes');
     $changes = array();
     foreach ($change_data as $dict) {
         $changes[] = ArcanistDiffChange::newFromDictionary($dict);
     }
     $diff = DifferentialDiff::newFromRawChanges($changes);
     $diff->setSourcePath($request->getValue('sourcePath'));
     $diff->setSourceMachine($request->getValue('sourceMachine'));
     $diff->setBranch($request->getValue('branch'));
     $diff->setCreationMethod($request->getValue('creationMethod'));
     $diff->setAuthorPHID($viewer->getPHID());
     $diff->setBookmark($request->getValue('bookmark'));
     // TODO: Remove this eventually; for now continue writing the UUID. Note
     // that we'll overwrite it below if we identify a repository, and `arc`
     // no longer sends it. This stuff is retained for backward compatibility.
     $diff->setRepositoryUUID($request->getValue('repositoryUUID'));
     $repository_phid = $request->getValue('repositoryPHID');
     if ($repository_phid) {
         $repository = id(new PhabricatorRepositoryQuery())->setViewer($viewer)->withPHIDs(array($repository_phid))->executeOne();
         if ($repository) {
             $diff->setRepositoryPHID($repository->getPHID());
             $diff->setRepositoryUUID($repository->getUUID());
         }
     }
     $system = $request->getValue('sourceControlSystem');
     $diff->setSourceControlSystem($system);
     $diff->setSourceControlPath($request->getValue('sourceControlPath'));
     $diff->setSourceControlBaseRevision($request->getValue('sourceControlBaseRevision'));
     $project_name = $request->getValue('arcanistProject');
     $project_phid = null;
     if ($project_name) {
         $arcanist_project = id(new PhabricatorRepositoryArcanistProject())->loadOneWhere('name = %s', $project_name);
         if (!$arcanist_project) {
             $arcanist_project = new PhabricatorRepositoryArcanistProject();
             $arcanist_project->setName($project_name);
             $arcanist_project->save();
         }
         $project_phid = $arcanist_project->getPHID();
     }
     $diff->setArcanistProjectPHID($project_phid);
     switch ($request->getValue('lintStatus')) {
         case 'skip':
             $diff->setLintStatus(DifferentialLintStatus::LINT_SKIP);
             break;
         case 'okay':
             $diff->setLintStatus(DifferentialLintStatus::LINT_OKAY);
             break;
         case 'warn':
             $diff->setLintStatus(DifferentialLintStatus::LINT_WARN);
             break;
         case 'fail':
             $diff->setLintStatus(DifferentialLintStatus::LINT_FAIL);
             break;
         case 'postponed':
             $diff->setLintStatus(DifferentialLintStatus::LINT_POSTPONED);
             break;
         case 'none':
         default:
             $diff->setLintStatus(DifferentialLintStatus::LINT_NONE);
             break;
     }
     switch ($request->getValue('unitStatus')) {
         case 'skip':
             $diff->setUnitStatus(DifferentialUnitStatus::UNIT_SKIP);
             break;
         case 'okay':
             $diff->setUnitStatus(DifferentialUnitStatus::UNIT_OKAY);
             break;
         case 'warn':
             $diff->setUnitStatus(DifferentialUnitStatus::UNIT_WARN);
             break;
         case 'fail':
             $diff->setUnitStatus(DifferentialUnitStatus::UNIT_FAIL);
             break;
         case 'postponed':
             $diff->setUnitStatus(DifferentialUnitStatus::UNIT_POSTPONED);
             break;
         case 'none':
         default:
             $diff->setUnitStatus(DifferentialUnitStatus::UNIT_NONE);
             break;
     }
     id(new DifferentialDiffEditor())->setActor($viewer)->setContentSource(PhabricatorContentSource::newFromConduitRequest($request))->saveDiff($diff);
     // If we didn't get an explicit `repositoryPHID` (which means the client is
     // old, or couldn't figure out which repository the working copy belongs
     // to), apply heuristics to try to figure it out.
     if (!$repository_phid) {
         $repository = id(new DifferentialRepositoryLookup())->setDiff($diff)->setViewer($viewer)->lookupRepository();
         if ($repository) {
             $diff->setRepositoryPHID($repository->getPHID());
             $diff->setRepositoryUUID($repository->getUUID());
             $diff->save();
         }
     }
     $path = '/differential/diff/' . $diff->getID() . '/';
     $uri = PhabricatorEnv::getURI($path);
     return array('diffid' => $diff->getID(), 'uri' => $uri);
 }
コード例 #30
0
 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;
 }