<commit_before><?php

/*
 * This file is part of Composer.
 *
 * (c) <NAME> <<EMAIL>>
 *     <NAME> <<EMAIL>>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Composer\Downloader;

use Composer\Package\PackageInterface;
use Composer\Util\Git as GitUtil;
use Composer\Util\Platform;
use Composer\Util\ProcessExecutor;
use Composer\IO\IOInterface;
use Composer\Util\Filesystem;
use Composer\Config;

/**
 * @author <NAME> <<EMAIL>>
 */
class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
{
    private $hasStashedChanges = false;
    private $hasDiscardedChanges = false;
    private $gitUtil;

    public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, Filesystem $fs = null)
    {
        parent::__construct($io, $config, $process, $fs);
        $this->gitUtil = new GitUtil($this->io, $this->config, $this->process, $this->filesystem);
    }

    /**
     * {@inheritDoc}
     */
    public function doDownload(PackageInterface $package, $path, $url)
    {
        GitUtil::cleanEnv();
        $path = $this->normalizePath($path);
        $cachePath = $this->config->get('cache-vcs-dir').'/'.preg_replace('{[^a-z0-9.]}i', '-', $url).'/';
        $cacheOptions = file_exists($cachePath) ? '--dissociate --reference '.ProcessExecutor::escape($cachePath).' ' : '';

        $ref = $package->getSourceReference();
        $flag = Platform::isWindows() ? '/D ' : '';
        $command = 'git clone --no-checkout %s %s '.$cacheOptions.'&& cd '.$flag.'%2$s && git remote add composer %1$s && git fetch composer';
        $this->io->writeError("    Cloning ".$ref);

        $commandCallable = function ($url) use ($ref, $path, $command) {
            return sprintf($command, ProcessExecutor::escape($url), ProcessExecutor::escape($path), ProcessExecutor::escape($ref));
        };

        $this->gitUtil->runCommand($commandCallable, $url, $path, true);
        if ($url !== $package->getSourceUrl()) {
            $this->updateOriginUrl($path, $package->getSourceUrl());
        } else {
            $this->setPushUrl($path, $url);
        }

        if ($newRef = $this->updateToCommit($path, $ref, $package->getPrettyVersion(), $package->getReleaseDate())) {
            if ($package->getDistReference() === $package->getSourceReference()) {
                $package->setDistReference($newRef);
            }
            $package->setSourceReference($newRef);
        }<commit_msg>Use git cache path to mirror the repository before download to vendor target.<commit_after><?php

/*
 * This file is part of Composer.
 *
 * (c) <NAME> <<EMAIL>>
 *     <NAME> <<EMAIL>>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Composer\Downloader;

use Composer\Package\PackageInterface;
use Composer\Util\Git as GitUtil;
use Composer\Util\Platform;
use Composer\Util\ProcessExecutor;
use Composer\IO\IOInterface;
use Composer\Util\Filesystem;
use Composer\Config;

/**
 * @author <NAME> <<EMAIL>>
 */
class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
{
    private $hasStashedChanges = false;
    private $hasDiscardedChanges = false;
    private $gitUtil;

    public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, Filesystem $fs = null)
    {
        parent::__construct($io, $config, $process, $fs);
        $this->gitUtil = new GitUtil($this->io, $this->config, $this->process, $this->filesystem);
    }

    /**
     * {@inheritDoc}
     */
    public function doDownload(PackageInterface $package, $path, $url)
    {
        GitUtil::cleanEnv();
        $path = $this->normalizePath($path);
        $cachePath = $this->config->get('cache-vcs-dir').'/'.preg_replace('{[^a-z0-9.]}i', '-', $url).'/';
        $ref = $package->getSourceReference();
        $flag = Platform::isWindows() ? '/D ' : '';

        // --dissociate option is only available since git 2.3.0-rc0
        if (version_compare($this->gitUtil->getVersion(), '2.3.0-rc0', '>=')) {
            if (!file_exists($cachePath)) {
                $this->io->writeError(sprintf('    Cloning to cache at %s', ProcessExecutor::escape($cachePath)));
                $mirrorCommand = 'git clone --mirror %s %s';
                $mirrorCommandCallable = function ($url) use ($cachePath, $mirrorCommand) {
                    return sprintf($mirrorCommand, ProcessExecutor::escape($url), ProcessExecutor::escape($cachePath));
                };
                $this->gitUtil->runCommand($mirrorCommandCallable, $url, $path, true);
            }
        }
        $cacheOptions = file_exists($cachePath) ? '--dissociate --reference '.ProcessExecutor::escape($cachePath).' ' : '';
        $command = 'git clone --no-checkout %s %s '.$cacheOptions.'&& cd '.$flag.'%2$s && git remote add composer %1$s && git fetch composer';
        $this->io->writeError("    Cloning ".$ref);

        $commandCallable = function ($url) use ($ref, $path, $command) {
            return sprintf($command, ProcessExecutor::escape($url), ProcessExecutor::escape($path), ProcessExecutor::escape($ref));
        };

        $this->gitUtil->runCommand($commandCallable, $url, $path, true);
        if ($url !== $package->getSourceUrl()) {
            $this->updateOriginUrl($path, $package->getSourceUrl());
        } else {
            $this->setPushUrl($path, $url);
        }

        if ($newRef = $this->updateToCommit($path, $ref, $package->getPrettyVersion(), $package->getReleaseDate())) {
            if ($package->getDistReference() === $package->getSourceReference()) {
                $package->setDistReference($newRef);
            }
            $package->setSourceReference($newRef);
        }
{'fraction_non_alphanumeric': 0.1658411614005124, 'fraction_numerical': 0.0027327070879590095, 'mean_word_length': 3.1037140854940435, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 76, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 11, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2877431', 'n_tokens_mistral': 1728, 'n_tokens_neox': 1698, 'n_words': 384}