@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
at upstream/main 169 lines 4.5 kB view raw
1<?php 2 3final class DiffusionLastModifiedQueryConduitAPIMethod 4 extends DiffusionQueryConduitAPIMethod { 5 6 public function getAPIMethodName() { 7 return 'diffusion.lastmodifiedquery'; 8 } 9 10 public function getMethodDescription() { 11 return pht('Get the commits at which paths were last modified.'); 12 } 13 14 protected function defineReturnType() { 15 return 'map<string, string>'; 16 } 17 18 protected function defineCustomParamTypes() { 19 return array( 20 'paths' => 'required map<string, string>', 21 ); 22 } 23 24 protected function getGitResult(ConduitAPIRequest $request) { 25 $drequest = $this->getDiffusionRequest(); 26 $repository = $drequest->getRepository(); 27 28 $paths = $request->getValue('paths'); 29 $results = $this->loadCommitsFromCache($paths); 30 31 foreach ($paths as $path => $commit) { 32 if (array_key_exists($path, $results)) { 33 continue; 34 } 35 list($hash) = $repository->execxLocalCommand( 36 'log -n1 %s %s -- %s', 37 '--format=%H', 38 gitsprintf('%s', $commit), 39 $path); 40 $results[$path] = trim($hash); 41 } 42 43 return $results; 44 } 45 46 protected function getSVNResult(ConduitAPIRequest $request) { 47 $drequest = $this->getDiffusionRequest(); 48 $repository = $drequest->getRepository(); 49 50 $results = array(); 51 foreach ($request->getValue('paths') as $path => $commit) { 52 $history_result = DiffusionQuery::callConduitWithDiffusionRequest( 53 $request->getUser(), 54 $drequest, 55 'diffusion.historyquery', 56 array( 57 'commit' => $commit, 58 'path' => $path, 59 'limit' => 1, 60 'offset' => 0, 61 'needDirectChanges' => true, 62 'needChildChanges' => true, 63 )); 64 65 $history_array = DiffusionPathChange::newFromConduit( 66 $history_result['pathChanges']); 67 if ($history_array) { 68 $results[$path] = head($history_array) 69 ->getCommit() 70 ->getCommitIdentifier(); 71 } 72 } 73 74 return $results; 75 } 76 77 protected function getMercurialResult(ConduitAPIRequest $request) { 78 $drequest = $this->getDiffusionRequest(); 79 $repository = $drequest->getRepository(); 80 81 $paths = $request->getValue('paths'); 82 $results = $this->loadCommitsFromCache($paths); 83 84 foreach ($paths as $path => $commit) { 85 if (array_key_exists($path, $results)) { 86 continue; 87 } 88 89 list($hash) = $repository->execxLocalCommand( 90 'log --template %s --limit 1 --removed --rev %s -- %s', 91 '{node}', 92 hgsprintf('reverse(ancestors(%s))', $commit), 93 nonempty(ltrim($path, '/'), '.')); 94 $results[$path] = trim($hash); 95 } 96 97 return $results; 98 } 99 100 private function loadCommitsFromCache(array $map) { 101 $drequest = $this->getDiffusionRequest(); 102 $repository = $drequest->getRepository(); 103 104 $path_map = id(new DiffusionPathIDQuery(array_keys($map))) 105 ->loadPathIDs(); 106 107 $commit_query = id(new DiffusionCommitQuery()) 108 ->setViewer($drequest->getUser()) 109 ->withRepository($repository) 110 ->withIdentifiers(array_values($map)); 111 $commit_query->execute(); 112 113 $commit_map = $commit_query->getIdentifierMap(); 114 $commit_map = mpull($commit_map, 'getID'); 115 116 $graph_cache = new PhabricatorRepositoryGraphCache(); 117 118 $results = array(); 119 120 // Spend no more than this many total seconds trying to satisfy queries 121 // via the graph cache. 122 $remaining_time = 10.0; 123 foreach ($map as $path => $commit) { 124 $path_id = idx($path_map, $path); 125 if (!$path_id) { 126 continue; 127 } 128 $commit_id = idx($commit_map, $commit); 129 if (!$commit_id) { 130 continue; 131 } 132 133 $t_start = microtime(true); 134 $cache_result = $graph_cache->loadLastModifiedCommitID( 135 $commit_id, 136 $path_id, 137 $remaining_time); 138 $t_end = microtime(true); 139 140 if ($cache_result !== false) { 141 $results[$path] = $cache_result; 142 } 143 144 $remaining_time -= ($t_end - $t_start); 145 if ($remaining_time <= 0) { 146 break; 147 } 148 } 149 150 if ($results) { 151 $commits = id(new DiffusionCommitQuery()) 152 ->setViewer($drequest->getUser()) 153 ->withRepository($repository) 154 ->withIDs($results) 155 ->execute(); 156 foreach ($results as $path => $id) { 157 $commit = idx($commits, $id); 158 if ($commit) { 159 $results[$path] = $commit->getCommitIdentifier(); 160 } else { 161 unset($results[$path]); 162 } 163 } 164 } 165 166 return $results; 167 } 168 169}