mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-23 07:12:41 +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:
parent
2ee5086ce9
commit
d28eb759d6
20 changed files with 409 additions and 136 deletions
|
@ -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',
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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');
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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');
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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');
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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');
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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');
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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');
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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');
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue