[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |