Differential D21514 Diff 51213 src/applications/repository/engine/PhabricatorRepositoryRefEngine.php
Changeset View
Changeset View
Standalone View
Standalone View
src/applications/repository/engine/PhabricatorRepositoryRefEngine.php
<?php | <?php | ||||
/** | /** | ||||
* Update the ref cursors for a repository, which track the positions of | * Update the ref cursors for a repository, which track the positions of | ||||
* branches, bookmarks, and tags. | * branches, bookmarks, and tags. | ||||
*/ | */ | ||||
final class PhabricatorRepositoryRefEngine | final class PhabricatorRepositoryRefEngine | ||||
extends PhabricatorRepositoryEngine { | extends PhabricatorRepositoryEngine { | ||||
private $newPositions = array(); | private $newPositions = array(); | ||||
private $deadPositions = array(); | private $deadPositions = array(); | ||||
private $closeCommits = array(); | private $permanentCommits = array(); | ||||
private $rebuild; | private $rebuild; | ||||
public function setRebuild($rebuild) { | public function setRebuild($rebuild) { | ||||
$this->rebuild = $rebuild; | $this->rebuild = $rebuild; | ||||
return $this; | return $this; | ||||
} | } | ||||
public function getRebuild() { | public function getRebuild() { | ||||
return $this->rebuild; | return $this->rebuild; | ||||
} | } | ||||
public function updateRefs() { | public function updateRefs() { | ||||
$this->newPositions = array(); | $this->newPositions = array(); | ||||
$this->deadPositions = array(); | $this->deadPositions = array(); | ||||
$this->closeCommits = array(); | $this->permanentCommits = array(); | ||||
$repository = $this->getRepository(); | $repository = $this->getRepository(); | ||||
$viewer = $this->getViewer(); | $viewer = $this->getViewer(); | ||||
$branches_may_close = false; | $branches_may_close = false; | ||||
$vcs = $repository->getVersionControlSystem(); | $vcs = $repository->getVersionControlSystem(); | ||||
switch ($vcs) { | switch ($vcs) { | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | public function updateRefs() { | ||||
$all_closing_heads = array_unique($all_closing_heads); | $all_closing_heads = array_unique($all_closing_heads); | ||||
$all_closing_heads = $this->removeMissingCommits($all_closing_heads); | $all_closing_heads = $this->removeMissingCommits($all_closing_heads); | ||||
foreach ($maps as $type => $refs) { | foreach ($maps as $type => $refs) { | ||||
$cursor_group = idx($cursor_groups, $type, array()); | $cursor_group = idx($cursor_groups, $type, array()); | ||||
$this->updateCursors($cursor_group, $refs, $type, $all_closing_heads); | $this->updateCursors($cursor_group, $refs, $type, $all_closing_heads); | ||||
} | } | ||||
if ($this->closeCommits) { | if ($this->permanentCommits) { | ||||
$this->setCloseFlagOnCommits($this->closeCommits); | $this->setPermanentFlagOnCommits($this->permanentCommits); | ||||
} | } | ||||
$save_cursors = $this->getCursorsForUpdate($all_cursors); | $save_cursors = $this->getCursorsForUpdate($all_cursors); | ||||
if ($this->newPositions || $this->deadPositions || $save_cursors) { | if ($this->newPositions || $this->deadPositions || $save_cursors) { | ||||
$repository->openTransaction(); | $repository->openTransaction(); | ||||
$this->saveNewPositions(); | $this->saveNewPositions(); | ||||
▲ Show 20 Lines • Show All 103 Lines • ▼ Show 20 Lines | final class PhabricatorRepositoryRefEngine | ||||
} | } | ||||
private function markPositionDead( | private function markPositionDead( | ||||
PhabricatorRepositoryRefPosition $position) { | PhabricatorRepositoryRefPosition $position) { | ||||
$this->deadPositions[] = $position; | $this->deadPositions[] = $position; | ||||
return $this; | return $this; | ||||
} | } | ||||
private function markCloseCommits(array $identifiers) { | private function markPermanentCommits(array $identifiers) { | ||||
foreach ($identifiers as $identifier) { | foreach ($identifiers as $identifier) { | ||||
$this->closeCommits[$identifier] = $identifier; | $this->permanentCommits[$identifier] = $identifier; | ||||
} | } | ||||
return $this; | return $this; | ||||
} | } | ||||
/** | /** | ||||
* Remove commits which no longer exist in the repository from a list. | * Remove commits which no longer exist in the repository from a list. | ||||
* | * | ||||
* After a force push and garbage collection, we may have branch cursors which | * After a force push and garbage collection, we may have branch cursors which | ||||
▲ Show 20 Lines • Show All 141 Lines • ▼ Show 20 Lines | foreach ($ref_groups as $name => $refs) { | ||||
$exclude = $all_closing_heads; | $exclude = $all_closing_heads; | ||||
} | } | ||||
foreach ($update_commits as $identifier) { | foreach ($update_commits as $identifier) { | ||||
$new_identifiers = $this->loadNewCommitIdentifiers( | $new_identifiers = $this->loadNewCommitIdentifiers( | ||||
$identifier, | $identifier, | ||||
$exclude); | $exclude); | ||||
$this->markCloseCommits($new_identifiers); | $this->markPermanentCommits($new_identifiers); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
// Find any cursors for refs which no longer exist. This happens when a | // Find any cursors for refs which no longer exist. This happens when a | ||||
// branch, tag or bookmark is deleted. | // branch, tag or bookmark is deleted. | ||||
foreach ($cursors as $name => $cursor) { | foreach ($cursors as $name => $cursor) { | ||||
▲ Show 20 Lines • Show All 113 Lines • ▼ Show 20 Lines | switch ($vcs) { | ||||
} | } | ||||
return phutil_split_lines($stdout, $retain_newlines = false); | return phutil_split_lines($stdout, $retain_newlines = false); | ||||
default: | default: | ||||
throw new Exception(pht('Unsupported VCS "%s"!', $vcs)); | throw new Exception(pht('Unsupported VCS "%s"!', $vcs)); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Mark a list of commits as closeable, and queue workers for those commits | * Mark a list of commits as permanent, and queue workers for those commits | ||||
* which don't already have the flag. | * which don't already have the flag. | ||||
*/ | */ | ||||
private function setCloseFlagOnCommits(array $identifiers) { | private function setPermanentFlagOnCommits(array $identifiers) { | ||||
$repository = $this->getRepository(); | $repository = $this->getRepository(); | ||||
$commit_table = new PhabricatorRepositoryCommit(); | $commit_table = new PhabricatorRepositoryCommit(); | ||||
$conn = $commit_table->establishConnection('w'); | $conn = $commit_table->establishConnection('w'); | ||||
$vcs = $repository->getVersionControlSystem(); | $vcs = $repository->getVersionControlSystem(); | ||||
switch ($vcs) { | switch ($vcs) { | ||||
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: | case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: | ||||
$class = 'PhabricatorRepositoryGitCommitMessageParserWorker'; | $class = 'PhabricatorRepositoryGitCommitMessageParserWorker'; | ||||
Show All 25 Lines | foreach (PhabricatorLiskDAO::chunkSQL($identifier_tokens) as $chunk) { | ||||
$commit_table->getTableName(), | $commit_table->getTableName(), | ||||
$repository->getID(), | $repository->getID(), | ||||
$chunk); | $chunk); | ||||
foreach ($rows as $row) { | foreach ($rows as $row) { | ||||
$all_commits[] = $row; | $all_commits[] = $row; | ||||
} | } | ||||
} | } | ||||
$closeable_flag = PhabricatorRepositoryCommit::IMPORTED_CLOSEABLE; | $permanent_flag = PhabricatorRepositoryCommit::IMPORTED_PERMANENT; | ||||
$published_flag = PhabricatorRepositoryCommit::IMPORTED_PUBLISH; | $published_flag = PhabricatorRepositoryCommit::IMPORTED_PUBLISH; | ||||
$all_commits = ipull($all_commits, null, 'commitIdentifier'); | $all_commits = ipull($all_commits, null, 'commitIdentifier'); | ||||
foreach ($identifiers as $identifier) { | foreach ($identifiers as $identifier) { | ||||
$row = idx($all_commits, $identifier); | $row = idx($all_commits, $identifier); | ||||
if (!$row) { | if (!$row) { | ||||
throw new Exception( | throw new Exception( | ||||
pht( | pht( | ||||
'Commit "%s" has not been discovered yet! Run discovery before '. | 'Commit "%s" has not been discovered yet! Run discovery before '. | ||||
'updating refs.', | 'updating refs.', | ||||
$identifier)); | $identifier)); | ||||
} | } | ||||
$import_status = $row['importStatus']; | $import_status = $row['importStatus']; | ||||
if (!($import_status & $closeable_flag)) { | if (!($import_status & $permanent_flag)) { | ||||
// Set the "closeable" flag. | // Set the "permanent" flag. | ||||
$import_status = ($import_status | $closeable_flag); | $import_status = ($import_status | $permanent_flag); | ||||
// See T13580. Clear the "published" flag, so publishing executes | // See T13580. Clear the "published" flag, so publishing executes | ||||
// again. We may have previously performed a no-op "publish" on the | // again. We may have previously performed a no-op "publish" on the | ||||
// commit to make sure it has all bits in the "IMPORTED_ALL" bitmask. | // commit to make sure it has all bits in the "IMPORTED_ALL" bitmask. | ||||
$import_status = ($import_status & ~$published_flag); | $import_status = ($import_status & ~$published_flag); | ||||
queryfx( | queryfx( | ||||
$conn, | $conn, | ||||
▲ Show 20 Lines • Show All 140 Lines • Show Last 20 Lines |