diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -2037,6 +2037,7 @@ 'PhabricatorRepositoryManagementMarkImportedWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMarkImportedWorkflow.php', 'PhabricatorRepositoryManagementMirrorWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMirrorWorkflow.php', 'PhabricatorRepositoryManagementParentsWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementParentsWorkflow.php', + 'PhabricatorRepositoryManagementPruneWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementPruneWorkflow.php', 'PhabricatorRepositoryManagementPullWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementPullWorkflow.php', 'PhabricatorRepositoryManagementRefsWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementRefsWorkflow.php', 'PhabricatorRepositoryManagementUpdateWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementUpdateWorkflow.php', @@ -4907,6 +4908,7 @@ 'PhabricatorRepositoryManagementMarkImportedWorkflow' => 'PhabricatorRepositoryManagementWorkflow', 'PhabricatorRepositoryManagementMirrorWorkflow' => 'PhabricatorRepositoryManagementWorkflow', 'PhabricatorRepositoryManagementParentsWorkflow' => 'PhabricatorRepositoryManagementWorkflow', + 'PhabricatorRepositoryManagementPruneWorkflow' => 'PhabricatorRepositoryManagementWorkflow', 'PhabricatorRepositoryManagementPullWorkflow' => 'PhabricatorRepositoryManagementWorkflow', 'PhabricatorRepositoryManagementRefsWorkflow' => 'PhabricatorRepositoryManagementWorkflow', 'PhabricatorRepositoryManagementUpdateWorkflow' => 'PhabricatorRepositoryManagementWorkflow', diff --git a/src/applications/repository/management/PhabricatorRepositoryManagementPruneWorkflow.php b/src/applications/repository/management/PhabricatorRepositoryManagementPruneWorkflow.php new file mode 100644 --- /dev/null +++ b/src/applications/repository/management/PhabricatorRepositoryManagementPruneWorkflow.php @@ -0,0 +1,82 @@ +setName('prune') + ->setExamples('**prune** __repository__ ...') + ->setSynopsis('Prune __repository__, removing orphaned commits from repository named by callsign.') + ->setArguments( + array( + array( + 'name' => 'verbose', + 'help' => 'Show additional debugging information.', + ), + array( + 'name' => 'repos', + 'wildcard' => true, + ), + )); + } + + public function execute(PhutilArgumentParser $args) { + $repos = $this->loadRepositories($args, 'repos'); + + if (!$repos) { + throw new PhutilArgumentUsageException( + 'Specify one or more repositories to prune, by callsign.'); + } + + $console = PhutilConsole::getConsole(); + foreach ($repos as $repo) { + $console->writeOut("Pruning '%s'...\n", $repo->getCallsign()); + + $commits = id(new DiffusionCommitQuery) + ->withRepository($repo) + ->setViewer(PhabricatorUser::getOmnipotentUser()) + ->execute(); + $bad_commits = array(); + + $console->writeOut("For each commit we have record of in phabricator, " + ."we will try to resolve it in the VCS. This will show errors for any " + ."that are missing.\n"); + + foreach ($commits as $commit) { + $out = $repo->execLocalCommand( + 'show %s', + $commit->getCommitIdentifier()); + + if (array_shift($out) == 128) { + $console->writeOut(trim(implode($out,"\n"))."\n"); + $bad_commits[] = $commit; + } + } + + if (count($bad_commits) == 0) { + $console->writeOut("No orphaned commits.\n"); + continue; + } + + $ok = $console->confirm( + pht( + 'Found %d orphaned commits out of %d total commits. Are you ' + .'absolutely certain you want to destroy the commits listed above?', + new PhutilNumber(count($bad_commits)), + new PhutilNumber(count($commits)) + )); + if (!$ok) { + throw new PhutilArgumentUsageException( + pht('Aborted, your commits are safe.')); + } + + foreach ($bad_commits as $commit) { + $commit->delete(); + } + } + + return 0; + } + +}