private function buildRawFileResponse(DifferentialChangeset $changeset, $is_new)
 {
     $viewer = $this->getViewer();
     if ($is_new) {
         $key = 'raw:new:phid';
     } else {
         $key = 'raw:old:phid';
     }
     $metadata = $changeset->getMetadata();
     $file = null;
     $phid = idx($metadata, $key);
     if ($phid) {
         $file = id(new PhabricatorFileQuery())->setViewer($viewer)->withPHIDs(array($phid))->execute();
         if ($file) {
             $file = head($file);
         }
     }
     if (!$file) {
         // This is just building a cache of the changeset content in the file
         // tool, and is safe to run on a read pathway.
         $unguard = AphrontWriteGuard::beginScopedUnguardedWrites();
         if ($is_new) {
             $data = $changeset->makeNewFile();
         } else {
             $data = $changeset->makeOldFile();
         }
         $file = PhabricatorFile::newFromFileData($data, array('name' => $changeset->getFilename(), 'mime-type' => 'text/plain'));
         $metadata[$key] = $file->getPHID();
         $changeset->setMetadata($metadata);
         $changeset->save();
         unset($unguard);
     }
     return $file->getRedirectResponse();
 }
 public static function newFromRawChanges(array $changes)
 {
     $diff = new DifferentialDiff();
     $lines = 0;
     foreach ($changes as $change) {
         $changeset = new DifferentialChangeset();
         $add_lines = 0;
         $del_lines = 0;
         $hunks = $change->getHunks();
         if ($hunks) {
             foreach ($hunks as $hunk) {
                 $dhunk = new DifferentialHunk();
                 $dhunk->setOldOffset($hunk->getOldOffset());
                 $dhunk->setOldLen($hunk->getOldLength());
                 $dhunk->setNewOffset($hunk->getNewOffset());
                 $dhunk->setNewLen($hunk->getNewLength());
                 $dhunk->setChanges($hunk->getCorpus());
                 $changeset->addUnsavedHunk($dhunk);
                 $add_lines += $hunk->getAddLines();
                 $del_lines += $hunk->getDelLines();
                 $lines += $add_lines + $del_lines;
             }
         } else {
             // This happens when you add empty files.
             $changeset->attachHunks(array());
         }
         $changeset->setOldFile($change->getOldPath());
         $changeset->setFilename($change->getCurrentPath());
         $changeset->setChangeType($change->getType());
         $changeset->setFileType($change->getFileType());
         $changeset->setMetadata($change->getAllMetadata());
         $changeset->setOldProperties($change->getOldProperties());
         $changeset->setNewProperties($change->getNewProperties());
         $changeset->setAwayPaths($change->getAwayPaths());
         $changeset->setAddLines($add_lines);
         $changeset->setDelLines($del_lines);
         $diff->addUnsavedChangeset($changeset);
     }
     $diff->setLineCount($lines);
     return $diff;
 }
 private static function buildChangesetsFromRawChanges(DifferentialDiff $diff, array $changes)
 {
     // There may not be any changes; initialize the changesets list so that
     // we don't throw later when accessing it.
     $diff->attachChangesets(array());
     $lines = 0;
     foreach ($changes as $change) {
         if ($change->getType() == ArcanistDiffChangeType::TYPE_MESSAGE) {
             // If a user pastes a diff into Differential which includes a commit
             // message (e.g., they ran `git show` to generate it), discard that
             // change when constructing a DifferentialDiff.
             continue;
         }
         $changeset = new DifferentialChangeset();
         $add_lines = 0;
         $del_lines = 0;
         $first_line = PHP_INT_MAX;
         $hunks = $change->getHunks();
         if ($hunks) {
             foreach ($hunks as $hunk) {
                 $dhunk = new DifferentialModernHunk();
                 $dhunk->setOldOffset($hunk->getOldOffset());
                 $dhunk->setOldLen($hunk->getOldLength());
                 $dhunk->setNewOffset($hunk->getNewOffset());
                 $dhunk->setNewLen($hunk->getNewLength());
                 $dhunk->setChanges($hunk->getCorpus());
                 $changeset->addUnsavedHunk($dhunk);
                 $add_lines += $hunk->getAddLines();
                 $del_lines += $hunk->getDelLines();
                 $added_lines = $hunk->getChangedLines('new');
                 if ($added_lines) {
                     $first_line = min($first_line, head_key($added_lines));
                 }
             }
             $lines += $add_lines + $del_lines;
         } else {
             // This happens when you add empty files.
             $changeset->attachHunks(array());
         }
         $metadata = $change->getAllMetadata();
         if ($first_line != PHP_INT_MAX) {
             $metadata['line:first'] = $first_line;
         }
         $changeset->setOldFile($change->getOldPath());
         $changeset->setFilename($change->getCurrentPath());
         $changeset->setChangeType($change->getType());
         $changeset->setFileType($change->getFileType());
         $changeset->setMetadata($metadata);
         $changeset->setOldProperties($change->getOldProperties());
         $changeset->setNewProperties($change->getNewProperties());
         $changeset->setAwayPaths($change->getAwayPaths());
         $changeset->setAddLines($add_lines);
         $changeset->setDelLines($del_lines);
         $diff->addUnsavedChangeset($changeset);
     }
     $diff->setLineCount($lines);
     $parser = new DifferentialChangesetParser();
     $changesets = $parser->detectCopiedCode($diff->getChangesets(), $min_width = 30, $min_lines = 3);
     $diff->attachChangesets($changesets);
     return $diff;
 }
 public static function newFromRawChanges(array $changes)
 {
     assert_instances_of($changes, 'ArcanistDiffChange');
     $diff = new DifferentialDiff();
     $lines = 0;
     foreach ($changes as $change) {
         $changeset = new DifferentialChangeset();
         $add_lines = 0;
         $del_lines = 0;
         $first_line = PHP_INT_MAX;
         $hunks = $change->getHunks();
         if ($hunks) {
             foreach ($hunks as $hunk) {
                 $dhunk = new DifferentialHunk();
                 $dhunk->setOldOffset($hunk->getOldOffset());
                 $dhunk->setOldLen($hunk->getOldLength());
                 $dhunk->setNewOffset($hunk->getNewOffset());
                 $dhunk->setNewLen($hunk->getNewLength());
                 $dhunk->setChanges($hunk->getCorpus());
                 $changeset->addUnsavedHunk($dhunk);
                 $add_lines += $hunk->getAddLines();
                 $del_lines += $hunk->getDelLines();
                 $added_lines = $hunk->getChangedLines('new');
                 if ($added_lines) {
                     $first_line = min($first_line, head_key($added_lines));
                 }
             }
             $lines += $add_lines + $del_lines;
         } else {
             // This happens when you add empty files.
             $changeset->attachHunks(array());
         }
         $metadata = $change->getAllMetadata();
         if ($first_line != PHP_INT_MAX) {
             $metadata['line:first'] = $first_line;
         }
         $changeset->setOldFile($change->getOldPath());
         $changeset->setFilename($change->getCurrentPath());
         $changeset->setChangeType($change->getType());
         $changeset->setFileType($change->getFileType());
         $changeset->setMetadata($metadata);
         $changeset->setOldProperties($change->getOldProperties());
         $changeset->setNewProperties($change->getNewProperties());
         $changeset->setAwayPaths($change->getAwayPaths());
         $changeset->setAddLines($add_lines);
         $changeset->setDelLines($del_lines);
         $diff->addUnsavedChangeset($changeset);
     }
     $diff->setLineCount($lines);
     $diff->detectCopiedCode();
     return $diff;
 }