1
0
Fork 0

Don't fetch when ref already on local

pull/6684/head
Robert Lu 2017-09-13 19:50:02 +08:00
parent bfed974ae9
commit 0ad985122d
2 changed files with 36 additions and 9 deletions

View File

@ -12,13 +12,13 @@
namespace Composer\Downloader; namespace Composer\Downloader;
use Composer\Config;
use Composer\IO\IOInterface;
use Composer\Package\PackageInterface; use Composer\Package\PackageInterface;
use Composer\Util\Filesystem;
use Composer\Util\Git as GitUtil; use Composer\Util\Git as GitUtil;
use Composer\Util\Platform; use Composer\Util\Platform;
use Composer\Util\ProcessExecutor; use Composer\Util\ProcessExecutor;
use Composer\IO\IOInterface;
use Composer\Util\Filesystem;
use Composer\Config;
/** /**
* @author Jordi Boggiano <j.boggiano@seld.be> * @author Jordi Boggiano <j.boggiano@seld.be>
@ -43,30 +43,41 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
GitUtil::cleanEnv(); GitUtil::cleanEnv();
$path = $this->normalizePath($path); $path = $this->normalizePath($path);
$cachePath = $this->config->get('cache-vcs-dir').'/'.preg_replace('{[^a-z0-9.]}i', '-', $url).'/'; $cachePath = $this->config->get('cache-vcs-dir').'/'.preg_replace('{[^a-z0-9.]}i', '-', $url).'/';
$cacheOptions = '';
$ref = $package->getSourceReference(); $ref = $package->getSourceReference();
$flag = Platform::isWindows() ? '/D ' : ''; $flag = Platform::isWindows() ? '/D ' : '';
// --dissociate option is only available since git 2.3.0-rc0 // --dissociate option is only available since git 2.3.0-rc0
$gitVersion = $this->gitUtil->getVersion(); $gitVersion = $this->gitUtil->getVersion();
$msg = "Cloning ".$this->getShortHash($ref); $msg = "Cloning ".$this->getShortHash($ref);
$command = 'git clone --no-checkout %url% %path% && cd '.$flag.'%path% && git remote add composer %url% && git fetch composer';
if ($gitVersion && version_compare($gitVersion, '2.3.0-rc0', '>=')) { if ($gitVersion && version_compare($gitVersion, '2.3.0-rc0', '>=')) {
$this->io->writeError('', true, IOInterface::DEBUG); $this->io->writeError('', true, IOInterface::DEBUG);
$this->io->writeError(sprintf(' Cloning to cache at %s', ProcessExecutor::escape($cachePath)), true, IOInterface::DEBUG); $this->io->writeError(sprintf(' Cloning to cache at %s', ProcessExecutor::escape($cachePath)), true, IOInterface::DEBUG);
try { try {
$this->gitUtil->syncMirror($url, $cachePath); $this->gitUtil->lazySyncMirror($url, $cachePath, $ref);
if (is_dir($cachePath)) { if (is_dir($cachePath)) {
$cacheOptions = sprintf('--dissociate --reference %s ', ProcessExecutor::escape($cachePath)); $command =
'git clone --no-checkout %cachePath% %path% --dissociate --reference %cachePath% '
. '&& cd '.$flag.'%path% '
. '&& git remote set-url origin %url% && git remote add composer %url%';
$msg = "Cloning ".$this->getShortHash($ref).' from cache'; $msg = "Cloning ".$this->getShortHash($ref).' from cache';
} }
} catch (\RuntimeException $e) { } catch (\RuntimeException $e) {
} }
} }
$command = 'git clone --no-checkout %s %s '.$cacheOptions.'&& cd '.$flag.'%2$s && git remote add composer %1$s && git fetch composer';
$this->io->writeError($msg); $this->io->writeError($msg);
$commandCallable = function ($url) use ($ref, $path, $command) { $commandCallable = function ($url) use ($path, $command, $cachePath) {
return sprintf($command, ProcessExecutor::escape($url), ProcessExecutor::escape($path), ProcessExecutor::escape($ref)); return str_replace(
array('%url%', '%path%', '%cachePath%'),
array(
ProcessExecutor::escape($url),
ProcessExecutor::escape($path),
ProcessExecutor::escape($cachePath),
),
$command
);
}; };
$this->gitUtil->runCommand($commandCallable, $url, $path, true); $this->gitUtil->runCommand($commandCallable, $url, $path, true);

View File

@ -228,6 +228,22 @@ class Git
return true; return true;
} }
public function lazySyncMirror($url, $dir, $ref)
{
if (is_dir($dir) && 0 === $this->process->execute('git rev-parse --git-dir', $output, $dir) && trim($output) === '.') {
try {
$commandCallable = function ($ref) {
return sprintf('git cat-file -t %s', ProcessExecutor::escape($ref));
};
$this->runCommand($commandCallable, $ref, $dir);
return true;
} catch (\Exception $e) {
}
}
return $this->syncMirror($url, $dir);
}
private function isAuthenticationFailure($url, &$match) private function isAuthenticationFailure($url, &$match)
{ {
if (!preg_match('{(https?://)([^/]+)(.*)$}i', $url, $match)) { if (!preg_match('{(https?://)([^/]+)(.*)$}i', $url, $match)) {