@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
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Compare two branches

Summary:
This shows the commits list only (Actual `git diff` will show up at a later date).
The inputs are left as text-fields, to allow the form to accept anything that can be resolved. The form is GET, to allow sharing URIs.

The conduit method response array is compatible with that of `diffusion.historyquery`, to make it easy to build
the "history" table.

The hardest part here was, of course, Naming. I think "from" and "onto" are unconfusing, and I'm fairly confident that the "to merge"
instructions are in sync with the actual content of the page.

Test Plan: Look at several "compare" views, with various values of "from" and "onto".

Reviewers: #blessed_reviewers!, epriestley

Subscribers: caov297, 20after4, Sam2304, reardencode, baileyb, chad, Korvin

Maniphest Tasks: T929

Differential Revision: https://secure.phabricator.com/D15330

authored by

Aviv Eyal and committed by
epriestley
43f9927a 0ad1dd64

+279 -4
+2
src/__phutil_library_map__.php
··· 635 635 'DiffusionCommitRevisionReviewersHeraldField' => 'applications/diffusion/herald/DiffusionCommitRevisionReviewersHeraldField.php', 636 636 'DiffusionCommitRevisionSubscribersHeraldField' => 'applications/diffusion/herald/DiffusionCommitRevisionSubscribersHeraldField.php', 637 637 'DiffusionCommitTagsController' => 'applications/diffusion/controller/DiffusionCommitTagsController.php', 638 + 'DiffusionCompareController' => 'applications/diffusion/controller/DiffusionCompareController.php', 638 639 'DiffusionConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionConduitAPIMethod.php', 639 640 'DiffusionController' => 'applications/diffusion/controller/DiffusionController.php', 640 641 'DiffusionCreateCommentConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionCreateCommentConduitAPIMethod.php', ··· 5273 5274 'DiffusionCommitRevisionReviewersHeraldField' => 'DiffusionCommitHeraldField', 5274 5275 'DiffusionCommitRevisionSubscribersHeraldField' => 'DiffusionCommitHeraldField', 5275 5276 'DiffusionCommitTagsController' => 'DiffusionController', 5277 + 'DiffusionCompareController' => 'DiffusionController', 5276 5278 'DiffusionConduitAPIMethod' => 'ConduitAPIMethod', 5277 5279 'DiffusionController' => 'PhabricatorController', 5278 5280 'DiffusionCreateCommentConduitAPIMethod' => 'DiffusionConduitAPIMethod',
+1
src/applications/diffusion/application/PhabricatorDiffusionApplication.php
··· 65 65 => 'DiffusionCommitTagsController', 66 66 'commit/(?P<commit>[a-z0-9]+)/edit/' 67 67 => 'DiffusionCommitEditController', 68 + 'compare/' => 'DiffusionCompareController', 68 69 'manage/(?:(?P<panel>[^/]+)/)?' 69 70 => 'DiffusionRepositoryManagePanelsController', 70 71 'uri/' => array(
+13 -4
src/applications/diffusion/conduit/DiffusionHistoryQueryConduitAPIMethod.php
··· 22 22 protected function defineCustomParamTypes() { 23 23 return array( 24 24 'commit' => 'required string', 25 + 'against' => 'optional string', 25 26 'path' => 'required string', 26 27 'offset' => 'required int', 27 28 'limit' => 'required int', ··· 43 44 $drequest = $this->getDiffusionRequest(); 44 45 $repository = $drequest->getRepository(); 45 46 $commit_hash = $request->getValue('commit'); 47 + $against_hash = $request->getValue('against'); 46 48 $path = $request->getValue('path'); 47 49 $offset = $request->getValue('offset'); 48 50 $limit = $request->getValue('limit'); 49 51 52 + if (strlen($against_hash)) { 53 + $commit_range = "${against_hash}..${commit_hash}"; 54 + } else { 55 + $commit_range = $commit_hash; 56 + } 57 + 50 58 list($stdout) = $repository->execxLocalCommand( 51 59 'log '. 52 60 '--skip=%d '. ··· 56 64 $offset, 57 65 $limit, 58 66 '%H:%P', 59 - $commit_hash, 67 + $commit_range, 60 68 // Git omits merge commits if the path is provided, even if it is empty. 61 69 (strlen($path) ? csprintf('%s', $path) : '')); 62 70 63 71 $lines = explode("\n", trim($stdout)); 64 72 $lines = array_filter($lines); 65 - if (!$lines) { 66 - return array(); 67 - } 68 73 69 74 $hash_list = array(); 70 75 $parent_map = array(); ··· 75 80 } 76 81 77 82 $this->parents = $parent_map; 83 + 84 + if (!$hash_list) { 85 + return array(); 86 + } 78 87 79 88 return DiffusionQuery::loadHistoryForCommitIdentifiers( 80 89 $hash_list,
+260
src/applications/diffusion/controller/DiffusionCompareController.php
··· 1 + <?php 2 + 3 + final class DiffusionCompareController extends DiffusionController { 4 + 5 + public function shouldAllowPublic() { 6 + return true; 7 + } 8 + 9 + public function handleRequest(AphrontRequest $request) { 10 + $response = $this->loadDiffusionContext(); 11 + if ($response) { 12 + return $response; 13 + } 14 + 15 + $viewer = $this->getViewer(); 16 + $drequest = $this->getDiffusionRequest(); 17 + $repository = $drequest->getRepository(); 18 + 19 + $content = array(); 20 + 21 + $crumbs = $this->buildCrumbs(array('view' => 'compare')); 22 + 23 + $empty_title = null; 24 + $error_message = null; 25 + 26 + if ($repository->getVersionControlSystem() != 27 + PhabricatorRepositoryType::REPOSITORY_TYPE_GIT) { 28 + $empty_title = pht('Not supported'); 29 + $error_message = pht( 30 + 'This feature is not yet supported for %s repositories.', 31 + $repository->getVersionControlSystem()); 32 + $content[] = id(new PHUIInfoView()) 33 + ->setTitle($empty_title) 34 + ->setSeverity(PHUIInfoView::SEVERITY_WARNING) 35 + ->setErrors(array($error_message)); 36 + } 37 + 38 + $head_ref = $request->getStr('head'); 39 + $against_ref = $request->getStr('against'); 40 + 41 + $refs = id(new DiffusionCachedResolveRefsQuery()) 42 + ->setRepository($repository) 43 + ->withRefs(array($head_ref, $against_ref)) 44 + ->execute(); 45 + 46 + 47 + if (count($refs) == 2) { 48 + $content[] = $this->buildCompareContent($drequest); 49 + } else { 50 + $content[] = $this->buildCompareForm($request, $refs); 51 + } 52 + 53 + 54 + return $this->newPage() 55 + ->setTitle( 56 + array( 57 + $repository->getName(), 58 + $repository->getDisplayName(), 59 + )) 60 + ->setCrumbs($crumbs) 61 + ->appendChild($content); 62 + } 63 + 64 + private function buildCompareForm(AphrontRequest $request, array $resolved) { 65 + $viewer = $this->getViewer(); 66 + 67 + $head_ref = $request->getStr('head'); 68 + $against_ref = $request->getStr('against'); 69 + 70 + if (idx($resolved, $head_ref)) { 71 + $e_head = null; 72 + } else { 73 + $e_head = 'Not Found'; 74 + } 75 + 76 + if (idx($resolved, $against_ref)) { 77 + $e_against = null; 78 + } else { 79 + $e_against = 'Not Found'; 80 + } 81 + 82 + 83 + $form = id(new AphrontFormView()) 84 + ->setUser($viewer) 85 + ->setMethod('GET') 86 + ->appendControl( 87 + id(new AphrontFormTextControl()) 88 + ->setLabel(pht('Head')) 89 + ->setName('head') 90 + ->setError($e_head) 91 + ->setValue($head_ref)) 92 + ->appendControl( 93 + id(new AphrontFormTextControl()) 94 + ->setLabel(pht('Against')) 95 + ->setName('against') 96 + ->setError($e_against) 97 + ->setValue($against_ref)) 98 + ->appendControl( 99 + id(new AphrontFormSubmitControl()) 100 + ->setValue('Compare')); 101 + 102 + return $form; 103 + } 104 + 105 + private function buildCompareContent(DiffusionRequest $drequest) { 106 + $request = $this->getRequest(); 107 + $repository = $drequest->getRepository(); 108 + 109 + $head_ref = $request->getStr('head'); 110 + $against_ref = $request->getStr('against'); 111 + 112 + $content = array(); 113 + 114 + $pager = id(new PHUIPagerView()) 115 + ->readFromRequest($request); 116 + 117 + try { 118 + $history_results = $this->callConduitWithDiffusionRequest( 119 + 'diffusion.historyquery', 120 + array( 121 + 'commit' => $head_ref, 122 + 'against' => $against_ref, 123 + 'path' => $drequest->getPath(), 124 + 'offset' => $pager->getOffset(), 125 + 'limit' => $pager->getPageSize() + 1, 126 + )); 127 + $history = DiffusionPathChange::newFromConduit( 128 + $history_results['pathChanges']); 129 + 130 + $history = $pager->sliceResults($history); 131 + 132 + $history_exception = null; 133 + } catch (Exception $ex) { 134 + $history_results = null; 135 + $history = null; 136 + $history_exception = $ex; 137 + } 138 + 139 + if ($history_results) { 140 + $content[] = $this->buildCompareProperties($drequest, $history_results); 141 + } 142 + $content[] = $this->buildCompareForm( 143 + $request, 144 + array($head_ref => true, $against_ref => true)); 145 + 146 + $content[] = $this->buildHistoryTable( 147 + $history_results, 148 + $history, 149 + $pager, 150 + $history_exception); 151 + 152 + $content[] = $this->renderTablePagerBox($pager); 153 + 154 + return $content; 155 + } 156 + 157 + private function buildCompareProperties($drequest, array $history_results) { 158 + $viewer = $this->getViewer(); 159 + 160 + $request = $this->getRequest(); 161 + $repository = $drequest->getRepository(); 162 + 163 + $head_ref = $request->getStr('head'); 164 + $against_ref = $request->getStr('against'); 165 + 166 + $reverse_uri = $repository->getPathURI( 167 + "compare/?head=${against_ref}&against=${head_ref}"); 168 + $actions = id(new PhabricatorActionListView()); 169 + $actions->setUser($viewer); 170 + 171 + 172 + $actions->addAction(id(new PhabricatorActionView()) 173 + ->setName(pht('Reverse Comparison')) 174 + ->setHref($reverse_uri) 175 + ->setIcon('fa-list')); 176 + 177 + $view = id(new PHUIPropertyListView()) 178 + ->setUser($viewer) 179 + ->setActionList($actions); 180 + 181 + $readme = 182 + 'These are the commits that are reachable from **Head** commit and not '. 183 + 'from the **Against** commit.'; 184 + $readme = new PHUIRemarkupView($viewer, $readme); 185 + $view->addTextContent($readme); 186 + 187 + $view->addProperty(pht('Head'), $head_ref); 188 + $view->addProperty(pht('Against'), $against_ref); 189 + 190 + $header = id(new PHUIHeaderView()) 191 + ->setUser($viewer) 192 + ->setPolicyObject($drequest->getRepository()); 193 + 194 + $box = id(new PHUIObjectBoxView()) 195 + ->setUser($viewer) 196 + ->setHeader($header) 197 + ->addPropertyList($view); 198 + return $box; 199 + } 200 + 201 + private function buildHistoryTable( 202 + $history_results, 203 + $history, 204 + $pager, 205 + $history_exception) { 206 + 207 + $request = $this->getRequest(); 208 + $viewer = $request->getUser(); 209 + $drequest = $this->getDiffusionRequest(); 210 + $repository = $drequest->getRepository(); 211 + 212 + if ($history_exception) { 213 + if ($repository->isImporting()) { 214 + return $this->renderStatusMessage( 215 + pht('Still Importing...'), 216 + pht( 217 + 'This repository is still importing. History is not yet '. 218 + 'available.')); 219 + } else { 220 + return $this->renderStatusMessage( 221 + pht('Unable to Retrieve History'), 222 + $history_exception->getMessage()); 223 + } 224 + } 225 + 226 + if (!$history) { 227 + return $this->renderStatusMessage( 228 + pht('Up to date'), 229 + new PHUIRemarkupView( 230 + $viewer, 231 + pht( 232 + '**Against** is strictly ahead of **Head** '. 233 + '- no commits are missing.'))); 234 + } 235 + 236 + $history_table = id(new DiffusionHistoryTableView()) 237 + ->setUser($viewer) 238 + ->setDiffusionRequest($drequest) 239 + ->setHistory($history); 240 + 241 + // TODO: Super sketchy? 242 + $history_table->loadRevisions(); 243 + 244 + if ($history_results) { 245 + $history_table->setParents($history_results['parents']); 246 + $history_table->setIsHead(!$pager->getOffset()); 247 + $history_table->setIsTail(!$pager->getHasMorePages()); 248 + } 249 + 250 + // TODO also expose diff. 251 + 252 + $panel = new PHUIObjectBoxView(); 253 + $header = id(new PHUIHeaderView()) 254 + ->setHeader(pht('Missing Commits')); 255 + $panel->setHeader($header); 256 + $panel->setTable($history_table); 257 + 258 + return $panel; 259 + } 260 + }
+3
src/applications/diffusion/controller/DiffusionController.php
··· 213 213 case 'change': 214 214 $view_name = pht('Change'); 215 215 break; 216 + case 'compare': 217 + $view_name = pht('Compare'); 218 + break; 216 219 } 217 220 218 221 $crumb = id(new PHUICrumbView())