protected function getChange($path)
 {
     $repository_api = $this->getRepositoryAPI();
     // TODO: Very gross
     $is_git = $repository_api instanceof ArcanistGitAPI;
     $is_hg = $repository_api instanceof ArcanistMercurialAPI;
     $is_svn = $repository_api instanceof ArcanistSubversionAPI;
     if ($is_svn) {
         // NOTE: In SVN, we don't currently support a "get all local changes"
         // operation, so special case it.
         if (empty($this->changeCache[$path])) {
             $diff = $repository_api->getRawDiffText($path);
             $parser = $this->newDiffParser();
             $changes = $parser->parseDiff($diff);
             if (count($changes) != 1) {
                 throw new Exception("Expected exactly one change.");
             }
             $this->changeCache[$path] = reset($changes);
         }
     } else {
         if ($is_git || $is_hg) {
             if (empty($this->changeCache)) {
                 $changes = $repository_api->getAllLocalChanges();
                 foreach ($changes as $change) {
                     $this->changeCache[$change->getCurrentPath()] = $change;
                 }
             }
         } else {
             throw new Exception("Missing VCS support.");
         }
     }
     if (empty($this->changeCache[$path])) {
         if ($is_git) {
             // This can legitimately occur under git if you make a change, "git
             // commit" it, and then revert the change in the working copy and run
             // "arc lint".
             $change = new ArcanistDiffChange();
             $change->setCurrentPath($path);
             return $change;
         } else {
             throw new Exception("Trying to get change for unchanged path '{$path}'!");
         }
     }
     return $this->changeCache[$path];
 }
 public static final function convertToArcanistChanges(array $changes)
 {
     assert_instances_of($changes, 'DiffusionPathChange');
     $direct = array();
     $result = array();
     foreach ($changes as $path) {
         $change = new ArcanistDiffChange();
         $change->setCurrentPath($path->getPath());
         $direct[] = $path->getPath();
         $change->setType($path->getChangeType());
         $file_type = $path->getFileType();
         if ($file_type == DifferentialChangeType::FILE_NORMAL) {
             $file_type = DifferentialChangeType::FILE_TEXT;
         }
         $change->setFileType($file_type);
         $change->setOldPath($path->getTargetPath());
         foreach ($path->getAwayPaths() as $away_path) {
             $change->addAwayPath($away_path);
         }
         $result[$path->getPath()] = $change;
     }
     return array_select_keys($result, $direct);
 }
 protected function buildChange($path = null)
 {
     $change = null;
     if ($path !== null) {
         if (!empty($this->changes[$path])) {
             return $this->changes[$path];
         }
     }
     if ($this->forcePath) {
         return $this->changes[$this->forcePath];
     }
     $change = new ArcanistDiffChange();
     if ($path !== null) {
         $change->setCurrentPath($path);
         $this->changes[$path] = $change;
     } else {
         $this->changes[] = $change;
     }
     return $change;
 }