[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/repository/management/ -> PhabricatorRepositoryManagementParentsWorkflow.php (source)

   1  <?php
   2  
   3  final class PhabricatorRepositoryManagementParentsWorkflow
   4    extends PhabricatorRepositoryManagementWorkflow {
   5  
   6    public function didConstruct() {
   7      $this
   8        ->setName('parents')
   9        ->setExamples('**parents** [options] [__repository__] ...')
  10        ->setSynopsis(
  11          pht(
  12            'Build parent caches in repositories that are missing the data, '.
  13            'or rebuild them in a specific __repository__.'))
  14        ->setArguments(
  15          array(
  16            array(
  17              'name'        => 'repos',
  18              'wildcard'    => true,
  19            ),
  20          ));
  21    }
  22  
  23    public function execute(PhutilArgumentParser $args) {
  24      $repos = $this->loadRepositories($args, 'repos');
  25      if (!$repos) {
  26        $repos = id(new PhabricatorRepositoryQuery())
  27          ->setViewer($this->getViewer())
  28          ->execute();
  29      }
  30  
  31      $console = PhutilConsole::getConsole();
  32      foreach ($repos as $repo) {
  33        $monogram = $repo->getMonogram();
  34        if ($repo->isSVN()) {
  35          $console->writeOut(
  36            "%s\n",
  37            pht(
  38              'Skipping "%s": Subversion repositories do not require this '.
  39              'cache to be built.',
  40              $monogram));
  41          continue;
  42        }
  43        $this->rebuildRepository($repo);
  44      }
  45  
  46      return 0;
  47    }
  48  
  49    private function rebuildRepository(PhabricatorRepository $repo) {
  50      $console = PhutilConsole::getConsole();
  51      $console->writeOut("%s\n", pht('Rebuilding "%s"...', $repo->getMonogram()));
  52  
  53      $refs = id(new PhabricatorRepositoryRefCursorQuery())
  54        ->setViewer($this->getViewer())
  55        ->withRefTypes(array(PhabricatorRepositoryRefCursor::TYPE_BRANCH))
  56        ->withRepositoryPHIDs(array($repo->getPHID()))
  57        ->execute();
  58  
  59      $graph = array();
  60      foreach ($refs as $ref) {
  61        if (!$repo->shouldTrackBranch($ref->getRefName())) {
  62          continue;
  63        }
  64  
  65        $console->writeOut(
  66          "%s\n",
  67          pht('Rebuilding branch "%s"...', $ref->getRefName()));
  68  
  69        $commit = $ref->getCommitIdentifier();
  70  
  71        if ($repo->isGit()) {
  72          $stream = new PhabricatorGitGraphStream($repo, $commit);
  73        } else {
  74          $stream = new PhabricatorMercurialGraphStream($repo, $commit);
  75        }
  76  
  77        $discover = array($commit);
  78        while ($discover) {
  79          $target = array_pop($discover);
  80          if (isset($graph[$target])) {
  81            continue;
  82          }
  83          $graph[$target] = $stream->getParents($target);
  84          foreach ($graph[$target] as $parent) {
  85            $discover[] = $parent;
  86          }
  87        }
  88      }
  89  
  90      $console->writeOut(
  91        "%s\n",
  92        pht(
  93          'Found %s total commit(s); updating...',
  94          new PhutilNumber(count($graph))));
  95  
  96      $commit_table = id(new PhabricatorRepositoryCommit());
  97      $commit_table_name = $commit_table->getTableName();
  98      $conn_w = $commit_table->establishConnection('w');
  99  
 100      $bar = id(new PhutilConsoleProgressBar())
 101        ->setTotal(count($graph));
 102  
 103      $need = array();
 104      foreach ($graph as $child => $parents) {
 105        foreach ($parents as $parent) {
 106          $need[$parent] = $parent;
 107        }
 108        $need[$child] = $child;
 109      }
 110  
 111      $map = array();
 112      foreach (array_chunk($need, 2048) as $chunk) {
 113        $rows = queryfx_all(
 114          $conn_w,
 115          'SELECT id, commitIdentifier FROM %T
 116            WHERE commitIdentifier IN (%Ls) AND repositoryID = %d',
 117          $commit_table_name,
 118          $chunk,
 119          $repo->getID());
 120        foreach ($rows as $row) {
 121          $map[$row['commitIdentifier']] = $row['id'];
 122        }
 123      }
 124  
 125      $insert_sql = array();
 126      $delete_sql = array();
 127  
 128      foreach ($graph as $child => $parents) {
 129        $names = $parents;
 130        $names[] = $child;
 131  
 132        foreach ($names as $name) {
 133          if (empty($map[$name])) {
 134            throw new Exception(pht('Unknown commit "%s"!', $name));
 135          }
 136        }
 137  
 138        if (!$parents) {
 139          // Write an explicit 0 to indicate "no parents" instead of "no data".
 140          $insert_sql[] = qsprintf(
 141            $conn_w,
 142            '(%d, 0)',
 143            $map[$child]);
 144        } else {
 145          foreach ($parents as $parent) {
 146            $insert_sql[] = qsprintf(
 147              $conn_w,
 148              '(%d, %d)',
 149              $map[$child],
 150              $map[$parent]);
 151          }
 152        }
 153  
 154        $delete_sql[] = $map[$child];
 155  
 156        $bar->update(1);
 157      }
 158  
 159      $commit_table->openTransaction();
 160      foreach (PhabricatorLiskDAO::chunkSQL($delete_sql) as $chunk) {
 161        queryfx(
 162          $conn_w,
 163          'DELETE FROM %T WHERE childCommitID IN (%Q)',
 164          PhabricatorRepository::TABLE_PARENTS,
 165          $chunk);
 166      }
 167  
 168      foreach (PhabricatorLiskDAO::chunkSQL($insert_sql) as $chunk) {
 169        queryfx(
 170          $conn_w,
 171          'INSERT INTO %T (childCommitID, parentCommitID) VALUES %Q',
 172          PhabricatorRepository::TABLE_PARENTS,
 173          $chunk);
 174      }
 175      $commit_table->saveTransaction();
 176  
 177      $bar->done();
 178    }
 179  
 180  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1