mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-18 21:02:41 +01:00
Diffusion: rough cut of history view
Summary: Very very rough approximation of history view. I left out all the log parsing stuff for now since we should be able to just look it up in a Repository table and I think that'll be a bit faster, although we can muck around and see. Test Plan: Looked at history of a path Reviewed By: jwilson Reviewers: aran, jwilson CC: epriestley, jwilson Differential Revision: 66
This commit is contained in:
parent
958b00c010
commit
c82cab35e2
19 changed files with 361 additions and 18 deletions
|
@ -151,8 +151,13 @@ phutil_register_library_map(array(
|
||||||
'DiffusionFileContentQuery' => 'applications/diffusion/query/filecontent/base',
|
'DiffusionFileContentQuery' => 'applications/diffusion/query/filecontent/base',
|
||||||
'DiffusionGitBrowseQuery' => 'applications/diffusion/query/browse/git',
|
'DiffusionGitBrowseQuery' => 'applications/diffusion/query/browse/git',
|
||||||
'DiffusionGitFileContentQuery' => 'applications/diffusion/query/filecontent/git',
|
'DiffusionGitFileContentQuery' => 'applications/diffusion/query/filecontent/git',
|
||||||
|
'DiffusionGitHistoryQuery' => 'applications/diffusion/query/history/git',
|
||||||
'DiffusionGitRequest' => 'applications/diffusion/request/git',
|
'DiffusionGitRequest' => 'applications/diffusion/request/git',
|
||||||
|
'DiffusionHistoryController' => 'applications/diffusion/controller/history',
|
||||||
|
'DiffusionHistoryQuery' => 'applications/diffusion/query/history/base',
|
||||||
|
'DiffusionHistoryTableView' => 'applications/diffusion/view/historytable',
|
||||||
'DiffusionHomeController' => 'applications/diffusion/controller/home',
|
'DiffusionHomeController' => 'applications/diffusion/controller/home',
|
||||||
|
'DiffusionPathChange' => 'applications/diffusion/data/pathchange',
|
||||||
'DiffusionRepositoryPath' => 'applications/diffusion/data/repositorypath',
|
'DiffusionRepositoryPath' => 'applications/diffusion/data/repositorypath',
|
||||||
'DiffusionRequest' => 'applications/diffusion/request/base',
|
'DiffusionRequest' => 'applications/diffusion/request/base',
|
||||||
'Javelin' => 'infrastructure/javelin/api',
|
'Javelin' => 'infrastructure/javelin/api',
|
||||||
|
@ -439,7 +444,10 @@ phutil_register_library_map(array(
|
||||||
'DiffusionController' => 'PhabricatorController',
|
'DiffusionController' => 'PhabricatorController',
|
||||||
'DiffusionGitBrowseQuery' => 'DiffusionBrowseQuery',
|
'DiffusionGitBrowseQuery' => 'DiffusionBrowseQuery',
|
||||||
'DiffusionGitFileContentQuery' => 'DiffusionFileContentQuery',
|
'DiffusionGitFileContentQuery' => 'DiffusionFileContentQuery',
|
||||||
|
'DiffusionGitHistoryQuery' => 'DiffusionHistoryQuery',
|
||||||
'DiffusionGitRequest' => 'DiffusionRequest',
|
'DiffusionGitRequest' => 'DiffusionRequest',
|
||||||
|
'DiffusionHistoryController' => 'DiffusionController',
|
||||||
|
'DiffusionHistoryTableView' => 'AphrontView',
|
||||||
'DiffusionHomeController' => 'DiffusionController',
|
'DiffusionHomeController' => 'DiffusionController',
|
||||||
'ManiphestController' => 'PhabricatorController',
|
'ManiphestController' => 'PhabricatorController',
|
||||||
'ManiphestDAO' => 'PhabricatorLiskDAO',
|
'ManiphestDAO' => 'PhabricatorLiskDAO',
|
||||||
|
|
|
@ -185,11 +185,19 @@ class AphrontDefaultApplicationConfiguration
|
||||||
|
|
||||||
'/diffusion/' => array(
|
'/diffusion/' => array(
|
||||||
'$' => 'DiffusionHomeController',
|
'$' => 'DiffusionHomeController',
|
||||||
'(?P<callsign>[A-Z]+)/browse/'.
|
'(?P<callsign>[A-Z]+)' => array(
|
||||||
'(?P<path>.*?)'.
|
'/history/'.
|
||||||
'(?:[;](?P<commit>[a-z0-9]+))?'.
|
'(?P<path>.*?)'.
|
||||||
'(?:[$](?P<line>\d+))?$'
|
'(?:[;](?P<commit>[a-z0-9]+))?'.
|
||||||
=> 'DiffusionBrowseController',
|
'$'
|
||||||
|
=> 'DiffusionHistoryController',
|
||||||
|
'/browse/'.
|
||||||
|
'(?P<path>.*?)'.
|
||||||
|
'(?:[;](?P<commit>[a-z0-9]+))?'.
|
||||||
|
'(?:[$](?P<line>\d+))?'.
|
||||||
|
'$'
|
||||||
|
=> 'DiffusionBrowseController',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
|
@ -18,6 +18,18 @@
|
||||||
|
|
||||||
abstract class DiffusionController extends PhabricatorController {
|
abstract class DiffusionController extends PhabricatorController {
|
||||||
|
|
||||||
|
protected $diffusionRequest;
|
||||||
|
|
||||||
|
public function willProcessRequest(array $data) {
|
||||||
|
$this->diffusionRequest = DiffusionRequest::newFromAphrontRequestDictionary(
|
||||||
|
$data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setDiffusionRequest(DiffusionRequest $request) {
|
||||||
|
$this->diffusionRequest = $request;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function buildStandardPageResponse($view, array $data) {
|
public function buildStandardPageResponse($view, array $data) {
|
||||||
|
|
||||||
$page = $this->buildStandardPageView();
|
$page = $this->buildStandardPageView();
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
phutil_require_module('phabricator', 'aphront/response/webpage');
|
phutil_require_module('phabricator', 'aphront/response/webpage');
|
||||||
phutil_require_module('phabricator', 'applications/base/controller/base');
|
phutil_require_module('phabricator', 'applications/base/controller/base');
|
||||||
|
phutil_require_module('phabricator', 'applications/diffusion/request/base');
|
||||||
|
|
||||||
phutil_require_module('phutil', 'utils');
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
|
@ -18,11 +18,6 @@
|
||||||
|
|
||||||
class DiffusionBrowseController extends DiffusionController {
|
class DiffusionBrowseController extends DiffusionController {
|
||||||
|
|
||||||
public function willProcessRequest(array $data) {
|
|
||||||
$this->diffusionRequest = DiffusionRequest::newFromAphrontRequestDictionary(
|
|
||||||
$data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function processRequest() {
|
public function processRequest() {
|
||||||
$drequest = $this->diffusionRequest;
|
$drequest = $this->diffusionRequest;
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
phutil_require_module('phabricator', 'applications/diffusion/controller/base');
|
phutil_require_module('phabricator', 'applications/diffusion/controller/base');
|
||||||
phutil_require_module('phabricator', 'applications/diffusion/controller/file');
|
phutil_require_module('phabricator', 'applications/diffusion/controller/file');
|
||||||
phutil_require_module('phabricator', 'applications/diffusion/query/browse/base');
|
phutil_require_module('phabricator', 'applications/diffusion/query/browse/base');
|
||||||
phutil_require_module('phabricator', 'applications/diffusion/request/base');
|
|
||||||
phutil_require_module('phabricator', 'applications/diffusion/view/browsetable');
|
phutil_require_module('phabricator', 'applications/diffusion/view/browsetable');
|
||||||
phutil_require_module('phabricator', 'view/form/error');
|
phutil_require_module('phabricator', 'view/form/error');
|
||||||
phutil_require_module('phabricator', 'view/layout/panel');
|
phutil_require_module('phabricator', 'view/layout/panel');
|
||||||
|
|
|
@ -18,13 +18,6 @@
|
||||||
|
|
||||||
class DiffusionBrowseFileController extends DiffusionController {
|
class DiffusionBrowseFileController extends DiffusionController {
|
||||||
|
|
||||||
private $diffusionRequest;
|
|
||||||
|
|
||||||
public function setDiffusionRequest(DiffusionRequest $request) {
|
|
||||||
$this->diffusionRequest = $request;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function processRequest() {
|
public function processRequest() {
|
||||||
$file_query = DiffusionFileContentQuery::newFromDiffusionRequest(
|
$file_query = DiffusionFileContentQuery::newFromDiffusionRequest(
|
||||||
$this->diffusionRequest);
|
$this->diffusionRequest);
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class DiffusionHistoryController extends DiffusionController {
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
$drequest = $this->diffusionRequest;
|
||||||
|
|
||||||
|
$history_query = DiffusionHistoryQuery::newFromDiffusionRequest(
|
||||||
|
$drequest);
|
||||||
|
|
||||||
|
$history = $history_query->loadHistory();
|
||||||
|
|
||||||
|
$content = array();
|
||||||
|
|
||||||
|
$history_table = new DiffusionHistoryTableView();
|
||||||
|
$history_table->setDiffusionRequest($drequest);
|
||||||
|
$history_table->setHistory($history);
|
||||||
|
|
||||||
|
$history_panel = new AphrontPanelView();
|
||||||
|
$history_panel->setHeader($drequest->getPath());
|
||||||
|
$history_panel->appendChild($history_table);
|
||||||
|
|
||||||
|
$content[] = $history_panel;
|
||||||
|
|
||||||
|
// TODO: Crumbs
|
||||||
|
// TODO: Side nav
|
||||||
|
|
||||||
|
return $this->buildStandardPageResponse(
|
||||||
|
$content,
|
||||||
|
array(
|
||||||
|
'title' => 'history',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
15
src/applications/diffusion/controller/history/__init__.php
Normal file
15
src/applications/diffusion/controller/history/__init__.php
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/diffusion/controller/base');
|
||||||
|
phutil_require_module('phabricator', 'applications/diffusion/query/history/base');
|
||||||
|
phutil_require_module('phabricator', 'applications/diffusion/view/historytable');
|
||||||
|
phutil_require_module('phabricator', 'view/layout/panel');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('DiffusionHistoryController.php');
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 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 DiffusionPathChange {
|
||||||
|
|
||||||
|
private $commit;
|
||||||
|
|
||||||
|
final public function setCommit($commit) {
|
||||||
|
$this->commit = $commit;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function getCommit() {
|
||||||
|
return $this->commit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
10
src/applications/diffusion/data/pathchange/__init__.php
Normal file
10
src/applications/diffusion/data/pathchange/__init__.php
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('DiffusionPathChange.php');
|
|
@ -0,0 +1,57 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 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 DiffusionHistoryQuery {
|
||||||
|
|
||||||
|
private $request;
|
||||||
|
|
||||||
|
final private function __construct() {
|
||||||
|
// <private>
|
||||||
|
}
|
||||||
|
|
||||||
|
final public static function newFromDiffusionRequest(
|
||||||
|
DiffusionRequest $request) {
|
||||||
|
|
||||||
|
$repository = $request->getRepository();
|
||||||
|
|
||||||
|
switch ($repository->getVersionControlSystem()) {
|
||||||
|
case 'git':
|
||||||
|
$class = 'DiffusionGitHistoryQuery';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Unsupported VCS!");
|
||||||
|
}
|
||||||
|
|
||||||
|
PhutilSymbolLoader::loadClass($class);
|
||||||
|
$query = new $class();
|
||||||
|
|
||||||
|
$query->request = $request;
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
final protected function getRequest() {
|
||||||
|
return $this->request;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function loadHistory() {
|
||||||
|
return $this->executeQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract protected function executeQuery();
|
||||||
|
}
|
12
src/applications/diffusion/query/history/base/__init__.php
Normal file
12
src/applications/diffusion/query/history/base/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'symbols');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('DiffusionHistoryQuery.php');
|
|
@ -0,0 +1,66 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 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 DiffusionGitHistoryQuery extends DiffusionHistoryQuery {
|
||||||
|
|
||||||
|
protected function executeQuery() {
|
||||||
|
$drequest = $this->getRequest();
|
||||||
|
|
||||||
|
$repository = $drequest->getRepository();
|
||||||
|
$path = $drequest->getPath();
|
||||||
|
$commit = $drequest->getCommit();
|
||||||
|
|
||||||
|
$local_path = $repository->getDetail('local-path');
|
||||||
|
$git = $drequest->getPathToGitBinary();
|
||||||
|
|
||||||
|
list($stdout) = execx(
|
||||||
|
'(cd %s && %s log '.
|
||||||
|
'-n %d '.
|
||||||
|
'--skip=%d '.
|
||||||
|
'-M '.
|
||||||
|
'-C '.
|
||||||
|
'-B '.
|
||||||
|
'--find-copies-harder '.
|
||||||
|
'--raw '.
|
||||||
|
'-t '.
|
||||||
|
'--abbrev=40 '.
|
||||||
|
'--pretty=format:%%x1c%%H%%x1d '.
|
||||||
|
'%s -- %s)',
|
||||||
|
$local_path,
|
||||||
|
$git,
|
||||||
|
$limit = 100,
|
||||||
|
$offset = 0,
|
||||||
|
$commit,
|
||||||
|
$path);
|
||||||
|
|
||||||
|
$commits = explode("\x1c", $stdout);
|
||||||
|
array_shift($commits); // \x1c character is first, remove empty record
|
||||||
|
|
||||||
|
$history = array();
|
||||||
|
foreach ($commits as $commit) {
|
||||||
|
list($hash, $raw) = explode("\x1d", $commit);
|
||||||
|
|
||||||
|
$item = new DiffusionPathChange();
|
||||||
|
$item->setCommit($hash);
|
||||||
|
$history[] = $item;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $history;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
15
src/applications/diffusion/query/history/git/__init__.php
Normal file
15
src/applications/diffusion/query/history/git/__init__.php
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/diffusion/data/pathchange');
|
||||||
|
phutil_require_module('phabricator', 'applications/diffusion/query/history/base');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'future/exec');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('DiffusionGitHistoryQuery.php');
|
|
@ -38,6 +38,7 @@ class DiffusionGitRequest extends DiffusionRequest {
|
||||||
// here than to try to do it in every query.
|
// here than to try to do it in every query.
|
||||||
|
|
||||||
$branch = $this->getBranch();
|
$branch = $this->getBranch();
|
||||||
|
|
||||||
execx(
|
execx(
|
||||||
'(cd %s && %s rev-parse --verify %s)',
|
'(cd %s && %s rev-parse --verify %s)',
|
||||||
$local_path,
|
$local_path,
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
final class DiffusionBrowseTableView extends AphrontView {
|
final class DiffusionBrowseTableView extends AphrontView {
|
||||||
|
|
||||||
private $request;
|
private $request;
|
||||||
|
private $paths;
|
||||||
|
|
||||||
public function setDiffusionRequest(DiffusionRequest $request) {
|
public function setDiffusionRequest(DiffusionRequest $request) {
|
||||||
$this->request = $request;
|
$this->request = $request;
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 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 DiffusionHistoryTableView extends AphrontView {
|
||||||
|
|
||||||
|
private $request;
|
||||||
|
private $history;
|
||||||
|
|
||||||
|
public function setDiffusionRequest(DiffusionRequest $request) {
|
||||||
|
$this->request = $request;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setHistory(array $history) {
|
||||||
|
$this->history = $history;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render() {
|
||||||
|
$rows = array();
|
||||||
|
foreach ($this->history as $history) {
|
||||||
|
$rows[] = array(
|
||||||
|
phutil_escape_html($history->getCommit()), // TODO: link
|
||||||
|
// TODO: etc etc
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$view = new AphrontTableView($rows);
|
||||||
|
$view->setHeaders(
|
||||||
|
array(
|
||||||
|
'Commit',
|
||||||
|
));
|
||||||
|
return $view->render();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
15
src/applications/diffusion/view/historytable/__init__.php
Normal file
15
src/applications/diffusion/view/historytable/__init__.php
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'view/base');
|
||||||
|
phutil_require_module('phabricator', 'view/control/table');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'markup');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('DiffusionHistoryTableView.php');
|
Loading…
Reference in a new issue