1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-27 01:02:42 +01:00

Show merged changes in commit views for merges

Summary:
When a commit is a merge, show what it merged.

Also fix some bugs:

  - Mercurial queries may contain ":", but mercurial rev ranges may also contain ":". A rev range with a branch that has a ":" in it is ambigiuous, e.g. branch "a:b" might appear in a rev range like "a🅱️0", which can not be parsed. Use stable commit names instead.
  - Mercurial stable commit name implementation was broken, fix it.
  - Extend DiffusionHistoryQuery from DiffusionQuery to share code.
  - Fix a bug where Mercurial's main browse list would not show the most recent commit if it was a merge commit.

Test Plan: Generated a bunch of mercurial/git merge commits and looked at them, they seemed to accurately represent the repository state.

Reviewers: btrahan, Makinde

Reviewed By: btrahan

CC: aran, epriestley

Maniphest Tasks: T961

Differential Revision: https://secure.phabricator.com/D2005
This commit is contained in:
epriestley 2012-03-23 15:32:26 -07:00
parent 2ee5086ce9
commit d28eb759d6
20 changed files with 409 additions and 136 deletions

View file

@ -306,6 +306,7 @@ phutil_register_library_map(array(
'DiffusionGitFileContentQuery' => 'applications/diffusion/query/filecontent/git', 'DiffusionGitFileContentQuery' => 'applications/diffusion/query/filecontent/git',
'DiffusionGitHistoryQuery' => 'applications/diffusion/query/history/git', 'DiffusionGitHistoryQuery' => 'applications/diffusion/query/history/git',
'DiffusionGitLastModifiedQuery' => 'applications/diffusion/query/lastmodified/git', 'DiffusionGitLastModifiedQuery' => 'applications/diffusion/query/lastmodified/git',
'DiffusionGitMergedCommitsQuery' => 'applications/diffusion/query/mergedcommits/git',
'DiffusionGitRequest' => 'applications/diffusion/request/git', 'DiffusionGitRequest' => 'applications/diffusion/request/git',
'DiffusionHistoryController' => 'applications/diffusion/controller/history', 'DiffusionHistoryController' => 'applications/diffusion/controller/history',
'DiffusionHistoryQuery' => 'applications/diffusion/query/history/base', 'DiffusionHistoryQuery' => 'applications/diffusion/query/history/base',
@ -321,7 +322,9 @@ phutil_register_library_map(array(
'DiffusionMercurialFileContentQuery' => 'applications/diffusion/query/filecontent/mercurial', 'DiffusionMercurialFileContentQuery' => 'applications/diffusion/query/filecontent/mercurial',
'DiffusionMercurialHistoryQuery' => 'applications/diffusion/query/history/mercurial', 'DiffusionMercurialHistoryQuery' => 'applications/diffusion/query/history/mercurial',
'DiffusionMercurialLastModifiedQuery' => 'applications/diffusion/query/lastmodified/mercurial', 'DiffusionMercurialLastModifiedQuery' => 'applications/diffusion/query/lastmodified/mercurial',
'DiffusionMercurialMergedCommitsQuery' => 'applications/diffusion/query/mergedcommits/mercurial',
'DiffusionMercurialRequest' => 'applications/diffusion/request/mercurial', 'DiffusionMercurialRequest' => 'applications/diffusion/request/mercurial',
'DiffusionMergedCommitsQuery' => 'applications/diffusion/query/mergedcommits/base',
'DiffusionPathChange' => 'applications/diffusion/data/pathchange', 'DiffusionPathChange' => 'applications/diffusion/data/pathchange',
'DiffusionPathChangeQuery' => 'applications/diffusion/query/pathchange/base', 'DiffusionPathChangeQuery' => 'applications/diffusion/query/pathchange/base',
'DiffusionPathCompleteController' => 'applications/diffusion/controller/pathcomplete', 'DiffusionPathCompleteController' => 'applications/diffusion/controller/pathcomplete',
@ -339,6 +342,7 @@ phutil_register_library_map(array(
'DiffusionSvnFileContentQuery' => 'applications/diffusion/query/filecontent/svn', 'DiffusionSvnFileContentQuery' => 'applications/diffusion/query/filecontent/svn',
'DiffusionSvnHistoryQuery' => 'applications/diffusion/query/history/svn', 'DiffusionSvnHistoryQuery' => 'applications/diffusion/query/history/svn',
'DiffusionSvnLastModifiedQuery' => 'applications/diffusion/query/lastmodified/svn', 'DiffusionSvnLastModifiedQuery' => 'applications/diffusion/query/lastmodified/svn',
'DiffusionSvnMergedCommitsQuery' => 'applications/diffusion/query/mergedcommits/svn',
'DiffusionSvnRequest' => 'applications/diffusion/request/svn', 'DiffusionSvnRequest' => 'applications/diffusion/request/svn',
'DiffusionSymbolController' => 'applications/diffusion/controller/symbol', 'DiffusionSymbolController' => 'applications/diffusion/controller/symbol',
'DiffusionSymbolQuery' => 'applications/diffusion/query/symbol', 'DiffusionSymbolQuery' => 'applications/diffusion/query/symbol',
@ -1166,8 +1170,10 @@ phutil_register_library_map(array(
'DiffusionGitFileContentQuery' => 'DiffusionFileContentQuery', 'DiffusionGitFileContentQuery' => 'DiffusionFileContentQuery',
'DiffusionGitHistoryQuery' => 'DiffusionHistoryQuery', 'DiffusionGitHistoryQuery' => 'DiffusionHistoryQuery',
'DiffusionGitLastModifiedQuery' => 'DiffusionLastModifiedQuery', 'DiffusionGitLastModifiedQuery' => 'DiffusionLastModifiedQuery',
'DiffusionGitMergedCommitsQuery' => 'DiffusionMergedCommitsQuery',
'DiffusionGitRequest' => 'DiffusionRequest', 'DiffusionGitRequest' => 'DiffusionRequest',
'DiffusionHistoryController' => 'DiffusionController', 'DiffusionHistoryController' => 'DiffusionController',
'DiffusionHistoryQuery' => 'DiffusionQuery',
'DiffusionHistoryTableView' => 'DiffusionView', 'DiffusionHistoryTableView' => 'DiffusionView',
'DiffusionHomeController' => 'DiffusionController', 'DiffusionHomeController' => 'DiffusionController',
'DiffusionInlineCommentController' => 'PhabricatorInlineCommentController', 'DiffusionInlineCommentController' => 'PhabricatorInlineCommentController',
@ -1179,7 +1185,9 @@ phutil_register_library_map(array(
'DiffusionMercurialFileContentQuery' => 'DiffusionFileContentQuery', 'DiffusionMercurialFileContentQuery' => 'DiffusionFileContentQuery',
'DiffusionMercurialHistoryQuery' => 'DiffusionHistoryQuery', 'DiffusionMercurialHistoryQuery' => 'DiffusionHistoryQuery',
'DiffusionMercurialLastModifiedQuery' => 'DiffusionLastModifiedQuery', 'DiffusionMercurialLastModifiedQuery' => 'DiffusionLastModifiedQuery',
'DiffusionMercurialMergedCommitsQuery' => 'DiffusionMergedCommitsQuery',
'DiffusionMercurialRequest' => 'DiffusionRequest', 'DiffusionMercurialRequest' => 'DiffusionRequest',
'DiffusionMergedCommitsQuery' => 'DiffusionQuery',
'DiffusionPathCompleteController' => 'DiffusionController', 'DiffusionPathCompleteController' => 'DiffusionController',
'DiffusionPathQueryTestCase' => 'PhabricatorTestCase', 'DiffusionPathQueryTestCase' => 'PhabricatorTestCase',
'DiffusionPathValidateController' => 'DiffusionController', 'DiffusionPathValidateController' => 'DiffusionController',
@ -1190,6 +1198,7 @@ phutil_register_library_map(array(
'DiffusionSvnFileContentQuery' => 'DiffusionFileContentQuery', 'DiffusionSvnFileContentQuery' => 'DiffusionFileContentQuery',
'DiffusionSvnHistoryQuery' => 'DiffusionHistoryQuery', 'DiffusionSvnHistoryQuery' => 'DiffusionHistoryQuery',
'DiffusionSvnLastModifiedQuery' => 'DiffusionLastModifiedQuery', 'DiffusionSvnLastModifiedQuery' => 'DiffusionLastModifiedQuery',
'DiffusionSvnMergedCommitsQuery' => 'DiffusionMergedCommitsQuery',
'DiffusionSvnRequest' => 'DiffusionRequest', 'DiffusionSvnRequest' => 'DiffusionRequest',
'DiffusionSymbolController' => 'DiffusionController', 'DiffusionSymbolController' => 'DiffusionController',
'DiffusionURITestCase' => 'ArcanistPhutilTestCase', 'DiffusionURITestCase' => 'ArcanistPhutilTestCase',

View file

@ -100,6 +100,8 @@ final class DiffusionCommitController extends DiffusionController {
$drequest); $drequest);
$changes = $change_query->loadChanges(); $changes = $change_query->loadChanges();
$content[] = $this->buildMergesTable($commit);
$original_changes_count = count($changes); $original_changes_count = count($changes);
if ($request->getStr('show_all') !== 'true' && if ($request->getStr('show_all') !== 'true' &&
$original_changes_count > self::CHANGES_LIMIT) { $original_changes_count > self::CHANGES_LIMIT) {
@ -464,4 +466,43 @@ final class DiffusionCommitController extends DiffusionController {
return $view; return $view;
} }
private function buildMergesTable(PhabricatorRepositoryCommit $commit) {
$drequest = $this->getDiffusionRequest();
$limit = 50;
$merge_query = DiffusionMergedCommitsQuery::newFromDiffusionRequest(
$drequest);
$merge_query->setLimit($limit + 1);
$merges = $merge_query->loadMergedCommits();
if (!$merges) {
return null;
}
$caption = null;
if (count($merges) > $limit) {
$merges = array_slice($merges, 0, $limit);
$caption =
"This commit merges more than {$limit} changes. Only the first ".
"{$limit} are shown.";
}
$history_table = new DiffusionHistoryTableView();
$history_table->setDiffusionRequest($drequest);
$history_table->setHistory($merges);
$phids = $history_table->getRequiredHandlePHIDs();
$handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
$history_table->setHandles($handles);
$panel = new AphrontPanelView();
$panel->setHeader('Merged Changes');
$panel->setCaption($caption);
$panel->appendChild($history_table);
return $panel;
}
} }

View file

@ -18,12 +18,14 @@ phutil_require_module('phabricator', 'applications/differential/view/changesetli
phutil_require_module('phabricator', 'applications/diffusion/controller/base'); phutil_require_module('phabricator', 'applications/diffusion/controller/base');
phutil_require_module('phabricator', 'applications/diffusion/data/pathchange'); phutil_require_module('phabricator', 'applications/diffusion/data/pathchange');
phutil_require_module('phabricator', 'applications/diffusion/query/contains/base'); phutil_require_module('phabricator', 'applications/diffusion/query/contains/base');
phutil_require_module('phabricator', 'applications/diffusion/query/mergedcommits/base');
phutil_require_module('phabricator', 'applications/diffusion/query/path'); phutil_require_module('phabricator', 'applications/diffusion/query/path');
phutil_require_module('phabricator', 'applications/diffusion/query/pathchange/base'); phutil_require_module('phabricator', 'applications/diffusion/query/pathchange/base');
phutil_require_module('phabricator', 'applications/diffusion/query/pathid/base'); phutil_require_module('phabricator', 'applications/diffusion/query/pathid/base');
phutil_require_module('phabricator', 'applications/diffusion/request/base'); phutil_require_module('phabricator', 'applications/diffusion/request/base');
phutil_require_module('phabricator', 'applications/diffusion/view/commentlist'); phutil_require_module('phabricator', 'applications/diffusion/view/commentlist');
phutil_require_module('phabricator', 'applications/diffusion/view/commitchangetable'); phutil_require_module('phabricator', 'applications/diffusion/view/commitchangetable');
phutil_require_module('phabricator', 'applications/diffusion/view/historytable');
phutil_require_module('phabricator', 'applications/draft/storage/draft'); phutil_require_module('phabricator', 'applications/draft/storage/draft');
phutil_require_module('phabricator', 'applications/markup/engine'); phutil_require_module('phabricator', 'applications/markup/engine');
phutil_require_module('phabricator', 'applications/phid/handle/data'); phutil_require_module('phabricator', 'applications/phid/handle/data');

View file

@ -37,18 +37,6 @@ final class DiffusionHistoryController extends DiffusionController {
$history = $history_query->loadHistory(); $history = $history_query->loadHistory();
$phids = array();
foreach ($history as $item) {
$data = $item->getCommitData();
if ($data) {
if ($data->getCommitDetail('authorPHID')) {
$phids[$data->getCommitDetail('authorPHID')] = true;
}
}
}
$phids = array_keys($phids);
$handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
$pager = new AphrontPagerView(); $pager = new AphrontPagerView();
$pager->setPageSize($page_size); $pager->setPageSize($page_size);
$pager->setOffset($offset); $pager->setOffset($offset);
@ -87,9 +75,12 @@ final class DiffusionHistoryController extends DiffusionController {
$history_table = new DiffusionHistoryTableView(); $history_table = new DiffusionHistoryTableView();
$history_table->setDiffusionRequest($drequest); $history_table->setDiffusionRequest($drequest);
$history_table->setHandles($handles);
$history_table->setHistory($history); $history_table->setHistory($history);
$phids = $history_table->getRequiredHandlePHIDs();
$handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
$history_table->setHandles($handles);
$history_panel = new AphrontPanelView(); $history_panel = new AphrontPanelView();
$history_panel->setHeader('History'); $history_panel->setHeader('History');
$history_panel->addButton($button); $history_panel->addButton($button);

View file

@ -53,4 +53,79 @@ abstract class DiffusionQuery {
} }
abstract protected function executeQuery(); abstract protected function executeQuery();
/* -( Query Utilities )---------------------------------------------------- */
final protected function loadHistoryForCommitIdentifiers(array $identifiers) {
if (!$identifiers) {
return array();
}
$commits = array();
$commit_data = array();
$path_changes = array();
$drequest = $this->getRequest();
$repository = $drequest->getRepository();
$path = $drequest->getPath();
$commits = id(new PhabricatorRepositoryCommit())->loadAllWhere(
'repositoryID = %d AND commitIdentifier IN (%Ls)',
$repository->getID(),
$identifiers);
$commits = mpull($commits, null, 'getCommitIdentifier');
if (!$commits) {
return array();
}
$commit_data = id(new PhabricatorRepositoryCommitData())->loadAllWhere(
'commitID in (%Ld)',
mpull($commits, 'getID'));
$commit_data = mpull($commit_data, null, 'getCommitID');
$conn_r = $repository->establishConnection('r');
$path_normal = DiffusionPathIDQuery::normalizePath($path);
$paths = queryfx_all(
$conn_r,
'SELECT id, path FROM %T WHERE pathHash IN (%Ls)',
PhabricatorRepository::TABLE_PATH,
array(md5($path_normal)));
$paths = ipull($paths, 'id', 'path');
$path_id = idx($paths, $path_normal);
$path_changes = queryfx_all(
$conn_r,
'SELECT * FROM %T WHERE commitID IN (%Ld) AND pathID = %d',
PhabricatorRepository::TABLE_PATHCHANGE,
mpull($commits, 'getID'),
$path_id);
$path_changes = ipull($path_changes, null, 'commitID');
$history = array();
foreach ($identifiers as $identifier) {
$item = new DiffusionPathChange();
$item->setCommitIdentifier($identifier);
$commit = idx($commits, $identifier);
if ($commit) {
$item->setCommit($commit);
$data = idx($commit_data, $commit->getID());
if ($data) {
$item->setCommitData($data);
}
$change = idx($path_changes, $commit->getID());
if ($change) {
$item->setChangeType($change['changeType']);
$item->setFileType($change['fileType']);
}
}
$history[] = $item;
}
return $history;
}
} }

View file

@ -6,7 +6,13 @@
phutil_require_module('phabricator', 'applications/diffusion/data/pathchange');
phutil_require_module('phabricator', 'applications/diffusion/query/pathid/base');
phutil_require_module('phabricator', 'applications/repository/constants/repositorytype'); phutil_require_module('phabricator', 'applications/repository/constants/repositorytype');
phutil_require_module('phabricator', 'applications/repository/storage/commit');
phutil_require_module('phabricator', 'applications/repository/storage/commitdata');
phutil_require_module('phabricator', 'applications/repository/storage/repository');
phutil_require_module('phabricator', 'storage/queryfx');
phutil_require_module('phutil', 'utils'); phutil_require_module('phutil', 'utils');

View file

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Copyright 2011 Facebook, Inc. * Copyright 2012 Facebook, Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -23,7 +23,7 @@ final class DiffusionMercurialBrowseQuery extends DiffusionBrowseQuery {
$repository = $drequest->getRepository(); $repository = $drequest->getRepository();
$path = $drequest->getPath(); $path = $drequest->getPath();
$commit = $drequest->getCommit(); $commit = $drequest->getStableCommitName();
// TODO: This is a really really awful mess but Mercurial doesn't offer // TODO: This is a really really awful mess but Mercurial doesn't offer
// an equivalent of "git ls-files -- directory". If it's any comfort, this // an equivalent of "git ls-files -- directory". If it's any comfort, this

View file

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Copyright 2011 Facebook, Inc. * Copyright 2012 Facebook, Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,44 +16,18 @@
* limitations under the License. * limitations under the License.
*/ */
abstract class DiffusionHistoryQuery { abstract class DiffusionHistoryQuery extends DiffusionQuery {
private $request;
private $limit = 100; private $limit = 100;
private $offset = 0; private $offset = 0;
protected $needDirectChanges; protected $needDirectChanges;
protected $needChildChanges; protected $needChildChanges;
final private function __construct() {
// <private>
}
final public static function newFromDiffusionRequest( final public static function newFromDiffusionRequest(
DiffusionRequest $request) { DiffusionRequest $request) {
$repository = $request->getRepository(); return parent::newQueryObject(__CLASS__, $request);
switch ($repository->getVersionControlSystem()) {
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
$class = 'DiffusionGitHistoryQuery';
break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
$class = 'DiffusionSvnHistoryQuery';
break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
$class = 'DiffusionMercurialHistoryQuery';
break;
default:
throw new Exception("Unsupported VCS!");
}
PhutilSymbolLoader::loadClass($class);
$query = new $class();
$query->request = $request;
return $query;
} }
final public function needDirectChanges($direct) { final public function needDirectChanges($direct) {
@ -66,10 +40,6 @@ abstract class DiffusionHistoryQuery {
return $this; return $this;
} }
final protected function getRequest() {
return $this->request;
}
final public function loadHistory() { final public function loadHistory() {
return $this->executeQuery(); return $this->executeQuery();
} }
@ -92,77 +62,4 @@ abstract class DiffusionHistoryQuery {
return $this->offset; return $this->offset;
} }
abstract protected function executeQuery();
final protected function loadHistoryForCommitIdentifiers(array $identifiers) {
if (!$identifiers) {
return array();
}
$commits = array();
$commit_data = array();
$path_changes = array();
$drequest = $this->getRequest();
$repository = $drequest->getRepository();
$path = $drequest->getPath();
$commits = id(new PhabricatorRepositoryCommit())->loadAllWhere(
'repositoryID = %d AND commitIdentifier IN (%Ls)',
$repository->getID(),
$identifiers);
$commits = mpull($commits, null, 'getCommitIdentifier');
if (!$commits) {
return array();
}
$commit_data = id(new PhabricatorRepositoryCommitData())->loadAllWhere(
'commitID in (%Ld)',
mpull($commits, 'getID'));
$commit_data = mpull($commit_data, null, 'getCommitID');
$conn_r = $repository->establishConnection('r');
$path_normal = DiffusionPathIDQuery::normalizePath($path);
$paths = queryfx_all(
$conn_r,
'SELECT id, path FROM %T WHERE pathHash IN (%Ls)',
PhabricatorRepository::TABLE_PATH,
array(md5($path_normal)));
$paths = ipull($paths, 'id', 'path');
$path_id = idx($paths, $path_normal);
$path_changes = queryfx_all(
$conn_r,
'SELECT * FROM %T WHERE commitID IN (%Ld) AND pathID = %d',
PhabricatorRepository::TABLE_PATHCHANGE,
mpull($commits, 'getID'),
$path_id);
$path_changes = ipull($path_changes, null, 'commitID');
$history = array();
foreach ($identifiers as $identifier) {
$item = new DiffusionPathChange();
$item->setCommitIdentifier($identifier);
$commit = idx($commits, $identifier);
if ($commit) {
$item->setCommit($commit);
$data = idx($commit_data, $commit->getID());
if ($data) {
$item->setCommitData($data);
}
$change = idx($path_changes, $commit->getID());
if ($change) {
$item->setChangeType($change['changeType']);
$item->setFileType($change['fileType']);
}
}
$history[] = $item;
}
return $history;
}
} }

View file

@ -6,16 +6,7 @@
phutil_require_module('phabricator', 'applications/diffusion/data/pathchange'); phutil_require_module('phabricator', 'applications/diffusion/query/base');
phutil_require_module('phabricator', 'applications/diffusion/query/pathid/base');
phutil_require_module('phabricator', 'applications/repository/constants/repositorytype');
phutil_require_module('phabricator', 'applications/repository/storage/commit');
phutil_require_module('phabricator', 'applications/repository/storage/commitdata');
phutil_require_module('phabricator', 'applications/repository/storage/repository');
phutil_require_module('phabricator', 'storage/queryfx');
phutil_require_module('phutil', 'symbols');
phutil_require_module('phutil', 'utils');
phutil_require_source('DiffusionHistoryQuery.php'); phutil_require_source('DiffusionHistoryQuery.php');

View file

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Copyright 2011 Facebook, Inc. * Copyright 2012 Facebook, Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -23,17 +23,22 @@ final class DiffusionMercurialHistoryQuery extends DiffusionHistoryQuery {
$repository = $drequest->getRepository(); $repository = $drequest->getRepository();
$path = $drequest->getPath(); $path = $drequest->getPath();
$commit_hash = $drequest->getCommit(); $commit_hash = $drequest->getStableCommitName();
$path = DiffusionPathIDQuery::normalizePath($path); $path = DiffusionPathIDQuery::normalizePath($path);
// NOTE: Using '' as a default path produces the correct behavior if HEAD
// is a merge commit; using '.' does not (the merge commit is not included
// in the log).
$default_path = '';
list($stdout) = $repository->execxLocalCommand( list($stdout) = $repository->execxLocalCommand(
'log --template %s --limit %d --branch %s --rev %s:0 -- %s', 'log --template %s --limit %d --branch %s --rev %s:0 -- %s',
'{node}\\n', '{node}\\n',
($this->getOffset() + $this->getLimit()), // No '--skip' in Mercurial. ($this->getOffset() + $this->getLimit()), // No '--skip' in Mercurial.
$drequest->getBranch(), $drequest->getBranch(),
$commit_hash, $commit_hash,
nonempty(ltrim($path, '/'), '.')); nonempty(ltrim($path, '/'), $default_path));
$hashes = explode("\n", $stdout); $hashes = explode("\n", $stdout);
$hashes = array_filter($hashes); $hashes = array_filter($hashes);

View file

@ -0,0 +1,42 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
abstract class DiffusionMergedCommitsQuery extends DiffusionQuery {
private $limit = PHP_INT_MAX;
final public static function newFromDiffusionRequest(
DiffusionRequest $request) {
return self::newQueryObject(__CLASS__, $request);
}
final public function loadMergedCommits() {
return $this->executeQuery();
}
final public function setLimit($limit) {
$this->limit = $limit;
return $this;
}
final public function getLimit() {
return $this->limit;
}
}

View file

@ -0,0 +1,12 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/diffusion/query/base');
phutil_require_source('DiffusionMergedCommitsQuery.php');

View file

@ -0,0 +1,55 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
final class DiffusionGitMergedCommitsQuery extends DiffusionMergedCommitsQuery {
protected function executeQuery() {
$request = $this->getRequest();
$repository = $request->getRepository();
list($parents) = $repository->execxLocalCommand(
'log -n 1 --format=%s %s',
'%P',
$request->getCommit());
$parents = preg_split('/\s+/', trim($parents));
if (count($parents) < 2) {
// This is not a merge commit, so it doesn't merge anything.
return array();
}
// Get all of the commits which are not reachable from the first parent.
// These are the commits this change merges.
$first_parent = head($parents);
list($logs) = $repository->execxLocalCommand(
'log -n %d --format=%s %s %s --',
// NOTE: "+ 1" accounts for the merge commit itself.
$this->getLimit() + 1,
'%H',
$request->getCommit(),
'^'.$first_parent);
$hashes = explode("\n", trim($logs));
// Remove the merge commit.
$hashes = array_diff($hashes, array($request->getCommit()));
return $this->loadHistoryForCommitIdentifiers($hashes);
}
}

View file

@ -0,0 +1,14 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/diffusion/query/mergedcommits/base');
phutil_require_module('phutil', 'utils');
phutil_require_source('DiffusionGitMergedCommitsQuery.php');

View file

@ -0,0 +1,57 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
final class DiffusionMercurialMergedCommitsQuery
extends DiffusionMergedCommitsQuery {
protected function executeQuery() {
$request = $this->getRequest();
$repository = $request->getRepository();
list($parents) = $repository->execxLocalCommand(
'parents --template=%s --rev %s',
'{node}\\n',
$request->getCommit());
$parents = explode("\n", trim($parents));
if (count($parents) < 2) {
// Not a merge commit.
return array();
}
// NOTE: In Git, the first parent is the "mainline". In Mercurial, the
// second parent is the "mainline" (the way 'git merge' and 'hg merge'
// work is also reversed).
$last_parent = last($parents);
list($logs) = $repository->execxLocalCommand(
'log --template=%s --follow --limit %d --rev %s:0 --prune %s --',
'{node}\\n',
$this->getLimit() + 1,
$request->getCommit(),
$last_parent);
$hashes = explode("\n", trim($logs));
// Remove the merge commit.
$hashes = array_diff($hashes, array($request->getCommit()));
return $this->loadHistoryForCommitIdentifiers($hashes);
}
}

View file

@ -0,0 +1,14 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/diffusion/query/mergedcommits/base');
phutil_require_module('phutil', 'utils');
phutil_require_source('DiffusionMercurialMergedCommitsQuery.php');

View file

@ -0,0 +1,27 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
final class DiffusionSvnMergedCommitsQuery extends DiffusionMergedCommitsQuery {
protected function executeQuery() {
// TODO: It might be possible to do something reasonable in recent versions
// of SVN.
return array();
}
}

View file

@ -0,0 +1,12 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/diffusion/query/mergedcommits/base');
phutil_require_source('DiffusionSvnMergedCommitsQuery.php');

View file

@ -47,7 +47,17 @@ final class DiffusionMercurialRequest extends DiffusionRequest {
} }
public function getStableCommitName() { public function getStableCommitName() {
return substr($this->stableCommitName, 0, 16); if (!$this->stableCommitName) {
if ($this->commit) {
$this->stableCommitName = $this->commit;
} else {
list($this->stableCommitName) = $this->repository->execxLocalCommand(
'log --template=%s --rev %s',
'{node}',
$this->getBranch());
}
}
return $this->stableCommitName;
} }
} }

View file

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Copyright 2011 Facebook, Inc. * Copyright 2012 Facebook, Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -31,6 +31,19 @@ final class DiffusionHistoryTableView extends DiffusionView {
return $this; return $this;
} }
public function getRequiredHandlePHIDs() {
$phids = array();
foreach ($this->history as $item) {
$data = $item->getCommitData();
if ($data) {
if ($data->getCommitDetail('authorPHID')) {
$phids[$data->getCommitDetail('authorPHID')] = true;
}
}
}
return array_keys($phids);
}
public function render() { public function render() {
$drequest = $this->getDiffusionRequest(); $drequest = $this->getDiffusionRequest();