@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.

Merge the new navigation design

For discussion, see T5241.

+224 -175
+4
conf/default.conf.php
··· 811 811 // only the submitter can close a revision. 812 812 'differential.always-allow-close' => false, 813 813 814 + // If you set this to true, any user can abandon any revision. If false, only 815 + // the submitter can abandon a revision. 816 + 'differential.always-allow-abandon' => false, 817 + 814 818 // If you set this to true, any user can reopen a revision so long as it has 815 819 // been closed. This can be useful if a revision is accidentally closed or 816 820 // if a developer changes his or her mind after closing a revision. If it is
+34 -34
resources/celerity/map.php
··· 7 7 return array( 8 8 'names' => 9 9 array( 10 - 'core.pkg.css' => '30eeae90', 11 - 'core.pkg.js' => '7db41c19', 10 + 'core.pkg.css' => '2920014c', 11 + 'core.pkg.js' => '639b2433', 12 12 'darkconsole.pkg.js' => 'ca8671ce', 13 13 'differential.pkg.css' => 'fbf57382', 14 14 'differential.pkg.js' => '74cb0d29', ··· 135 135 'rsrc/css/phui/phui-info-panel.css' => '27ea50a1', 136 136 'rsrc/css/phui/phui-list.css' => '43ed2d93', 137 137 'rsrc/css/phui/phui-object-box.css' => 'ce92d8ec', 138 - 'rsrc/css/phui/phui-object-item-list-view.css' => '15c582b1', 138 + 'rsrc/css/phui/phui-object-item-list-view.css' => 'bd66015e', 139 139 'rsrc/css/phui/phui-pinboard-view.css' => '874c22f9', 140 140 'rsrc/css/phui/phui-property-list-view.css' => '2f7199e8', 141 141 'rsrc/css/phui/phui-remarkup-preview.css' => '19ad512b', ··· 343 343 'rsrc/image/texture/table_header_tall.png' => 'd56b434f', 344 344 'rsrc/js/application/aphlict/Aphlict.js' => '493665ee', 345 345 'rsrc/js/application/aphlict/behavior-aphlict-dropdown.js' => '2a2dba85', 346 - 'rsrc/js/application/aphlict/behavior-aphlict-listen.js' => '0a6c2de6', 346 + 'rsrc/js/application/aphlict/behavior-aphlict-listen.js' => '9aa97ab6', 347 347 'rsrc/js/application/auth/behavior-persona-login.js' => '9414ff18', 348 348 'rsrc/js/application/config/behavior-reorder-fields.js' => '938aed89', 349 349 'rsrc/js/application/conpherence/behavior-menu.js' => '7ee23816', ··· 459 459 'rsrc/js/core/behavior-keyboard-shortcuts.js' => 'd75709e6', 460 460 'rsrc/js/core/behavior-konami.js' => '5bc2cb21', 461 461 'rsrc/js/core/behavior-lightbox-attachments.js' => '3aa45ad9', 462 - 'rsrc/js/core/behavior-line-linker.js' => '0969ff43', 462 + 'rsrc/js/core/behavior-line-linker.js' => 'f726d506', 463 463 'rsrc/js/core/behavior-more.js' => '9b9197be', 464 464 'rsrc/js/core/behavior-object-selector.js' => 'e6f67523', 465 465 'rsrc/js/core/behavior-oncopy.js' => 'c3e218fe', ··· 532 532 'javelin-aphlict' => '493665ee', 533 533 'javelin-behavior' => '8a3ed18b', 534 534 'javelin-behavior-aphlict-dropdown' => '2a2dba85', 535 - 'javelin-behavior-aphlict-listen' => '0a6c2de6', 535 + 'javelin-behavior-aphlict-listen' => '9aa97ab6', 536 536 'javelin-behavior-aphront-basic-tokenizer' => 'b3a4b884', 537 537 'javelin-behavior-aphront-crop' => 'b98fc918', 538 538 'javelin-behavior-aphront-drag-and-drop-textarea' => '4a11ea9c', ··· 601 601 'javelin-behavior-phabricator-hovercards' => '9c808199', 602 602 'javelin-behavior-phabricator-keyboard-pager' => 'b657bdf8', 603 603 'javelin-behavior-phabricator-keyboard-shortcuts' => 'd75709e6', 604 - 'javelin-behavior-phabricator-line-linker' => '0969ff43', 604 + 'javelin-behavior-phabricator-line-linker' => 'f726d506', 605 605 'javelin-behavior-phabricator-nav' => 'b5842a5e', 606 606 'javelin-behavior-phabricator-notification-example' => 'c51a6616', 607 607 'javelin-behavior-phabricator-object-selector' => 'e6f67523', ··· 766 766 'phui-info-panel-css' => '27ea50a1', 767 767 'phui-list-view-css' => '43ed2d93', 768 768 'phui-object-box-css' => 'ce92d8ec', 769 - 'phui-object-item-list-view-css' => '15c582b1', 769 + 'phui-object-item-list-view-css' => 'bd66015e', 770 770 'phui-pinboard-view-css' => '874c22f9', 771 771 'phui-property-list-view-css' => '2f7199e8', 772 772 'phui-remarkup-preview-css' => '19ad512b', ··· 863 863 array( 864 864 0 => 'javelin-install', 865 865 ), 866 - '0969ff43' => 867 - array( 868 - 0 => 'javelin-behavior', 869 - 1 => 'javelin-stratcom', 870 - 2 => 'javelin-dom', 871 - 3 => 'javelin-history', 872 - ), 873 866 '09b15cf1' => 874 867 array( 875 868 0 => 'javelin-stratcom', ··· 890 883 3 => 'javelin-dom', 891 884 4 => 'javelin-router', 892 885 ), 893 - '0a6c2de6' => 894 - array( 895 - 0 => 'javelin-behavior', 896 - 1 => 'javelin-aphlict', 897 - 2 => 'javelin-stratcom', 898 - 3 => 'javelin-request', 899 - 4 => 'javelin-uri', 900 - 5 => 'javelin-dom', 901 - 6 => 'javelin-json', 902 - 7 => 'javelin-router', 903 - 8 => 'phabricator-notification', 904 - ), 905 886 '0c33c1a0' => 906 887 array( 907 888 0 => 'javelin-view', ··· 1270 1251 2 => 'javelin-util', 1271 1252 3 => 'phabricator-shaped-request', 1272 1253 ), 1273 - '62e18640' => 1274 - array( 1275 - 0 => 'javelin-install', 1276 - 1 => 'javelin-util', 1277 - 2 => 'javelin-dom', 1278 - 3 => 'javelin-typeahead-normalizer', 1279 - ), 1280 1254 '6453c869' => 1281 1255 array( 1282 1256 0 => 'javelin-install', ··· 1334 1308 array( 1335 1309 0 => 'javelin-behavior', 1336 1310 1 => 'javelin-dom', 1311 + ), 1312 + '62e18640' => 1313 + array( 1314 + 0 => 'javelin-install', 1315 + 1 => 'javelin-util', 1316 + 2 => 'javelin-dom', 1317 + 3 => 'javelin-typeahead-normalizer', 1337 1318 ), 1338 1319 '76f4ebed' => 1339 1320 array( ··· 1532 1513 3 => 'javelin-dom', 1533 1514 4 => 'phabricator-draggable-list', 1534 1515 ), 1516 + '9aa97ab6' => 1517 + array( 1518 + 0 => 'javelin-behavior', 1519 + 1 => 'javelin-aphlict', 1520 + 2 => 'javelin-stratcom', 1521 + 3 => 'javelin-request', 1522 + 4 => 'javelin-uri', 1523 + 5 => 'javelin-dom', 1524 + 6 => 'javelin-json', 1525 + 7 => 'javelin-router', 1526 + 8 => 'phabricator-notification', 1527 + ), 1535 1528 '9b9197be' => 1536 1529 array( 1537 1530 0 => 'javelin-behavior', ··· 2004 1997 1 => 'javelin-reactornode', 2005 1998 2 => 'javelin-util', 2006 1999 3 => 'javelin-reactor', 2000 + ), 2001 + 'f726d506' => 2002 + array( 2003 + 0 => 'javelin-behavior', 2004 + 1 => 'javelin-stratcom', 2005 + 2 => 'javelin-dom', 2006 + 3 => 'javelin-history', 2007 2007 ), 2008 2008 'f7379f45' => 2009 2009 array(
+3 -3
scripts/install/install_rhel-derivs.sh
··· 119 119 120 120 if [[ ! -e libphutil ]] 121 121 then 122 - git clone git://github.com/phacility/libphutil.git 122 + git clone https://github.com/phacility/libphutil.git 123 123 else 124 124 (cd libphutil && git pull --rebase) 125 125 fi 126 126 127 127 if [[ ! -e arcanist ]] 128 128 then 129 - git clone git://github.com/phacility/arcanist.git 129 + git clone https://github.com/phacility/arcanist.git 130 130 else 131 131 (cd arcanist && git pull --rebase) 132 132 fi 133 133 134 134 if [[ ! -e phabricator ]] 135 135 then 136 - git clone git://github.com/phacility/phabricator.git 136 + git clone https://github.com/phacility/phabricator.git 137 137 else 138 138 (cd phabricator && git pull --rebase) 139 139 fi
+3 -3
scripts/install/install_ubuntu.sh
··· 64 64 65 65 if [ ! -e libphutil ] 66 66 then 67 - git clone git://github.com/phacility/libphutil.git 67 + git clone https://github.com/phacility/libphutil.git 68 68 else 69 69 (cd libphutil && git pull --rebase) 70 70 fi 71 71 72 72 if [ ! -e arcanist ] 73 73 then 74 - git clone git://github.com/phacility/arcanist.git 74 + git clone https://github.com/phacility/arcanist.git 75 75 else 76 76 (cd arcanist && git pull --rebase) 77 77 fi 78 78 79 79 if [ ! -e phabricator ] 80 80 then 81 - git clone git://github.com/phacility/phabricator.git 81 + git clone https://github.com/phacility/phabricator.git 82 82 else 83 83 (cd phabricator && git pull --rebase) 84 84 fi
+3 -2
src/__phutil_library_map__.php
··· 2022 2022 'PhabricatorRepositoryGraphStream' => 'applications/repository/daemon/PhabricatorRepositoryGraphStream.php', 2023 2023 'PhabricatorRepositoryListController' => 'applications/repository/controller/PhabricatorRepositoryListController.php', 2024 2024 'PhabricatorRepositoryManagementCacheWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementCacheWorkflow.php', 2025 - 'PhabricatorRepositoryManagementDeleteWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementDeleteWorkflow.php', 2026 2025 'PhabricatorRepositoryManagementDiscoverWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementDiscoverWorkflow.php', 2027 2026 'PhabricatorRepositoryManagementEditWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementEditWorkflow.php', 2028 2027 'PhabricatorRepositoryManagementImportingWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementImportingWorkflow.php', ··· 4749 4748 2 => 'PhabricatorPolicyInterface', 4750 4749 3 => 'PhabricatorSubscribableInterface', 4751 4750 4 => 'PhabricatorCustomFieldInterface', 4751 + 5 => 'PhabricatorDestructableInterface', 4752 4752 ), 4753 4753 'PhabricatorProjectArchiveController' => 'PhabricatorProjectController', 4754 4754 'PhabricatorProjectBoardController' => 'PhabricatorProjectController', ··· 4759 4759 array( 4760 4760 0 => 'PhabricatorProjectDAO', 4761 4761 1 => 'PhabricatorPolicyInterface', 4762 + 2 => 'PhabricatorDestructableInterface', 4762 4763 ), 4763 4764 'PhabricatorProjectColumnDetailController' => 'PhabricatorProjectBoardController', 4764 4765 'PhabricatorProjectColumnQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', ··· 4831 4832 1 => 'PhabricatorPolicyInterface', 4832 4833 2 => 'PhabricatorFlaggableInterface', 4833 4834 3 => 'PhabricatorMarkupInterface', 4835 + 4 => 'PhabricatorDestructableInterface', 4834 4836 ), 4835 4837 'PhabricatorRepositoryArcanistProject' => 4836 4838 array( ··· 4872 4874 'PhabricatorRepositoryGraphStream' => 'Phobject', 4873 4875 'PhabricatorRepositoryListController' => 'PhabricatorRepositoryController', 4874 4876 'PhabricatorRepositoryManagementCacheWorkflow' => 'PhabricatorRepositoryManagementWorkflow', 4875 - 'PhabricatorRepositoryManagementDeleteWorkflow' => 'PhabricatorRepositoryManagementWorkflow', 4876 4877 'PhabricatorRepositoryManagementDiscoverWorkflow' => 'PhabricatorRepositoryManagementWorkflow', 4877 4878 'PhabricatorRepositoryManagementEditWorkflow' => 'PhabricatorRepositoryManagementWorkflow', 4878 4879 'PhabricatorRepositoryManagementImportingWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
+11
src/applications/differential/config/PhabricatorDifferentialConfigOptions.php
··· 165 165 "where the reviewer is often the actual committer can benefit ". 166 166 "from turning this option to true. If false, only the submitter ". 167 167 "can close a revision.")), 168 + $this->newOption('differential.always-allow-abandon', 'bool', false) 169 + ->setBoolOptions( 170 + array( 171 + pht('Allow any user'), 172 + pht('Restrict to submitter'), 173 + )) 174 + ->setSummary(pht('Allows any user to abandon revisions.')) 175 + ->setDescription( 176 + pht( 177 + 'If you set this to true, any user can abandon any revision. If '. 178 + 'false, only the submitter can abandon a revision.')), 168 179 $this->newOption('differential.allow-reopen', 'bool', false) 169 180 ->setBoolOptions( 170 181 array(
+5
src/applications/differential/controller/DifferentialRevisionViewController.php
··· 553 553 554 554 $allow_self_accept = PhabricatorEnv::getEnvConfig( 555 555 'differential.allow-self-accept'); 556 + $always_allow_abandon = PhabricatorEnv::getEnvConfig( 557 + 'differential.always-allow-abandon'); 556 558 $always_allow_close = PhabricatorEnv::getEnvConfig( 557 559 'differential.always-allow-close'); 558 560 $allow_reopen = PhabricatorEnv::getEnvConfig( ··· 586 588 } else { 587 589 switch ($status) { 588 590 case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW: 591 + $actions[DifferentialAction::ACTION_ABANDON] = $always_allow_abandon; 589 592 $actions[DifferentialAction::ACTION_ACCEPT] = true; 590 593 $actions[DifferentialAction::ACTION_REJECT] = true; 591 594 $actions[DifferentialAction::ACTION_RESIGN] = $viewer_is_reviewer; 592 595 break; 593 596 case ArcanistDifferentialRevisionStatus::NEEDS_REVISION: 594 597 case ArcanistDifferentialRevisionStatus::CHANGES_PLANNED: 598 + $actions[DifferentialAction::ACTION_ABANDON] = $always_allow_abandon; 595 599 $actions[DifferentialAction::ACTION_ACCEPT] = true; 596 600 $actions[DifferentialAction::ACTION_REJECT] = !$viewer_has_rejected; 597 601 $actions[DifferentialAction::ACTION_RESIGN] = $viewer_is_reviewer; 598 602 break; 599 603 case ArcanistDifferentialRevisionStatus::ACCEPTED: 604 + $actions[DifferentialAction::ACTION_ABANDON] = $always_allow_abandon; 600 605 $actions[DifferentialAction::ACTION_ACCEPT] = !$viewer_has_accepted; 601 606 $actions[DifferentialAction::ACTION_REJECT] = true; 602 607 $actions[DifferentialAction::ACTION_RESIGN] = $viewer_is_reviewer;
+4 -1
src/applications/differential/editor/DifferentialTransactionEditor.php
··· 789 789 $actor_phid = $this->getActor()->getPHID(); 790 790 $actor_is_author = ($author_phid == $actor_phid); 791 791 792 + $config_abandon_key = 'differential.always-allow-abandon'; 793 + $always_allow_abandon = PhabricatorEnv::getEnvConfig($config_abandon_key); 794 + 792 795 $config_close_key = 'differential.always-allow-close'; 793 796 $always_allow_close = PhabricatorEnv::getEnvConfig($config_close_key); 794 797 ··· 860 863 break; 861 864 862 865 case DifferentialAction::ACTION_ABANDON: 863 - if (!$actor_is_author) { 866 + if (!$actor_is_author && !$always_allow_abandon) { 864 867 return pht( 865 868 "You can not abandon this revision because you do not own it. ". 866 869 "You can only abandon revisions you own.");
+1 -1
src/applications/diffusion/controller/DiffusionRepositoryEditDeleteController.php
··· 29 29 'If you really want to delete the repository, run this command from '. 30 30 'the command line:'); 31 31 $command = csprintf( 32 - 'phabricator/ $ ./bin/repository delete %s', 32 + 'phabricator/ $ ./bin/remove destroy %s', 33 33 $repository->getCallsign()); 34 34 $text_2 = pht('Repositories touch many objects and as such deletes are '. 35 35 'prohibitively expensive to run from the web UI.');
+1 -1
src/applications/metamta/application/PhabricatorApplicationMetaMTA.php
··· 32 32 33 33 public function getRoutes() { 34 34 return array( 35 - $this->getBaseURI() => array( 35 + '/mail/' => array( 36 36 'sendgrid/' => 'PhabricatorMetaMTASendGridReceiveController', 37 37 'mailgun/' => 'PhabricatorMetaMTAMailgunReceiveController', 38 38 ),
+25 -15
src/applications/phriction/controller/PhrictionDocumentController.php
··· 75 75 $vdate = phabricator_datetime($content->getDateCreated(), $user); 76 76 $version_note = new AphrontErrorView(); 77 77 $version_note->setSeverity(AphrontErrorView::SEVERITY_NOTICE); 78 - $version_note->setTitle('Older Version'); 79 78 $version_note->appendChild( 80 79 pht('You are viewing an older version of this document, as it '. 81 80 'appeared on %s.', $vdate)); ··· 126 125 $slug_uri = PhrictionDocument::getSlugURI($new_doc->getSlug()); 127 126 } 128 127 129 - $notice = new AphrontErrorView(); 130 - $notice->setSeverity(AphrontErrorView::SEVERITY_NOTICE); 131 - $notice->setTitle(pht('Document Moved')); 128 + $notice = id(new AphrontErrorView()) 129 + ->setSeverity(AphrontErrorView::SEVERITY_NOTICE); 132 130 133 131 if ($slug_uri) { 134 132 $notice->appendChild( ··· 159 157 $move_notice = null; 160 158 if ($current_status == PhrictionChangeType::CHANGE_MOVE_HERE) { 161 159 $from_doc_id = $content->getChangeRef(); 162 - $from_doc = id(new PhrictionDocumentQuery()) 160 + 161 + $slug_uri = null; 162 + 163 + // If the old document exists and is visible, provide a link to it. 164 + $from_docs = id(new PhrictionDocumentQuery()) 163 165 ->setViewer($user) 164 166 ->withIDs(array($from_doc_id)) 165 - ->executeOne(); 166 - $slug_uri = PhrictionDocument::getSlugURI($from_doc->getSlug()); 167 + ->execute(); 168 + if ($from_docs) { 169 + $from_doc = head($from_docs); 170 + $slug_uri = PhrictionDocument::getSlugURI($from_doc->getSlug()); 171 + } 167 172 168 173 $move_notice = id(new AphrontErrorView()) 169 - ->setSeverity(AphrontErrorView::SEVERITY_NOTICE) 170 - ->appendChild(pht('This document was moved from %s', 171 - phutil_tag('a', array('href' => $slug_uri), $slug_uri))) 172 - ->render(); 174 + ->setSeverity(AphrontErrorView::SEVERITY_NOTICE); 175 + 176 + if ($slug_uri) { 177 + $move_notice->appendChild( 178 + pht( 179 + 'This document was moved from %s.', 180 + phutil_tag('a', array('href' => $slug_uri), $slug_uri))); 181 + } else { 182 + // Render this for consistency, even though it's a bit silly. 183 + $move_notice->appendChild( 184 + pht('This document was moved from elsewhere.')); 185 + } 173 186 } 174 - } 175 - 176 - if ($version_note) { 177 - $version_note = $version_note->render(); 178 187 } 179 188 180 189 $children = $this->renderDocumentChildren($slug); ··· 204 213 array( 205 214 $actions, 206 215 $prop_list, 216 + $version_note, 207 217 $move_notice, 208 218 $core_content, 209 219 ));
+25 -1
src/applications/project/storage/PhabricatorProject.php
··· 5 5 PhabricatorFlaggableInterface, 6 6 PhabricatorPolicyInterface, 7 7 PhabricatorSubscribableInterface, 8 - PhabricatorCustomFieldInterface { 8 + PhabricatorCustomFieldInterface, 9 + PhabricatorDestructableInterface { 9 10 10 11 protected $name; 11 12 protected $status = PhabricatorProjectStatus::STATUS_ACTIVE; ··· 246 247 return $this; 247 248 } 248 249 250 + 251 + /* -( PhabricatorDestructableInterface )----------------------------------- */ 252 + 253 + public function destroyObjectPermanently( 254 + PhabricatorDestructionEngine $engine) { 255 + 256 + $this->openTransaction(); 257 + $this->delete(); 258 + 259 + $columns = id(new PhabricatorProjectColumn()) 260 + ->loadAllWhere('projectPHID = %s', $this->getPHID()); 261 + foreach ($columns as $column) { 262 + $engine->destroyObject($column); 263 + } 264 + 265 + $slugs = id(new PhabricatorProjectSlug()) 266 + ->loadAllWhere('projectPHID = %s', $this->getPHID()); 267 + foreach ($slugs as $slug) { 268 + $slug->delete(); 269 + } 270 + 271 + $this->saveTransaction(); 272 + } 249 273 250 274 }
+13 -1
src/applications/project/storage/PhabricatorProjectColumn.php
··· 2 2 3 3 final class PhabricatorProjectColumn 4 4 extends PhabricatorProjectDAO 5 - implements PhabricatorPolicyInterface { 5 + implements PhabricatorPolicyInterface, 6 + PhabricatorDestructableInterface { 6 7 7 8 const STATUS_ACTIVE = 0; 8 9 const STATUS_DELETED = 1; ··· 85 86 86 87 public function describeAutomaticCapability($capability) { 87 88 return pht('Users must be able to see a project to see its board.'); 89 + } 90 + 91 + 92 + /* -( PhabricatorDestructableInterface )----------------------------------- */ 93 + 94 + public function destroyObjectPermanently( 95 + PhabricatorDestructionEngine $engine) { 96 + 97 + $this->openTransaction(); 98 + $this->delete(); 99 + $this->saveTransaction(); 88 100 } 89 101 90 102 }
+6 -1
src/applications/repository/daemon/PhabricatorGitGraphStream.php
··· 29 29 if (!isset($this->parents[$commit])) { 30 30 $this->parseUntil($commit); 31 31 } 32 - return $this->parents[$commit]; 32 + $parents = $this->parents[$commit]; 33 + 34 + // NOTE: In Git, it is possible for a commit to list the same parent more 35 + // than once. See T5226. Discard duplicate parents. 36 + 37 + return array_unique($parents); 33 38 } 34 39 35 40 public function getCommitDate($commit) {
-64
src/applications/repository/management/PhabricatorRepositoryManagementDeleteWorkflow.php
··· 1 - <?php 2 - 3 - final class PhabricatorRepositoryManagementDeleteWorkflow 4 - extends PhabricatorRepositoryManagementWorkflow { 5 - 6 - public function didConstruct() { 7 - $this 8 - ->setName('delete') 9 - ->setExamples('**delete** __repository__ ...') 10 - ->setSynopsis('Delete __repository__, named by callsign.') 11 - ->setArguments( 12 - array( 13 - array( 14 - 'name' => 'verbose', 15 - 'help' => 'Show additional debugging information.', 16 - ), 17 - array( 18 - 'name' => 'force', 19 - 'help' => 'Do not prompt for confirmation.', 20 - ), 21 - array( 22 - 'name' => 'repos', 23 - 'wildcard' => true, 24 - ), 25 - )); 26 - } 27 - 28 - public function execute(PhutilArgumentParser $args) { 29 - $repos = $this->loadRepositories($args, 'repos'); 30 - 31 - if (!$repos) { 32 - throw new PhutilArgumentUsageException( 33 - "Specify one or more repositories to delete, by callsign."); 34 - } 35 - 36 - $console = PhutilConsole::getConsole(); 37 - 38 - if (!$args->getArg('force')) { 39 - $console->writeOut("%s\n\n", pht('These repositories will be deleted:')); 40 - 41 - foreach ($repos as $repo) { 42 - $console->writeOut( 43 - " %s %s\n", 44 - 'r'.$repo->getCallsign(), 45 - $repo->getName()); 46 - } 47 - 48 - $prompt = pht('Permanently delete these repositories?'); 49 - if (!$console->confirm($prompt)) { 50 - return 1; 51 - } 52 - } 53 - 54 - foreach ($repos as $repo) { 55 - $console->writeOut("Deleting '%s'...\n", $repo->getCallsign()); 56 - $repo->delete(); 57 - } 58 - 59 - $console->writeOut("Done.\n"); 60 - 61 - return 0; 62 - } 63 - 64 - }
+41 -22
src/applications/repository/management/PhabricatorRepositoryManagementParentsWorkflow.php
··· 100 100 $bar = id(new PhutilConsoleProgressBar()) 101 101 ->setTotal(count($graph)); 102 102 103 + $need = array(); 103 104 foreach ($graph as $child => $parents) { 104 - $names = $parents; 105 - $names[] = $child; 105 + foreach ($parents as $parent) { 106 + $need[$parent] = $parent; 107 + } 108 + $need[$child] = $child; 109 + } 106 110 111 + $map = array(); 112 + foreach (array_chunk($need, 2048) as $chunk) { 107 113 $rows = queryfx_all( 108 114 $conn_w, 109 115 'SELECT id, commitIdentifier FROM %T 110 116 WHERE commitIdentifier IN (%Ls) AND repositoryID = %d', 111 117 $commit_table_name, 112 - $names, 118 + $chunk, 113 119 $repo->getID()); 120 + foreach ($rows as $row) { 121 + $map[$row['commitIdentifier']] = $row['id']; 122 + } 123 + } 114 124 115 - $map = ipull($rows, 'id', 'commitIdentifier'); 125 + $insert_sql = array(); 126 + $delete_sql = array(); 127 + 128 + foreach ($graph as $child => $parents) { 129 + $names = $parents; 130 + $names[] = $child; 131 + 116 132 foreach ($names as $name) { 117 133 if (empty($map[$name])) { 118 134 throw new Exception(pht('Unknown commit "%s"!', $name)); 119 135 } 120 136 } 121 137 122 - $sql = array(); 123 138 if (!$parents) { 124 139 // Write an explicit 0 to indicate "no parents" instead of "no data". 125 - $sql[] = qsprintf( 140 + $insert_sql[] = qsprintf( 126 141 $conn_w, 127 142 '(%d, 0)', 128 143 $map[$child]); 129 144 } else { 130 145 foreach ($parents as $parent) { 131 - $sql[] = qsprintf( 146 + $insert_sql[] = qsprintf( 132 147 $conn_w, 133 148 '(%d, %d)', 134 149 $map[$child], ··· 136 151 } 137 152 } 138 153 139 - $commit_table->openTransaction(); 140 - queryfx( 141 - $conn_w, 142 - 'DELETE FROM %T WHERE childCommitID = %d', 143 - PhabricatorRepository::TABLE_PARENTS, 144 - $map[$child]); 154 + $delete_sql[] = $map[$child]; 155 + 156 + $bar->update(1); 157 + } 145 158 146 - if ($sql) { 147 - queryfx( 148 - $conn_w, 149 - 'INSERT INTO %T (childCommitID, parentCommitID) VALUES %Q', 150 - PhabricatorRepository::TABLE_PARENTS, 151 - implode(', ', $sql)); 152 - } 153 - $commit_table->saveTransaction(); 159 + $commit_table->openTransaction(); 160 + foreach (PhabricatorLiskDAO::chunkSQL($delete_sql) as $chunk) { 161 + queryfx( 162 + $conn_w, 163 + 'DELETE FROM %T WHERE childCommitID IN (%Q)', 164 + PhabricatorRepository::TABLE_PARENTS, 165 + $chunk); 166 + } 154 167 155 - $bar->update(1); 168 + foreach (PhabricatorLiskDAO::chunkSQL($insert_sql) as $chunk) { 169 + queryfx( 170 + $conn_w, 171 + 'INSERT INTO %T (childCommitID, parentCommitID) VALUES %Q', 172 + PhabricatorRepository::TABLE_PARENTS, 173 + $chunk); 156 174 } 175 + $commit_table->saveTransaction(); 157 176 158 177 $bar->done(); 159 178 }
+13 -1
src/applications/repository/storage/PhabricatorRepository.php
··· 7 7 implements 8 8 PhabricatorPolicyInterface, 9 9 PhabricatorFlaggableInterface, 10 - PhabricatorMarkupInterface { 10 + PhabricatorMarkupInterface, 11 + PhabricatorDestructableInterface { 11 12 12 13 /** 13 14 * Shortest hash we'll recognize in raw "a829f32" form. ··· 1320 1321 1321 1322 public function shouldUseMarkupCache($field) { 1322 1323 return true; 1324 + } 1325 + 1326 + 1327 + /* -( PhabricatorDestructableInterface )----------------------------------- */ 1328 + 1329 + public function destroyObjectPermanently( 1330 + PhabricatorDestructionEngine $engine) { 1331 + 1332 + $this->openTransaction(); 1333 + $this->delete(); 1334 + $this->saveTransaction(); 1323 1335 } 1324 1336 1325 1337 }
+15 -12
src/applications/search/management/PhabricatorSearchManagementIndexWorkflow.php
··· 62 62 } 63 63 64 64 if (!$phids) { 65 - throw new PhutilArgumentUsageException( 66 - "Nothing to index!"); 65 + throw new PhutilArgumentUsageException('Nothing to index!'); 67 66 } 68 67 69 68 if ($args->getArg('background')) { ··· 73 72 $is_background = false; 74 73 } 75 74 75 + if (!$is_background) { 76 + $console->writeOut( 77 + "%s\n", 78 + pht( 79 + 'Run this workflow with "--background" to queue tasks for the '. 80 + 'daemon workers.')); 81 + } 82 + 76 83 $groups = phid_group_by_type($phids); 77 84 foreach ($groups as $group_type => $group) { 78 85 $console->writeOut( 79 86 "%s\n", 80 - pht( 81 - "Indexing %d object(s) of type %s.", 82 - count($group), 83 - $group_type)); 87 + pht('Indexing %d object(s) of type %s.', count($group), $group_type)); 84 88 } 85 89 90 + $bar = id(new PhutilConsoleProgressBar()) 91 + ->setTotal(count($phids)); 92 + 86 93 $indexer = new PhabricatorSearchIndexer(); 87 94 foreach ($phids as $phid) { 88 - if ($is_background) { 89 - $console->writeOut("%s\n", pht("Queueing '%s'...", $phid)); 90 - } else { 91 - $console->writeOut("%s\n", pht("Indexing '%s'...", $phid)); 92 - } 93 95 $indexer->queueDocumentForIndexing($phid); 96 + $bar->update(1); 94 97 } 95 98 96 - $console->writeOut("Done.\n"); 99 + $bar->done(); 97 100 } 98 101 99 102 private function loadPHIDsByNames(array $names) {
+3 -3
src/docs/user/installation_guide.diviner
··· 95 95 dependencies: 96 96 97 97 $ cd somewhere/ # pick some install directory 98 - somewhere/ $ git clone git://github.com/phacility/libphutil.git 99 - somewhere/ $ git clone git://github.com/phacility/arcanist.git 100 - somewhere/ $ git clone git://github.com/phacility/phabricator.git 98 + somewhere/ $ git clone https://github.com/phacility/libphutil.git 99 + somewhere/ $ git clone https://github.com/phacility/arcanist.git 100 + somewhere/ $ git clone https://github.com/phacility/phabricator.git 101 101 102 102 = Installing APC (Optional) = 103 103
+2 -2
src/docs/user/userguide/arcanist.diviner
··· 92 92 93 93 To install Arcanist, pick an install directory and clone the code from GitHub: 94 94 95 - some_install_path/ $ git clone git://github.com/phacility/libphutil.git 96 - some_install_path/ $ git clone git://github.com/phacility/arcanist.git 95 + some_install_path/ $ git clone https://github.com/phacility/libphutil.git 96 + some_install_path/ $ git clone https://github.com/phacility/arcanist.git 97 97 98 98 This should leave you with a directory structure like this 99 99
+2 -2
src/docs/user/userguide/arcanist_quick_start.diviner
··· 23 23 24 24 $ mkdir somewhere/ 25 25 $ cd somewhere/ 26 - somewhere/ $ git clone git://github.com/phacility/libphutil.git 27 - somewhere/ $ git clone git://github.com/phacility/arcanist.git 26 + somewhere/ $ git clone https://github.com/phacility/libphutil.git 27 + somewhere/ $ git clone https://github.com/phacility/arcanist.git 28 28 29 29 Add `arc` to your path: 30 30
+1 -2
support/aphlict/client/build_aphlict_client.sh
··· 12 12 13 13 $MXMLC \ 14 14 -output=$ROOT/webroot/rsrc/swf/aphlict.swf \ 15 - -default-background-color=0x444444 \ 16 - -default-size=500,500 \ 15 + -strict=true \ 17 16 -warnings=true \ 18 17 -source-path=$ROOT/externals/vegas/src \ 19 18 -static-link-runtime-shared-libraries=true \
+2 -2
webroot/rsrc/css/phui/phui-object-item-list-view.css
··· 659 659 margin-bottom: -1px; 660 660 } 661 661 662 - .dashboard-panel .phui-object-list-cards .phui-object-item { 662 + .dashboard-panel .phui-object-item-list-view .phui-object-item { 663 663 border-radius: 0; 664 - margin-bottom: 0; 664 + margin: 0; 665 665 background-image: none; 666 666 background-color: #fff; 667 667 border-left-width: 4px;
-1
webroot/rsrc/js/application/aphlict/behavior-aphlict-listen.js
··· 41 41 new JX.Notification() 42 42 .setContent('(Aphlict) [' + type + '] ' + details) 43 43 .alterClassName('jx-notification-debug', true) 44 - .setDuration(0) 45 44 .show(); 46 45 } 47 46 }
+7 -1
webroot/rsrc/js/core/behavior-line-linker.js
··· 10 10 var origin = null; 11 11 var target = null; 12 12 var root = null; 13 - var editor_link = JX.$('editor_link'); 13 + 14 + var editor_link = null; 15 + try { 16 + editor_link = JX.$('editor_link'); 17 + } catch (ex) { 18 + // Ignore. 19 + } 14 20 15 21 function getRowNumber(tr) { 16 22 var th = JX.DOM.find(tr, 'th', 'phabricator-source-line');