@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+96 -29
+8
resources/sql/patches/20131026.commitstatus.sql
··· 1 + ALTER TABLE {$NAMESPACE}_repository.repository_commit 2 + ADD COLUMN importStatus INT UNSIGNED NOT NULL COLLATE utf8_bin; 3 + 4 + UPDATE {$NAMESPACE}_repository.repository_commit 5 + SET importStatus = 15; 6 + 7 + ALTER TABLE {$NAMESPACE}_repository.repository_commit 8 + ADD KEY (repositoryID, importStatus);
+31 -28
src/applications/diffusion/controller/DiffusionCommitController.php
··· 76 76 $this->auditAuthorityPHIDs = 77 77 PhabricatorAuditCommentEditor::loadAuditPHIDsForUser($user); 78 78 79 - 80 79 $is_foreign = $commit_data->getCommitDetail('foreign-svn-stub'); 81 80 $changesets = null; 82 81 if ($is_foreign) { ··· 154 153 155 154 $hard_limit = 1000; 156 155 157 - $change_query = DiffusionPathChangeQuery::newFromDiffusionRequest( 158 - $drequest); 159 - $change_query->setLimit($hard_limit + 1); 160 - $changes = $change_query->loadChanges(); 156 + if ($commit->isImported()) { 157 + $change_query = DiffusionPathChangeQuery::newFromDiffusionRequest( 158 + $drequest); 159 + $change_query->setLimit($hard_limit + 1); 160 + $changes = $change_query->loadChanges(); 161 + } else { 162 + $changes = array(); 163 + } 161 164 162 165 $was_limited = (count($changes) > $hard_limit); 163 166 if ($was_limited) { ··· 206 209 } 207 210 208 211 if ($bad_commit) { 209 - $error_panel = new AphrontErrorView(); 210 - $error_panel->setTitle(pht('Bad Commit')); 211 - $error_panel->appendChild($bad_commit['description']); 212 - 213 - $content[] = $error_panel; 212 + $content[] = $this->renderStatusMessage( 213 + pht('Bad Commit'), 214 + $bad_commit['description']); 214 215 } else if ($is_foreign) { 215 216 // Don't render anything else. 217 + } else if (!$commit->isImported()) { 218 + $content[] = $this->renderStatusMessage( 219 + pht('Still Importing...'), 220 + pht( 221 + 'This commit is still importing. Changes will be visible once '. 222 + 'the import finishes.')); 216 223 } else if (!count($changes)) { 217 - $no_changes = new AphrontErrorView(); 218 - $no_changes->setSeverity(AphrontErrorView::SEVERITY_WARNING); 219 - $no_changes->setTitle(pht('Not Yet Parsed')); 220 - // TODO: This can also happen with weird SVN changes that don't do 221 - // anything (or only alter properties?), although the real no-changes case 222 - // is extremely rare and might be impossible to produce organically. We 223 - // should probably write some kind of "Nothing Happened!" change into the 224 - // DB once we parse these changes so we can distinguish between 225 - // "not parsed yet" and "no changes". 226 - $no_changes->appendChild( 227 - pht("This commit hasn't been fully parsed yet (or doesn't affect any ". 228 - "paths).")); 229 - $content[] = $no_changes; 224 + $content[] = $this->renderStatusMessage( 225 + pht('Empty Commit'), 226 + pht( 227 + 'This commit is empty and does not affect any paths.')); 230 228 } else if ($was_limited) { 231 - $huge_commit = new AphrontErrorView(); 232 - $huge_commit->setSeverity(AphrontErrorView::SEVERITY_WARNING); 233 - $huge_commit->setTitle(pht('Enormous Commit')); 234 - $huge_commit->appendChild( 229 + $content[] = $this->renderStatusMessage( 230 + pht('Enormous Commit'), 235 231 pht( 236 232 'This commit is enormous, and affects more than %d files. '. 237 233 'Changes are not shown.', 238 234 $hard_limit)); 239 - $content[] = $huge_commit; 240 235 } else { 241 236 // The user has clicked "Show All Changes", and we should show all the 242 237 // changes inline even if there are more than the soft limit. ··· 253 248 'href' => '?show_all=true', 254 249 ), 255 250 pht('Show All Changes')); 251 + 256 252 $warning_view = id(new AphrontErrorView()) 257 253 ->setSeverity(AphrontErrorView::SEVERITY_WARNING) 258 254 ->setTitle('Very Large Commit') ··· 1082 1078 } 1083 1079 1084 1080 return $parser->processCorpus($corpus); 1081 + } 1082 + 1083 + private function renderStatusMessage($title, $body) { 1084 + return id(new AphrontErrorView()) 1085 + ->setSeverity(AphrontErrorView::SEVERITY_WARNING) 1086 + ->setTitle($title) 1087 + ->appendChild($body); 1085 1088 } 1086 1089 1087 1090 }
+21
src/applications/repository/storage/PhabricatorRepositoryCommit.php
··· 15 15 protected $authorPHID; 16 16 protected $auditStatus = PhabricatorAuditCommitStatusConstants::NONE; 17 17 protected $summary = ''; 18 + protected $importStatus = 0; 19 + 20 + const IMPORTED_MESSAGE = 1; 21 + const IMPORTED_CHANGE = 2; 22 + const IMPORTED_OWNERS = 4; 23 + const IMPORTED_HERALD = 8; 24 + const IMPORTED_ALL = 15; 18 25 19 26 private $commitData = self::ATTACHABLE; 20 27 private $audits; ··· 37 44 38 45 public function getIsUnparsed() { 39 46 return $this->isUnparsed; 47 + } 48 + 49 + public function isImported() { 50 + return ($this->getImportStatus() == self::IMPORTED_ALL); 51 + } 52 + 53 + public function writeImportStatusFlag($flag) { 54 + queryfx( 55 + $this->establishConnection('w'), 56 + 'UPDATE %T SET importStatus = (importStatus | %d) WHERE id = %d', 57 + $this->getTableName(), 58 + $flag, 59 + $this->getID()); 60 + return $this; 40 61 } 41 62 42 63 public function getConfiguration() {
+12
src/applications/repository/worker/PhabricatorRepositoryCommitHeraldWorker.php
··· 12 12 PhabricatorRepository $repository, 13 13 PhabricatorRepositoryCommit $commit) { 14 14 15 + $result = $this->applyHeraldRules($repository, $commit); 16 + 17 + $commit->writeImportStatusFlag( 18 + PhabricatorRepositoryCommit::IMPORTED_HERALD); 19 + 20 + return $result; 21 + } 22 + 23 + private function applyHeraldRules( 24 + PhabricatorRepository $repository, 25 + PhabricatorRepositoryCommit $commit) { 26 + 15 27 $data = id(new PhabricatorRepositoryCommitData())->loadOneWhere( 16 28 'commitID = %d', 17 29 $commit->getID());
+3
src/applications/repository/worker/PhabricatorRepositoryCommitOwnersWorker.php
··· 58 58 $commit->save(); 59 59 } 60 60 61 + $commit->writeImportStatusFlag( 62 + PhabricatorRepositoryCommit::IMPORTED_OWNERS); 63 + 61 64 if ($this->shouldQueueFollowupTasks()) { 62 65 PhabricatorWorker::scheduleTask( 63 66 'PhabricatorRepositoryCommitHeraldWorker',
+3
src/applications/repository/worker/commitchangeparser/PhabricatorRepositoryCommitChangeParserWorker.php
··· 58 58 protected function finishParse() { 59 59 $commit = $this->commit; 60 60 61 + $commit->writeImportStatusFlag( 62 + PhabricatorRepositoryCommit::IMPORTED_CHANGE); 63 + 61 64 id(new PhabricatorSearchIndexer()) 62 65 ->indexDocumentByPHID($commit->getPHID()); 63 66
+14 -1
src/applications/repository/worker/commitmessageparser/PhabricatorRepositoryCommitMessageParserWorker.php
··· 220 220 } 221 221 222 222 $data->save(); 223 + 224 + $commit->writeImportStatusFlag( 225 + PhabricatorRepositoryCommit::IMPORTED_MESSAGE); 223 226 } 224 227 225 228 private function loadUserName($user_phid, $default, PhabricatorUser $actor) { ··· 249 252 ->loadRawDiff(); 250 253 251 254 // TODO: Support adds, deletes and moves under SVN. 252 - $changes = id(new ArcanistDiffParser())->parseDiff($raw_diff); 255 + if (strlen($raw_diff)) { 256 + $changes = id(new ArcanistDiffParser())->parseDiff($raw_diff); 257 + } else { 258 + // This is an empty diff, maybe made with `git commit --allow-empty`. 259 + // NOTE: These diffs have the same tree hash as their ancestors, so 260 + // they may attach to revisions in an unexpected way. Just let this 261 + // happen for now, although it might make sense to special case it 262 + // eventually. 263 + $changes = array(); 264 + } 265 + 253 266 $diff = DifferentialDiff::newFromRawChanges($changes) 254 267 ->setRevisionID($revision->getID()) 255 268 ->setAuthorPHID($actor_phid)
+4
src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
··· 1708 1708 'type' => 'sql', 1709 1709 'name' => $this->getPatchPath('20131025.repopush.sql'), 1710 1710 ), 1711 + '20131026.commitstatus.sql' => array( 1712 + 'type' => 'sql', 1713 + 'name' => $this->getPatchPath('20131026.commitstatus.sql'), 1714 + ), 1711 1715 ); 1712 1716 } 1713 1717 }