mirror of
https://we.phorge.it/source/phorge.git
synced 2025-04-02 23:48:18 +02: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',
|
'PhabricatorRepositoryManagementListWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementListWorkflow.php',
|
||||||
'PhabricatorRepositoryManagementLookupUsersWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementLookupUsersWorkflow.php',
|
'PhabricatorRepositoryManagementLookupUsersWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementLookupUsersWorkflow.php',
|
||||||
'PhabricatorRepositoryManagementMarkImportedWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMarkImportedWorkflow.php',
|
'PhabricatorRepositoryManagementMarkImportedWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMarkImportedWorkflow.php',
|
||||||
|
'PhabricatorRepositoryManagementMarkReachableWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMarkReachableWorkflow.php',
|
||||||
'PhabricatorRepositoryManagementMirrorWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMirrorWorkflow.php',
|
'PhabricatorRepositoryManagementMirrorWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMirrorWorkflow.php',
|
||||||
'PhabricatorRepositoryManagementMovePathsWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMovePathsWorkflow.php',
|
'PhabricatorRepositoryManagementMovePathsWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMovePathsWorkflow.php',
|
||||||
'PhabricatorRepositoryManagementParentsWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementParentsWorkflow.php',
|
'PhabricatorRepositoryManagementParentsWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementParentsWorkflow.php',
|
||||||
|
@ -8052,6 +8053,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorRepositoryManagementListWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
'PhabricatorRepositoryManagementListWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||||
'PhabricatorRepositoryManagementLookupUsersWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
'PhabricatorRepositoryManagementLookupUsersWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||||
'PhabricatorRepositoryManagementMarkImportedWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
'PhabricatorRepositoryManagementMarkImportedWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||||
|
'PhabricatorRepositoryManagementMarkReachableWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||||
'PhabricatorRepositoryManagementMirrorWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
'PhabricatorRepositoryManagementMirrorWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||||
'PhabricatorRepositoryManagementMovePathsWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
'PhabricatorRepositoryManagementMovePathsWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||||
'PhabricatorRepositoryManagementParentsWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
'PhabricatorRepositoryManagementParentsWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
|
||||||
|
|
|
@ -11,14 +11,20 @@ final class PhabricatorGitGraphStream
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
PhabricatorRepository $repository,
|
PhabricatorRepository $repository,
|
||||||
$start_commit) {
|
$start_commit = null) {
|
||||||
|
|
||||||
$this->repository = $repository;
|
$this->repository = $repository;
|
||||||
|
|
||||||
|
if ($start_commit !== null) {
|
||||||
$future = $repository->getLocalCommandFuture(
|
$future = $repository->getLocalCommandFuture(
|
||||||
'log --format=%s %s --',
|
'log --format=%s %s --',
|
||||||
'%H%x01%P%x01%ct',
|
'%H%x01%P%x01%ct',
|
||||||
$start_commit);
|
$start_commit);
|
||||||
|
} else {
|
||||||
|
$future = $repository->getLocalCommandFuture(
|
||||||
|
'log --format=%s --all --',
|
||||||
|
'%H%x01%P%x01%ct');
|
||||||
|
}
|
||||||
|
|
||||||
$this->iterator = new LinesOfALargeExecFuture($future);
|
$this->iterator = new LinesOfALargeExecFuture($future);
|
||||||
$this->iterator->setDelimiter("\n");
|
$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) {
|
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(
|
queryfx(
|
||||||
$this->establishConnection('w'),
|
$conn_w,
|
||||||
'UPDATE %T SET importStatus = (importStatus | %d) WHERE id = %d',
|
'UPDATE %T SET importStatus = (importStatus | %d) WHERE id = %d',
|
||||||
$this->getTableName(),
|
$table_name,
|
||||||
$flag,
|
$flag,
|
||||||
$this->getID());
|
$id);
|
||||||
|
|
||||||
$this->setImportStatus($this->getImportStatus() | $flag);
|
$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;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue