1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-29 10:12:41 +01:00

Distinguish between empty and unparsed commits in Diffusion

Summary:
Fixes T3416. Fixes T1733.

  - Adds a flag to the commit table showing whether or not we have parsed it.
  - The flag is set to `0` initially when the commit is discovered.
  - The flag is set to `1` when the changes are parsed.
  - The UI can now use the flag to distinguish between "empty commit" and "commit which we haven't imported changes for yet".
  - Simplify rendering code a little bit.
  - Fix an issue with the Message parser for empty commits.
  - There's a key on the flag so we can do `SELECT * FROM repository_commit WHERE repositoryID = %d AND importStatus = 0 LIMIT 1` soon, to determine if a repository is fully imported or not. This will let us improve the UI (Ref T776, Ref T3217).

Test Plan:
  - Ran `bin/storage upgrade -f`.
  - Created an empty commit.
  - Without the daemons running, ran `bin/repository pull GTEST` and `bin/repository discover GTEST`.
  - Viewed web UI to get the first screenshot ("Still Importing...").
  - Ran the message and change steps with `scripts/repository/reparse.php`.
  - Viewed web UI to get the second screenshot ("Empty Commit").

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T776, T1733, T3416, T3217

Differential Revision: https://secure.phabricator.com/D7428
This commit is contained in:
epriestley 2013-10-26 19:16:10 -07:00
parent 0965f0041a
commit 9125095587
8 changed files with 96 additions and 29 deletions

View file

@ -0,0 +1,8 @@
ALTER TABLE {$NAMESPACE}_repository.repository_commit
ADD COLUMN importStatus INT UNSIGNED NOT NULL COLLATE utf8_bin;
UPDATE {$NAMESPACE}_repository.repository_commit
SET importStatus = 15;
ALTER TABLE {$NAMESPACE}_repository.repository_commit
ADD KEY (repositoryID, importStatus);

View file

@ -76,7 +76,6 @@ final class DiffusionCommitController extends DiffusionController {
$this->auditAuthorityPHIDs = $this->auditAuthorityPHIDs =
PhabricatorAuditCommentEditor::loadAuditPHIDsForUser($user); PhabricatorAuditCommentEditor::loadAuditPHIDsForUser($user);
$is_foreign = $commit_data->getCommitDetail('foreign-svn-stub'); $is_foreign = $commit_data->getCommitDetail('foreign-svn-stub');
$changesets = null; $changesets = null;
if ($is_foreign) { if ($is_foreign) {
@ -154,10 +153,14 @@ final class DiffusionCommitController extends DiffusionController {
$hard_limit = 1000; $hard_limit = 1000;
$change_query = DiffusionPathChangeQuery::newFromDiffusionRequest( if ($commit->isImported()) {
$drequest); $change_query = DiffusionPathChangeQuery::newFromDiffusionRequest(
$change_query->setLimit($hard_limit + 1); $drequest);
$changes = $change_query->loadChanges(); $change_query->setLimit($hard_limit + 1);
$changes = $change_query->loadChanges();
} else {
$changes = array();
}
$was_limited = (count($changes) > $hard_limit); $was_limited = (count($changes) > $hard_limit);
if ($was_limited) { if ($was_limited) {
@ -206,37 +209,29 @@ final class DiffusionCommitController extends DiffusionController {
} }
if ($bad_commit) { if ($bad_commit) {
$error_panel = new AphrontErrorView(); $content[] = $this->renderStatusMessage(
$error_panel->setTitle(pht('Bad Commit')); pht('Bad Commit'),
$error_panel->appendChild($bad_commit['description']); $bad_commit['description']);
$content[] = $error_panel;
} else if ($is_foreign) { } else if ($is_foreign) {
// Don't render anything else. // Don't render anything else.
} else if (!$commit->isImported()) {
$content[] = $this->renderStatusMessage(
pht('Still Importing...'),
pht(
'This commit is still importing. Changes will be visible once '.
'the import finishes.'));
} else if (!count($changes)) { } else if (!count($changes)) {
$no_changes = new AphrontErrorView(); $content[] = $this->renderStatusMessage(
$no_changes->setSeverity(AphrontErrorView::SEVERITY_WARNING); pht('Empty Commit'),
$no_changes->setTitle(pht('Not Yet Parsed')); pht(
// TODO: This can also happen with weird SVN changes that don't do 'This commit is empty and does not affect any paths.'));
// anything (or only alter properties?), although the real no-changes case
// is extremely rare and might be impossible to produce organically. We
// should probably write some kind of "Nothing Happened!" change into the
// DB once we parse these changes so we can distinguish between
// "not parsed yet" and "no changes".
$no_changes->appendChild(
pht("This commit hasn't been fully parsed yet (or doesn't affect any ".
"paths)."));
$content[] = $no_changes;
} else if ($was_limited) { } else if ($was_limited) {
$huge_commit = new AphrontErrorView(); $content[] = $this->renderStatusMessage(
$huge_commit->setSeverity(AphrontErrorView::SEVERITY_WARNING); pht('Enormous Commit'),
$huge_commit->setTitle(pht('Enormous Commit'));
$huge_commit->appendChild(
pht( pht(
'This commit is enormous, and affects more than %d files. '. 'This commit is enormous, and affects more than %d files. '.
'Changes are not shown.', 'Changes are not shown.',
$hard_limit)); $hard_limit));
$content[] = $huge_commit;
} else { } else {
// The user has clicked "Show All Changes", and we should show all the // The user has clicked "Show All Changes", and we should show all the
// changes inline even if there are more than the soft limit. // changes inline even if there are more than the soft limit.
@ -253,6 +248,7 @@ final class DiffusionCommitController extends DiffusionController {
'href' => '?show_all=true', 'href' => '?show_all=true',
), ),
pht('Show All Changes')); pht('Show All Changes'));
$warning_view = id(new AphrontErrorView()) $warning_view = id(new AphrontErrorView())
->setSeverity(AphrontErrorView::SEVERITY_WARNING) ->setSeverity(AphrontErrorView::SEVERITY_WARNING)
->setTitle('Very Large Commit') ->setTitle('Very Large Commit')
@ -1084,4 +1080,11 @@ final class DiffusionCommitController extends DiffusionController {
return $parser->processCorpus($corpus); return $parser->processCorpus($corpus);
} }
private function renderStatusMessage($title, $body) {
return id(new AphrontErrorView())
->setSeverity(AphrontErrorView::SEVERITY_WARNING)
->setTitle($title)
->appendChild($body);
}
} }

View file

@ -15,6 +15,13 @@ final class PhabricatorRepositoryCommit
protected $authorPHID; protected $authorPHID;
protected $auditStatus = PhabricatorAuditCommitStatusConstants::NONE; protected $auditStatus = PhabricatorAuditCommitStatusConstants::NONE;
protected $summary = ''; protected $summary = '';
protected $importStatus = 0;
const IMPORTED_MESSAGE = 1;
const IMPORTED_CHANGE = 2;
const IMPORTED_OWNERS = 4;
const IMPORTED_HERALD = 8;
const IMPORTED_ALL = 15;
private $commitData = self::ATTACHABLE; private $commitData = self::ATTACHABLE;
private $audits; private $audits;
@ -39,6 +46,20 @@ final class PhabricatorRepositoryCommit
return $this->isUnparsed; return $this->isUnparsed;
} }
public function isImported() {
return ($this->getImportStatus() == self::IMPORTED_ALL);
}
public function writeImportStatusFlag($flag) {
queryfx(
$this->establishConnection('w'),
'UPDATE %T SET importStatus = (importStatus | %d) WHERE id = %d',
$this->getTableName(),
$flag,
$this->getID());
return $this;
}
public function getConfiguration() { public function getConfiguration() {
return array( return array(
self::CONFIG_AUX_PHID => true, self::CONFIG_AUX_PHID => true,

View file

@ -12,6 +12,18 @@ final class PhabricatorRepositoryCommitHeraldWorker
PhabricatorRepository $repository, PhabricatorRepository $repository,
PhabricatorRepositoryCommit $commit) { PhabricatorRepositoryCommit $commit) {
$result = $this->applyHeraldRules($repository, $commit);
$commit->writeImportStatusFlag(
PhabricatorRepositoryCommit::IMPORTED_HERALD);
return $result;
}
private function applyHeraldRules(
PhabricatorRepository $repository,
PhabricatorRepositoryCommit $commit) {
$data = id(new PhabricatorRepositoryCommitData())->loadOneWhere( $data = id(new PhabricatorRepositoryCommitData())->loadOneWhere(
'commitID = %d', 'commitID = %d',
$commit->getID()); $commit->getID());

View file

@ -58,6 +58,9 @@ final class PhabricatorRepositoryCommitOwnersWorker
$commit->save(); $commit->save();
} }
$commit->writeImportStatusFlag(
PhabricatorRepositoryCommit::IMPORTED_OWNERS);
if ($this->shouldQueueFollowupTasks()) { if ($this->shouldQueueFollowupTasks()) {
PhabricatorWorker::scheduleTask( PhabricatorWorker::scheduleTask(
'PhabricatorRepositoryCommitHeraldWorker', 'PhabricatorRepositoryCommitHeraldWorker',

View file

@ -58,6 +58,9 @@ abstract class PhabricatorRepositoryCommitChangeParserWorker
protected function finishParse() { protected function finishParse() {
$commit = $this->commit; $commit = $this->commit;
$commit->writeImportStatusFlag(
PhabricatorRepositoryCommit::IMPORTED_CHANGE);
id(new PhabricatorSearchIndexer()) id(new PhabricatorSearchIndexer())
->indexDocumentByPHID($commit->getPHID()); ->indexDocumentByPHID($commit->getPHID());

View file

@ -220,6 +220,9 @@ abstract class PhabricatorRepositoryCommitMessageParserWorker
} }
$data->save(); $data->save();
$commit->writeImportStatusFlag(
PhabricatorRepositoryCommit::IMPORTED_MESSAGE);
} }
private function loadUserName($user_phid, $default, PhabricatorUser $actor) { private function loadUserName($user_phid, $default, PhabricatorUser $actor) {
@ -249,7 +252,17 @@ abstract class PhabricatorRepositoryCommitMessageParserWorker
->loadRawDiff(); ->loadRawDiff();
// TODO: Support adds, deletes and moves under SVN. // TODO: Support adds, deletes and moves under SVN.
$changes = id(new ArcanistDiffParser())->parseDiff($raw_diff); if (strlen($raw_diff)) {
$changes = id(new ArcanistDiffParser())->parseDiff($raw_diff);
} else {
// This is an empty diff, maybe made with `git commit --allow-empty`.
// NOTE: These diffs have the same tree hash as their ancestors, so
// they may attach to revisions in an unexpected way. Just let this
// happen for now, although it might make sense to special case it
// eventually.
$changes = array();
}
$diff = DifferentialDiff::newFromRawChanges($changes) $diff = DifferentialDiff::newFromRawChanges($changes)
->setRevisionID($revision->getID()) ->setRevisionID($revision->getID())
->setAuthorPHID($actor_phid) ->setAuthorPHID($actor_phid)

View file

@ -1708,6 +1708,10 @@ final class PhabricatorBuiltinPatchList extends PhabricatorSQLPatchList {
'type' => 'sql', 'type' => 'sql',
'name' => $this->getPatchPath('20131025.repopush.sql'), 'name' => $this->getPatchPath('20131025.repopush.sql'),
), ),
'20131026.commitstatus.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('20131026.commitstatus.sql'),
),
); );
} }
} }