src/Composer/Downloader/GitDownloader.php
protected function updateToCommit($path, $reference, $branch, $date)
    {
        $force = $this->hasDiscardedChanges || $this->hasStashedChanges ? '-f ' : '';

        // This uses the "--" sequence to separate branch from file parameters.
        //
        // Otherwise git tries the branch name as well as file name.
        // If the non-existent branch is actually the name of a file, the file
        // is checked out.
        $template = 'git checkout '.$force.'%s -- && git reset --hard %1$s --';
        $branch = preg_replace('{(?:^dev-|(?:\.x)?-dev$)}i', '', $branch);

        $branches = null;
        if (0 === $this->process->execute('git branch -r', $output, $path)) {
            $branches = $output;
        }

        // check whether non-commitish are branches or tags, and fetch branches with the remote name
        $gitRef = $reference;
        if (!preg_match('{^[a-f0-9]{40}$}', $reference)
            && $branches
            && preg_match('{^\s+composer/'.preg_quote($reference).'$}m', $branches)
        ) {
            $command = sprintf('git checkout '.$force.'-B %s %s -- && git reset --hard %2$s --', ProcessExecutor::escape($branch), ProcessExecutor::escape('composer/'.$reference));
            if (0 === $this->process->execute($command, $output, $path)) {
                return;
            }
        }

        // try to checkout branch by name and then reset it so it's on the proper branch name
        if (preg_match('{^[a-f0-9]{40}$}', $reference)) {
            // add 'v' in front of the branch if it was stripped when generating the pretty name
            if (!preg_match('{^\s+composer/'.preg_quote($branch).'$}m', $branches) && preg_match('{^\s+composer/v'.preg_quote($branch).'$}m', $branches)) {
                $branch = 'v' . $branch;
            }

            $command = sprintf('git checkout %s --', ProcessExecutor::escape($branch));
            $fallbackCommand = sprintf('git checkout '.$force.'-B %s %s --', ProcessExecutor::escape($branch), ProcessExecutor::escape('composer/'.$branch));
            if (0 === $this->process->execute($command, $output, $path)
                || 0 === $this->process->execute($fallbackCommand, $output, $path)
            ) {
                $command = sprintf('git reset --hard %s --', ProcessExecutor::escape($reference));
                if (0 === $this->process->execute($command, $output, $path)) {
                    return;
                }
            }
        }

        $command = sprintf($template, ProcessExecutor::escape($gitRef));
        if (0 === $this->process->execute($command, $output, $path)) {
            return;
        }

        // reference was not found (prints "fatal: reference is not a tree: $ref")
        if (false !== strpos($this->process->getErrorOutput(), $reference)) {
            $this->io->writeError('    <warning>'.$reference.' is gone (history was rewritten?)</warning>');
        }

        throw new \RuntimeException(GitUtil::sanitizeUrl('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput()));
    }
protected function updateToCommit($path, $reference, $branch, $date)
    {
        $force = $this->hasDiscardedChanges || $this->hasStashedChanges ? '-f ' : '';

        // This uses the "--" sequence to separate branch from file parameters.
        //
        // Otherwise git tries the branch name as well as file name.
        // If the non-existent branch is actually the name of a file, the file
        // is checked out.
        $template = 'git checkout '.$force.'%s -- && git reset --hard %1$s --';
        $branch = preg_replace('{(?:^dev-|(?:\.x)?-dev$)}i', '', $branch);

        $branches = null;
        if (0 === $this->process->execute('git branch -r', $output, $path)) {
            $branches = $output;
        }

        // check whether non-commitish are branches or tags, and fetch branches with the remote name
        $gitRef = $reference;
        if (!preg_match('{^[a-f0-9]{40}$}', $reference)
            && $branches
            && preg_match('{^\s+composer/'.preg_quote($reference).'$}m', $branches)
        ) {
            $command = sprintf('git checkout '.$force.'-B %s %s -- && git reset --hard %2$s --', ProcessExecutor::escape($branch), ProcessExecutor::escape('composer/'.$reference));
            if (0 === $this->process->execute($command, $output, $path)) {
                return;
            }
        }

        // try to checkout branch by name and then reset it so it's on the proper branch name
        if (preg_match('{^[a-f0-9]{40}$}', $reference)) {
            // add 'v' in front of the branch if it was stripped when generating the pretty name
            if (!preg_match('{^\s+composer/'.preg_quote($branch).'$}m', $branches) && preg_match('{^\s+composer/v'.preg_quote($branch).'$}m', $branches)) {
                $branch = 'v' . $branch;
            }

            $command = sprintf('git checkout %s --', ProcessExecutor::escape($branch));
            $fallbackCommand = sprintf('git checkout '.$force.'-B %s %s --', ProcessExecutor::escape($branch), ProcessExecutor::escape('composer/'.$branch));
            if (0 === $this->process->execute($command, $output, $path)
                || 0 === $this->process->execute($fallbackCommand, $output, $path)
            ) {
                $command = sprintf('git reset --hard %s --', ProcessExecutor::escape($reference));
                if (0 === $this->process->execute($command, $output, $path)) {
                    return;
                }
            }
        }

        $command = sprintf($template, ProcessExecutor::escape($gitRef));
        if (0 === $this->process->execute($command, $output, $path)) {
            return;
        }

        // reference was not found (prints "fatal: reference is not a tree: $ref")
        if (false !== strpos($this->process->getErrorOutput(), $reference)) {
            $this->io->writeError('    <warning>'.$reference.' is gone (history was rewritten?)</warning>');
        }

        throw new \RuntimeException(GitUtil::sanitizeUrl('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput()));
    }
protected function updateToCommit ( $ path , $ reference , $ branch , $ date ) { $ force = $ this -> hasDiscardedChanges || $ this -> hasStashedChanges ? '-f ' : '' ; // This uses the "--" sequence to separate branch from file parameters. // // Otherwise git tries the branch name as well as file name. // If the non-existent branch is actually the name of a file, the file // is checked out. $ template = 'git checkout ' . $ force . '%s -- && git reset --hard %1$s --' ; $ branch = preg_replace ( '{(?:^dev-|(?:\.x)?-dev$)}i' , '' , $ branch ) ; $ branches = null ; if ( 0 === $ this -> process -> execute ( 'git branch -r' , $ output , $ path ) ) { $ branches = $ output ; } // check whether non-commitish are branches or tags, and fetch branches with the remote name $ gitRef = $ reference ; if ( ! preg_match ( '{^[a-f0-9]{40}$}' , $ reference ) && $ branches && preg_match ( '{^\s+composer/' . preg_quote ( $ reference ) . '$}m' , $ branches ) ) { $ command = sprintf ( 'git checkout ' . $ force . '-B %s %s -- && git reset --hard %2$s --' , ProcessExecutor :: escape ( $ branch ) , ProcessExecutor :: escape ( 'composer/' . $ reference ) ) ; if ( 0 === $ this -> process -> execute ( $ command , $ output , $ path ) ) { return ; } } // try to checkout branch by name and then reset it so it's on the proper branch name if ( preg_match ( '{^[a-f0-9]{40}$}' , $ reference ) ) { // add 'v' in front of the branch if it was stripped when generating the pretty name if ( ! preg_match ( '{^\s+composer/' . preg_quote ( $ branch ) . '$}m' , $ branches ) && preg_match ( '{^\s+composer/v' . preg_quote ( $ branch ) . '$}m' , $ branches ) ) { $ branch = 'v' . $ branch ; } $ command = sprintf ( 'git checkout %s --' , ProcessExecutor :: escape ( $ branch ) ) ; $ fallbackCommand = sprintf ( 'git checkout ' . $ force . '-B %s %s --' , ProcessExecutor :: escape ( $ branch ) , ProcessExecutor :: escape ( 'composer/' . $ branch ) ) ; if ( 0 === $ this -> process -> execute ( $ command , $ output , $ path ) || 0 === $ this -> process -> execute ( $ fallbackCommand , $ output , $ path ) ) { $ command = sprintf ( 'git reset --hard %s --' , ProcessExecutor :: escape ( $ reference ) ) ; if ( 0 === $ this -> process -> execute ( $ command , $ output , $ path ) ) { return ; } } } $ command = sprintf ( $ template , ProcessExecutor :: escape ( $ gitRef ) ) ; if ( 0 === $ this -> process -> execute ( $ command , $ output , $ path ) ) { return ; } // reference was not found (prints "fatal: reference is not a tree: $ref") if ( false !== strpos ( $ this -> process -> getErrorOutput ( ) , $ reference ) ) { $ this -> io -> writeError ( '    <warning>' . $ reference . ' is gone (history was rewritten?)</warning>' ) ; } throw new \ RuntimeException ( GitUtil :: sanitizeUrl ( 'Failed to execute ' . $ command . "\n\n" . $ this -> process -> getErrorOutput ( ) ) ) ; }
Updates the given path to the given commit ref

@param  string            $path
@param  string            $reference
@param  string            $branch
@param  \DateTime         $date
@throws \RuntimeException
@return null|string       if a string is returned, it is the commit reference that was checked out if the original could not be found
Updates the given path to the given commit ref