3 final class DiffusionCompareController
extends DiffusionController
{
5 public function shouldAllowPublic() {
9 public function handleRequest(AphrontRequest
$request) {
10 $response = $this->loadDiffusionContext();
15 $viewer = $this->getViewer();
16 $drequest = $this->getDiffusionRequest();
17 $repository = $drequest->getRepository();
18 require_celerity_resource('diffusion-css');
20 if (!$repository->supportsBranchComparison()) {
21 return $this->newDialog()
22 ->setTitle(pht('Not Supported'))
25 'Branch comparison is not supported for this version control '.
27 ->addCancelButton($this->getApplicationURI(), pht('Okay'));
30 $head_ref = $request->getStr('head');
31 $against_ref = $request->getStr('against');
34 if (!$request->isFormPost()) {
35 if (!strlen($head_ref)) {
36 $head_ref = $drequest->getSymbolicCommit();
37 if (!strlen($head_ref)) {
38 $head_ref = $drequest->getBranch();
42 if (!strlen($against_ref)) {
43 $default_branch = $repository->getDefaultBranch();
44 if ($default_branch != $head_ref) {
45 $against_ref = $default_branch;
47 // If we filled this in by default, we want to prompt the user to
48 // confirm that this is really what they want.
54 $refs = $drequest->resolveRefs(
62 if ($head_ref === $against_ref) {
65 if (count($refs) == 2) {
66 if ($refs[$head_ref] === $refs[$against_ref]) {
72 if ($must_prompt ||
count($refs) != 2 ||
$identical) {
73 return $this->buildCompareDialog(
80 if ($request->isFormPost()) {
81 // Redirect to a stable URI that can be copy/pasted.
82 $compare_uri = $drequest->generateURI(
84 'action' => 'compare',
86 'against' => $against_ref,
89 return id(new AphrontRedirectResponse())->setURI($compare_uri);
92 $crumbs = $this->buildCrumbs(
96 $crumbs->setBorder(true);
98 $pager = id(new PHUIPagerView())
99 ->readFromRequest($request);
103 $history_results = $this->callConduitWithDiffusionRequest(
104 'diffusion.historyquery',
106 'commit' => $head_ref,
107 'against' => $against_ref,
108 'path' => $drequest->getPath(),
109 'offset' => $pager->getOffset(),
110 'limit' => $pager->getPageSize() +
1,
112 $history = DiffusionPathChange
::newFromConduit(
113 $history_results['pathChanges']);
114 $history = $pager->sliceResults($history);
116 $history_view = $this->newHistoryView(
123 } catch (Exception
$ex) {
124 if ($repository->isImporting()) {
125 $history_view = $this->renderStatusMessage(
126 pht('Still Importing...'),
128 'This repository is still importing. History is not yet '.
131 $history_view = $this->renderStatusMessage(
132 pht('Unable to Retrieve History'),
137 $header = id(new PHUIHeaderView())
140 'Changes on %s but not %s',
141 phutil_tag('em', array(), $head_ref),
142 phutil_tag('em', array(), $against_ref)));
144 $curtain = $this->buildCurtain($head_ref, $against_ref);
146 $column_view = id(new PHUITwoColumnView())
148 ->setCurtain($curtain)
154 return $this->newPage()
157 $repository->getName(),
158 $repository->getDisplayName(),
161 ->appendChild($column_view);
164 private function buildCompareDialog(
170 $viewer = $this->getViewer();
171 $request = $this->getRequest();
172 $drequest = $this->getDiffusionRequest();
173 $repository = $drequest->getRepository();
178 if ($request->isFormPost()) {
179 if (!strlen($head_ref)) {
180 $e_head = pht('Required');
182 'You must provide two different commits to compare.');
183 } else if (!isset($resolved[$head_ref])) {
184 $e_head = pht('Not Found');
186 'Commit "%s" is not a valid commit in this repository.',
190 if (!strlen($against_ref)) {
191 $e_against = pht('Required');
193 'You must provide two different commits to compare.');
194 } else if (!isset($resolved[$against_ref])) {
195 $e_against = pht('Not Found');
197 'Commit "%s" is not a valid commit in this repository.',
202 $e_head = pht('Identical');
203 $e_against = pht('Identical');
205 'Both references identify the same commit. You can not compare a '.
206 'commit against itself.');
210 $form = id(new AphrontFormView())
213 id(new AphrontFormTextControl())
214 ->setLabel(pht('Head'))
217 ->setValue($head_ref))
219 id(new AphrontFormTextControl())
220 ->setLabel(pht('Against'))
222 ->setError($e_against)
223 ->setValue($against_ref));
225 $cancel_uri = $repository->generateURI(
227 'action' => 'browse',
230 return $this->newDialog()
231 ->setTitle(pht('Compare Against'))
232 ->setWidth(AphrontDialogView
::WIDTH_FORM
)
235 ->addSubmitButton(pht('Compare'))
236 ->addCancelButton($cancel_uri, pht('Cancel'));
239 private function buildCurtain($head_ref, $against_ref) {
240 $viewer = $this->getViewer();
241 $request = $this->getRequest();
242 $drequest = $this->getDiffusionRequest();
243 $repository = $drequest->getRepository();
245 $curtain = $this->newCurtainView(null);
247 $reverse_uri = $drequest->generateURI(
249 'action' => 'compare',
250 'head' => $against_ref,
251 'against' => $head_ref,
255 id(new PhabricatorActionView())
256 ->setName(pht('Reverse Comparison'))
257 ->setHref($reverse_uri)
258 ->setIcon('fa-refresh'));
260 $compare_uri = $drequest->generateURI(
262 'action' => 'compare',
267 id(new PhabricatorActionView())
268 ->setName(pht('Compare Against...'))
269 ->setIcon('fa-code-fork')
271 ->setHref($compare_uri));
273 // TODO: Provide a "Show Diff" action.
278 private function newHistoryView(
281 PHUIPagerView
$pager,
285 $request = $this->getRequest();
286 $viewer = $this->getViewer();
287 $drequest = $this->getDiffusionRequest();
290 return $this->renderStatusMessage(
293 'There are no commits on %s that are not already on %s.',
294 phutil_tag('strong', array(), $head_ref),
295 phutil_tag('strong', array(), $against_ref)));
298 $history_view = id(new DiffusionCommitGraphView())
300 ->setDiffusionRequest($drequest)
301 ->setHistory($history)
302 ->setParents($results['parents'])
303 ->setFilterParents(true)
304 ->setIsHead(!$pager->getOffset())
305 ->setIsTail(!$pager->getHasMorePages());
307 return $history_view;