Skip to content

Commit

Permalink
Fix cache invalidation issue when a git tag gets created on an old re…
Browse files Browse the repository at this point in the history
…f after the cache is populated, fixes #11002
  • Loading branch information
Seldaek committed Aug 17, 2022
1 parent c529087 commit d75545c
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/Composer/Downloader/GitDownloader.php
Expand Up @@ -75,7 +75,7 @@ protected function doDownload(PackageInterface $package, string $path, string $u
$this->io->writeError(" - Syncing <info>" . $package->getName() . "</info> (<comment>" . $package->getFullPrettyVersion() . "</comment>) into cache");
$this->io->writeError(sprintf(' Cloning to cache at %s', ProcessExecutor::escape($cachePath)), true, IOInterface::DEBUG);
$ref = $package->getSourceReference();
if ($this->gitUtil->fetchRefOrSyncMirror($url, $cachePath, $ref) && is_dir($cachePath)) {
if ($this->gitUtil->fetchRefOrSyncMirror($url, $cachePath, $ref, $package->getPrettyVersion()) && is_dir($cachePath)) {
$this->cachedPackages[$package->getId()][$ref] = true;
}
} elseif (null === $gitVersion) {
Expand Down
24 changes: 23 additions & 1 deletion src/Composer/Util/Git.php
Expand Up @@ -297,9 +297,31 @@ public function syncMirror(string $url, string $dir): bool
return true;
}

public function fetchRefOrSyncMirror(string $url, string $dir, string $ref): bool
public function fetchRefOrSyncMirror(string $url, string $dir, string $ref, string $prettyVersion = null): bool
{
if ($this->checkRefIsInMirror($dir, $ref)) {
if (Preg::isMatch('{^[a-f0-9]{40}$}', $ref) && $prettyVersion !== null) {
$branch = Preg::replace('{(?:^dev-|(?:\.x)?-dev$)}i', '', $prettyVersion);
$branches = null;
$tags = null;
if (0 === $this->process->execute('git branch', $output, $dir)) {
$branches = $output;
}
if (0 === $this->process->execute('git tag', $output, $dir)) {
$tags = $output;
}

// if the pretty version cannot be found as a branch (nor branch with 'v' in front of the branch as it may have been stripped when generating pretty name),
// nor as a tag, then we sync the mirror as otherwise it will likely fail during install.
// this can occur if a git tag gets created *after* the reference is already put into the cache, as the ref check above will then not sync the new tags
// see https://github.com/composer/composer/discussions/11002
if (null !== $branches && !Preg::isMatch('{^[\s*]*v?'.preg_quote($branch).'$}m', $branches)
&& null !== $tags && !Preg::isMatch('{^[\s*]*'.preg_quote($branch).'$}m', $tags)
) {
$this->syncMirror($url, $dir);
}
}

return true;
}

Expand Down

0 comments on commit d75545c

Please sign in to comment.