[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/diffusion/query/lowlevel/ -> DiffusionLowLevelGitRefQuery.php (source)

   1  <?php
   2  
   3  /**
   4   * Execute and parse a low-level Git ref query using `git for-each-ref`. This
   5   * is useful for returning a list of tags or branches.
   6   *
   7   *
   8   */
   9  final class DiffusionLowLevelGitRefQuery extends DiffusionLowLevelQuery {
  10  
  11    private $isTag;
  12    private $isOriginBranch;
  13  
  14    public function withIsTag($is_tag) {
  15      $this->isTag = $is_tag;
  16      return $this;
  17    }
  18  
  19    public function withIsOriginBranch($is_origin_branch) {
  20      $this->isOriginBranch = $is_origin_branch;
  21      return $this;
  22    }
  23  
  24    protected function executeQuery() {
  25      $repository = $this->getRepository();
  26  
  27      if ($this->isTag && $this->isOriginBranch) {
  28        throw new Exception('Specify tags or origin branches, not both!');
  29      } else if ($this->isTag) {
  30        $prefix = 'refs/tags/';
  31      } else if ($this->isOriginBranch) {
  32        if ($repository->isWorkingCopyBare()) {
  33          $prefix = 'refs/heads/';
  34        } else {
  35          $remote = DiffusionGitBranch::DEFAULT_GIT_REMOTE;
  36          $prefix = 'refs/remotes/'.$remote.'/';
  37        }
  38      } else {
  39        throw new Exception('Specify tags or origin branches!');
  40      }
  41  
  42      $order = '-creatordate';
  43  
  44      list($stdout) = $repository->execxLocalCommand(
  45        'for-each-ref --sort=%s --format=%s %s',
  46        $order,
  47        $this->getFormatString(),
  48        $prefix);
  49  
  50      $stdout = rtrim($stdout);
  51      if (!strlen($stdout)) {
  52        return array();
  53      }
  54  
  55      // NOTE: Although git supports --count, we can't apply any offset or limit
  56      // logic until the very end because we may encounter a HEAD which we want
  57      // to discard.
  58  
  59      $lines = explode("\n", $stdout);
  60      $results = array();
  61      foreach ($lines as $line) {
  62        $fields = $this->extractFields($line);
  63  
  64        $creator = $fields['creator'];
  65        $matches = null;
  66        if (preg_match('/^(.*) ([0-9]+) ([0-9+-]+)$/', $creator, $matches)) {
  67          $fields['author'] = $matches[1];
  68          $fields['epoch'] = (int)$matches[2];
  69        } else {
  70          $fields['author'] = null;
  71          $fields['epoch'] = null;
  72        }
  73  
  74        $commit = nonempty($fields['*objectname'], $fields['objectname']);
  75  
  76        $short = substr($fields['refname'], strlen($prefix));
  77        if ($short == 'HEAD') {
  78          continue;
  79        }
  80  
  81        $ref = id(new DiffusionRepositoryRef())
  82          ->setShortName($short)
  83          ->setCommitIdentifier($commit)
  84          ->setRawFields($fields);
  85  
  86        $results[] = $ref;
  87      }
  88  
  89      return $results;
  90    }
  91  
  92    /**
  93     * List of git `--format` fields we want to grab.
  94     */
  95    private function getFields() {
  96      return array(
  97        'objectname',
  98        'objecttype',
  99        'refname',
 100        '*objectname',
 101        '*objecttype',
 102        'subject',
 103        'creator',
 104      );
 105    }
 106  
 107    /**
 108     * Get a string for `--format` which enumerates all the fields we want.
 109     */
 110    private function getFormatString() {
 111      $fields = $this->getFields();
 112  
 113      foreach ($fields as $key => $field) {
 114        $fields[$key] = '%('.$field.')';
 115      }
 116  
 117      return implode('%01', $fields);
 118    }
 119  
 120    /**
 121     * Parse a line back into fields.
 122     */
 123    private function extractFields($line) {
 124      $fields = $this->getFields();
 125      $parts = explode("\1", $line, count($fields));
 126  
 127      $dict = array();
 128      foreach ($fields as $index => $field) {
 129        $dict[$field] = idx($parts, $index);
 130      }
 131  
 132      return $dict;
 133    }
 134  
 135  }


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