protected function getCommitFileList(array $revision)
 {
     $repository_api = $this->getRepositoryAPI();
     $revision_id = $revision['id'];
     $commit_paths = $this->getConduit()->callMethodSynchronous('differential.getcommitpaths', array('revision_id' => $revision_id));
     $dir_paths = array();
     foreach ($commit_paths as $path) {
         $path = dirname($path);
         while ($path != '.') {
             $dir_paths[$path] = true;
             $path = dirname($path);
         }
     }
     $commit_paths = array_fill_keys($commit_paths, true);
     $status = $repository_api->getSVNStatus();
     $modified_but_not_included = array();
     foreach ($status as $path => $mask) {
         if (!empty($dir_paths[$path])) {
             $commit_paths[$path] = true;
         }
         if (!empty($commit_paths[$path])) {
             continue;
         }
         foreach ($commit_paths as $will_commit => $ignored) {
             if (Filesystem::isDescendant($path, $will_commit)) {
                 throw new ArcanistUsageException(pht("This commit includes the directory '%s', but it contains a " . "modified path ('%s') which is NOT included in the commit. " . "Subversion can not handle this operation and will commit the " . "path anyway. You need to sort out the working copy changes to " . "'%s' before you may proceed with the commit.", $will_commit, $path, $path));
             }
         }
         $modified_but_not_included[] = $path;
     }
     if ($modified_but_not_included) {
         $prefix = pht('%s locally modified path(s) are not included in this revision:', phutil_count($modified_but_not_included));
         $prompt = pht('These %s path(s) will NOT be committed. Commit this revision anyway?', phutil_count($modified_but_not_included));
         $this->promptFileWarning($prefix, $prompt, $modified_but_not_included);
     }
     $do_not_exist = array();
     foreach ($commit_paths as $path => $ignored) {
         $disk_path = $repository_api->getPath($path);
         if (file_exists($disk_path)) {
             continue;
         }
         if (is_link($disk_path)) {
             continue;
         }
         if (idx($status, $path) & ArcanistRepositoryAPI::FLAG_DELETED) {
             continue;
         }
         $do_not_exist[] = $path;
         unset($commit_paths[$path]);
     }
     if ($do_not_exist) {
         $prefix = pht('Revision includes changes to %s path(s) that do not exist:', phutil_count($do_not_exist));
         $prompt = pht('Commit this revision anyway?');
         $this->promptFileWarning($prefix, $prompt, $do_not_exist);
     }
     $files = array_keys($commit_paths);
     $files = ArcanistSubversionAPI::escapeFileNamesForSVN($files);
     if (empty($files)) {
         throw new ArcanistUsageException(pht('There is nothing left to commit. ' . 'None of the modified paths exist.'));
     }
     return $files;
 }
 public function testSVNFileEscapes()
 {
     $input = array('.', 'x', '*****@*****.**');
     $expect = array('.', 'x', 'x@2x.png@');
     $this->assertEqual($expect, ArcanistSubversionAPI::escapeFileNamesForSVN($input));
 }