mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-24 06:20:56 +01:00
Add "bin/repository mark-reachable" for fixing commit reachability flags
Summary: Ref T9028. This corrects the reachability of existing commits in a repository. In particular, it can be used to mark deleted commits as unreachable. Test Plan: - Ran it on a bad repository, with bad args, etc. - Ran it on a clean repo, got no changes. - Marked a reachable commit as unreachable, ran script, got it marked reachable. - Started deleting tags and branches from the local working copy while running the script, saw greater parts of the repository get marked unreachable. - Pulled repository again, everything automatically revived. Reviewers: chad Reviewed By: chad Maniphest Tasks: T9028 Differential Revision: https://secure.phabricator.com/D16132
This commit is contained in:
parent
77ee518d88
commit
02d7bb8604
4 changed files with 148 additions and 12 deletions
|
@ -3263,6 +3263,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorRepositoryManagementListWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementListWorkflow.php',
|
||||
'PhabricatorRepositoryManagementLookupUsersWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementLookupUsersWorkflow.php',
|
||||
'PhabricatorRepositoryManagementMarkImportedWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMarkImportedWorkflow.php',
|
||||
'PhabricatorRepositoryManagementMarkReachableWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMarkReachableWorkflow.php',
|
||||
'PhabricatorRepositoryManagementMirrorWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMirrorWorkflow.php',
|
||||
'PhabricatorRepositoryManagementMovePathsWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMovePathsWorkflow.php',
|
||||
'PhabricatorRepositoryManagementParentsWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementParentsWorkflow.php',
|
||||
|
@ -8052,6 +8053,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorRepositoryManagementListWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||
'PhabricatorRepositoryManagementLookupUsersWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||
'PhabricatorRepositoryManagementMarkImportedWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||
'PhabricatorRepositoryManagementMarkReachableWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||
'PhabricatorRepositoryManagementMirrorWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||
'PhabricatorRepositoryManagementMovePathsWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||
'PhabricatorRepositoryManagementParentsWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||
|
|
|
@ -11,14 +11,20 @@ final class PhabricatorGitGraphStream
|
|||
|
||||
public function __construct(
|
||||
PhabricatorRepository $repository,
|
||||
$start_commit) {
|
||||
$start_commit = null) {
|
||||
|
||||
$this->repository = $repository;
|
||||
|
||||
if ($start_commit !== null) {
|
||||
$future = $repository->getLocalCommandFuture(
|
||||
'log --format=%s %s --',
|
||||
'%H%x01%P%x01%ct',
|
||||
$start_commit);
|
||||
} else {
|
||||
$future = $repository->getLocalCommandFuture(
|
||||
'log --format=%s --all --',
|
||||
'%H%x01%P%x01%ct');
|
||||
}
|
||||
|
||||
$this->iterator = new LinesOfALargeExecFuture($future);
|
||||
$this->iterator->setDelimiter("\n");
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorRepositoryManagementMarkReachableWorkflow
|
||||
extends PhabricatorRepositoryManagementWorkflow {
|
||||
|
||||
private $untouchedCount = 0;
|
||||
|
||||
protected function didConstruct() {
|
||||
$this
|
||||
->setName('mark-reachable')
|
||||
->setExamples('**mark-reachable** [__options__] __repository__ ...')
|
||||
->setSynopsis(
|
||||
pht(
|
||||
'Rebuild "unreachable" flags for commits in __repository__.'))
|
||||
->setArguments(
|
||||
array(
|
||||
array(
|
||||
'name' => 'repos',
|
||||
'wildcard' => true,
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
public function execute(PhutilArgumentParser $args) {
|
||||
$repos = $this->loadRepositories($args, 'repos');
|
||||
if (!$repos) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
pht(
|
||||
'Specify one or more repositories to correct reachability status '.
|
||||
'for.'));
|
||||
}
|
||||
|
||||
foreach ($repos as $repo) {
|
||||
$this->markReachable($repo);
|
||||
}
|
||||
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
pht(
|
||||
'Examined %s commits already in the correct state.',
|
||||
new PhutilNumber($this->untouchedCount)));
|
||||
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
pht('Done.'));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function markReachable(PhabricatorRepository $repository) {
|
||||
if (!$repository->isGit()) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
pht(
|
||||
'Only Git repositories are supported, this repository ("%s") is '.
|
||||
'not a Git repository.',
|
||||
$repository->getDisplayName()));
|
||||
}
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$commits = id(new DiffusionCommitQuery())
|
||||
->setViewer($viewer)
|
||||
->withRepository($repository)
|
||||
->execute();
|
||||
|
||||
$flag = PhabricatorRepositoryCommit::IMPORTED_UNREACHABLE;
|
||||
|
||||
$graph = new PhabricatorGitGraphStream($repository);
|
||||
foreach ($commits as $commit) {
|
||||
$identifier = $commit->getCommitIdentifier();
|
||||
|
||||
try {
|
||||
$graph->getCommitDate($identifier);
|
||||
$unreachable = false;
|
||||
} catch (Exception $ex) {
|
||||
$unreachable = true;
|
||||
}
|
||||
|
||||
// The commit has proper reachability, so do nothing.
|
||||
if ($commit->isUnreachable() === $unreachable) {
|
||||
$this->untouchedCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($unreachable) {
|
||||
echo tsprintf(
|
||||
"%s: %s\n",
|
||||
$commit->getMonogram(),
|
||||
pht('Marking commit unreachable.'));
|
||||
|
||||
$commit->writeImportStatusFlag($flag);
|
||||
} else {
|
||||
echo tsprintf(
|
||||
"%s: %s\n",
|
||||
$commit->getMonogram(),
|
||||
pht('Marking commit reachable.'));
|
||||
|
||||
$commit->clearImportStatusFlag($flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -64,13 +64,38 @@ final class PhabricatorRepositoryCommit
|
|||
}
|
||||
|
||||
public function writeImportStatusFlag($flag) {
|
||||
return $this->adjustImportStatusFlag($flag, true);
|
||||
}
|
||||
|
||||
public function clearImportStatusFlag($flag) {
|
||||
return $this->adjustImportStatusFlag($flag, false);
|
||||
}
|
||||
|
||||
private function adjustImportStatusFlag($flag, $set) {
|
||||
$conn_w = $this->establishConnection('w');
|
||||
$table_name = $this->getTableName();
|
||||
$id = $this->getID();
|
||||
|
||||
if ($set) {
|
||||
queryfx(
|
||||
$this->establishConnection('w'),
|
||||
$conn_w,
|
||||
'UPDATE %T SET importStatus = (importStatus | %d) WHERE id = %d',
|
||||
$this->getTableName(),
|
||||
$table_name,
|
||||
$flag,
|
||||
$this->getID());
|
||||
$id);
|
||||
|
||||
$this->setImportStatus($this->getImportStatus() | $flag);
|
||||
} else {
|
||||
queryfx(
|
||||
$conn_w,
|
||||
'UPDATE %T SET importStatus = (importStatus & ~%d) WHERE id = %d',
|
||||
$table_name,
|
||||
$flag,
|
||||
$id);
|
||||
|
||||
$this->setImportStatus($this->getImportStatus() & ~$flag);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue