2011-04-17 22:14:44 +00:00
< ? php
/*
* This file is part of Composer .
*
* ( c ) Nils Adermann < naderman @ naderman . de >
* Jordi Boggiano < j . boggiano @ seld . be >
*
* 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 ;
2012-10-21 15:56:57 +00:00
use Composer\Util\GitHub ;
2011-04-17 22:14:44 +00:00
/**
* @ author Jordi Boggiano < j . boggiano @ seld . be >
*/
2012-01-22 20:14:56 +00:00
class GitDownloader extends VcsDownloader
2011-04-17 22:14:44 +00:00
{
2012-10-07 13:19:55 +00:00
private $hasStashedChanges = false ;
2011-09-25 10:39:08 +00:00
/**
* { @ inheritDoc }
*/
2012-01-22 20:14:56 +00:00
public function doDownload ( PackageInterface $package , $path )
2011-09-25 10:39:08 +00:00
{
2013-05-27 17:54:46 +00:00
$this -> cleanEnv ();
2013-06-08 15:49:51 +00:00
$path = $this -> normalizePath ( $path );
2013-05-27 17:54:46 +00:00
2012-04-04 15:11:50 +00:00
$ref = $package -> getSourceReference ();
2013-06-08 14:41:34 +00:00
$flag = defined ( 'PHP_WINDOWS_VERSION_MAJOR' ) ? '/D ' : '' ;
$command = 'git clone %s %s && cd ' . $flag . '%2$s && git remote add composer %1$s && git fetch composer' ;
2012-06-20 09:46:59 +00:00
$this -> io -> write ( " Cloning " . $ref );
2012-03-06 23:58:37 +00:00
2012-03-10 16:49:08 +00:00
$commandCallable = function ( $url ) use ( $ref , $path , $command ) {
2012-04-04 15:11:50 +00:00
return sprintf ( $command , escapeshellarg ( $url ), escapeshellarg ( $path ), escapeshellarg ( $ref ));
2012-03-10 16:49:08 +00:00
};
2013-04-28 09:12:09 +00:00
$this -> runCommand ( $commandCallable , $package -> getSourceUrl (), $path , true );
2012-04-03 17:49:57 +00:00
$this -> setPushUrl ( $package , $path );
2012-06-20 09:46:59 +00:00
2012-06-20 10:05:18 +00:00
$this -> updateToCommit ( $path , $ref , $package -> getPrettyVersion (), $package -> getReleaseDate ());
2011-09-28 22:48:17 +00:00
}
2011-09-25 10:39:08 +00:00
2011-09-28 22:48:17 +00:00
/**
* { @ inheritDoc }
*/
2012-01-22 20:14:56 +00:00
public function doUpdate ( PackageInterface $initial , PackageInterface $target , $path )
2011-04-17 22:14:44 +00:00
{
2013-05-27 17:54:46 +00:00
$this -> cleanEnv ();
2013-06-08 15:49:51 +00:00
$path = $this -> normalizePath ( $path );
2013-05-27 17:54:46 +00:00
2012-04-04 15:11:50 +00:00
$ref = $target -> getSourceReference ();
2012-06-20 09:46:59 +00:00
$this -> io -> write ( " Checking out " . $ref );
2013-04-28 09:12:09 +00:00
$command = 'git remote set-url composer %s && git fetch composer && git fetch --tags composer' ;
2012-03-10 16:49:08 +00:00
2012-10-01 17:56:41 +00:00
// capture username/password from URL if there is one
2013-04-28 09:12:09 +00:00
$this -> process -> execute ( 'git remote -v' , $output , $path );
2013-03-10 13:47:36 +00:00
if ( preg_match ( '{^(?:composer|origin)\s+https?://(.+):(.+)@([^/]+)}im' , $output , $match )) {
2013-03-11 09:04:45 +00:00
$this -> io -> setAuthentication ( $match [ 3 ], urldecode ( $match [ 1 ]), urldecode ( $match [ 2 ]));
2012-05-06 15:19:30 +00:00
}
2013-04-28 09:12:09 +00:00
$commandCallable = function ( $url ) use ( $command ) {
return sprintf ( $command , escapeshellarg ( $url ));
2012-03-10 16:49:08 +00:00
};
2013-04-28 09:12:09 +00:00
$this -> runCommand ( $commandCallable , $target -> getSourceUrl (), $path );
2012-06-20 10:05:18 +00:00
$this -> updateToCommit ( $path , $ref , $target -> getPrettyVersion (), $target -> getReleaseDate ());
2012-06-20 09:46:59 +00:00
}
2012-06-25 23:18:10 +00:00
/**
* { @ inheritDoc }
*/
2012-08-18 12:34:24 +00:00
public function getLocalChanges ( $path )
2012-06-25 23:18:10 +00:00
{
2013-06-08 15:49:51 +00:00
$path = $this -> normalizePath ( $path );
2012-11-20 13:32:57 +00:00
if ( ! is_dir ( $path . '/.git' )) {
return ;
}
2013-04-28 09:12:09 +00:00
$command = 'git status --porcelain --untracked-files=no' ;
if ( 0 !== $this -> process -> execute ( $command , $output , $path )) {
2012-06-25 23:18:10 +00:00
throw new \RuntimeException ( 'Failed to execute ' . $command . " \n \n " . $this -> process -> getErrorOutput ());
}
2012-08-18 12:34:24 +00:00
return trim ( $output ) ? : null ;
2012-06-25 23:18:10 +00:00
}
2012-10-07 13:19:55 +00:00
/**
2012-10-10 11:46:49 +00:00
* { @ inheritDoc }
2012-10-07 13:19:55 +00:00
*/
protected function cleanChanges ( $path , $update )
{
2013-06-08 15:49:51 +00:00
$path = $this -> normalizePath ( $path );
2013-02-28 18:44:29 +00:00
if ( ! $changes = $this -> getLocalChanges ( $path )) {
return ;
}
2012-10-07 13:19:55 +00:00
if ( ! $this -> io -> isInteractive ()) {
2013-03-01 22:47:24 +00:00
$discardChanges = $this -> config -> get ( 'discard-changes' );
if ( true === $discardChanges ) {
return $this -> discardChanges ( $path );
}
if ( 'stash' === $discardChanges ) {
if ( ! $update ) {
2013-02-28 16:10:04 +00:00
return parent :: cleanChanges ( $path , $update );
2013-03-01 22:47:24 +00:00
}
return $this -> stashChanges ( $path );
2013-02-28 16:10:04 +00:00
}
2013-03-01 22:47:24 +00:00
return parent :: cleanChanges ( $path , $update );
2012-10-07 13:19:55 +00:00
}
$changes = array_map ( function ( $elem ) {
return ' ' . $elem ;
}, preg_split ( '{\s*\r?\n\s*}' , $changes ));
$this -> io -> write ( ' <error>The package has modified files:</error>' );
$this -> io -> write ( array_slice ( $changes , 0 , 10 ));
if ( count ( $changes ) > 10 ) {
$this -> io -> write ( ' <info>' . count ( $changes ) - 10 . ' more files modified, choose "v" to view the full list</info>' );
}
while ( true ) {
switch ( $this -> io -> ask ( ' <info>Discard changes [y,n,v,' . ( $update ? 's,' : '' ) . '?]?</info> ' , '?' )) {
case 'y' :
2013-02-28 16:10:04 +00:00
$this -> discardChanges ( $path );
2012-10-07 13:19:55 +00:00
break 2 ;
case 's' :
if ( ! $update ) {
goto help ;
}
2013-02-28 16:10:04 +00:00
$this -> stashChanges ( $path );
2012-10-07 13:19:55 +00:00
break 2 ;
case 'n' :
throw new \RuntimeException ( 'Update aborted' );
case 'v' :
$this -> io -> write ( $changes );
break ;
case '?' :
default :
help :
$this -> io -> write ( array (
' y - discard changes and apply the ' . ( $update ? 'update' : 'uninstall' ),
' n - abort the ' . ( $update ? 'update' : 'uninstall' ) . ' and let you manually clean things up' ,
' v - view modified files' ,
));
if ( $update ) {
$this -> io -> write ( ' s - stash changes and try to reapply them after the update' );
}
$this -> io -> write ( ' ? - print help' );
break ;
}
}
}
/**
2012-10-10 11:46:49 +00:00
* { @ inheritDoc }
2012-10-07 13:19:55 +00:00
*/
protected function reapplyChanges ( $path )
{
2013-06-08 15:49:51 +00:00
$path = $this -> normalizePath ( $path );
2012-10-07 13:19:55 +00:00
if ( $this -> hasStashedChanges ) {
2012-10-24 10:30:11 +00:00
$this -> hasStashedChanges = false ;
2012-10-07 13:19:55 +00:00
$this -> io -> write ( ' <info>Re-applying stashed changes' );
if ( 0 !== $this -> process -> execute ( 'git stash pop' , $output , $path )) {
throw new \RuntimeException ( " Failed to apply stashed changes: \n \n " . $this -> process -> getErrorOutput ());
}
}
}
2012-06-20 09:46:59 +00:00
protected function updateToCommit ( $path , $reference , $branch , $date )
{
$template = 'git checkout %s && git reset --hard %1$s' ;
2012-10-17 09:29:26 +00:00
$branch = preg_replace ( '{(?:^dev-|(?:\.x)?-dev$)}i' , '' , $branch );
2012-06-20 09:46:59 +00:00
2012-10-19 09:43:49 +00:00
$branches = null ;
if ( 0 === $this -> process -> execute ( 'git branch -r' , $output , $path )) {
$branches = $output ;
}
2012-07-10 17:02:06 +00:00
// 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 )
2012-10-19 09:43:49 +00:00
&& $branches
2012-07-10 17:02:06 +00:00
&& preg_match ( '{^\s+composer/' . preg_quote ( $reference ) . '$}m' , $output )
) {
2012-10-17 09:29:26 +00:00
$command = sprintf ( 'git checkout -B %s %s && git reset --hard %2$s' , escapeshellarg ( $branch ), escapeshellarg ( 'composer/' . $reference ));
if ( 0 === $this -> process -> execute ( $command , $output , $path )) {
return ;
}
2012-07-10 17:02:06 +00:00
}
2012-10-17 15:15:49 +00:00
// 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 )) {
2012-10-19 09:43:49 +00:00
// 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 ;
}
2012-10-17 15:15:49 +00:00
$command = sprintf ( 'git checkout %s' , escapeshellarg ( $branch ));
$fallbackCommand = sprintf ( 'git checkout -B %s %s' , escapeshellarg ( $branch ), escapeshellarg ( 'composer/' . $branch ));
if ( 0 === $this -> process -> execute ( $command , $output , $path )
|| 0 === $this -> process -> execute ( $fallbackCommand , $output , $path )
) {
$command = sprintf ( 'git reset --hard %s' , escapeshellarg ( $reference ));
if ( 0 === $this -> process -> execute ( $command , $output , $path )) {
return ;
}
2012-10-17 08:49:54 +00:00
}
}
2012-07-10 17:02:06 +00:00
$command = sprintf ( $template , escapeshellarg ( $gitRef ));
2012-06-20 09:46:59 +00:00
if ( 0 === $this -> process -> execute ( $command , $output , $path )) {
return ;
}
// reference was not found (prints "fatal: reference is not a tree: $ref")
2012-06-20 10:05:18 +00:00
if ( $date && false !== strpos ( $this -> process -> getErrorOutput (), $reference )) {
$date = $date -> format ( 'U' );
2012-06-20 09:46:59 +00:00
2012-06-20 10:09:09 +00:00
// guess which remote branch to look at first
2012-06-20 09:46:59 +00:00
$command = 'git branch -r' ;
2012-06-20 10:09:09 +00:00
if ( 0 !== $this -> process -> execute ( $command , $output , $path )) {
2012-06-20 09:46:59 +00:00
throw new \RuntimeException ( 'Failed to execute ' . $command . " \n \n " . $this -> process -> getErrorOutput ());
}
$guessTemplate = 'git log --until=%s --date=raw -n1 --pretty=%%H %s' ;
foreach ( $this -> process -> splitLines ( $output ) as $line ) {
if ( preg_match ( '{^composer/' . preg_quote ( $branch ) . '(?:\.x)?$}i' , trim ( $line ))) {
2012-06-20 10:09:09 +00:00
// find the previous commit by date in the given branch
2012-06-20 09:46:59 +00:00
if ( 0 === $this -> process -> execute ( sprintf ( $guessTemplate , $date , escapeshellarg ( trim ( $line ))), $output , $path )) {
$newReference = trim ( $output );
}
break ;
}
}
if ( empty ( $newReference )) {
2012-06-20 10:09:09 +00:00
// no matching branch found, find the previous commit by date in all commits
2012-06-20 09:46:59 +00:00
if ( 0 !== $this -> process -> execute ( sprintf ( $guessTemplate , $date , '--all' ), $output , $path )) {
2012-10-10 21:47:53 +00:00
throw new \RuntimeException ( 'Failed to execute ' . $this -> sanitizeUrl ( $command ) . " \n \n " . $this -> process -> getErrorOutput ());
2012-06-20 09:46:59 +00:00
}
$newReference = trim ( $output );
}
2012-06-20 10:09:09 +00:00
// checkout the new recovered ref
2012-07-10 17:02:06 +00:00
$command = sprintf ( $template , escapeshellarg ( $reference ));
2012-06-20 09:46:59 +00:00
if ( 0 === $this -> process -> execute ( $command , $output , $path )) {
$this -> io -> write ( ' ' . $reference . ' is gone (history was rewritten?), recovered by checking out ' . $newReference );
return ;
}
}
2012-10-10 21:47:53 +00:00
throw new \RuntimeException ( 'Failed to execute ' . $this -> sanitizeUrl ( $command ) . " \n \n " . $this -> process -> getErrorOutput ());
2011-04-17 22:14:44 +00:00
}
2012-03-10 16:49:08 +00:00
/**
* Runs a command doing attempts for each protocol supported by github .
*
2012-05-22 10:07:08 +00:00
* @ param callable $commandCallable A callable building the command for the given url
* @ param string $url
2013-04-28 09:12:09 +00:00
* @ param string $cwd
* @ param bool $initialClone If true , the directory if cleared between every attempt
2013-06-13 00:05:44 +00:00
* @ throws \InvalidArgumentException
2012-03-10 16:49:08 +00:00
* @ throws \RuntimeException
*/
2013-04-28 09:12:09 +00:00
protected function runCommand ( $commandCallable , $url , $cwd , $initialClone = false )
2012-03-10 16:49:08 +00:00
{
2013-04-28 09:12:09 +00:00
if ( $initialClone ) {
$origCwd = $cwd ;
2013-04-29 15:27:02 +00:00
$cwd = null ;
2013-04-28 09:12:09 +00:00
}
2012-12-05 22:23:01 +00:00
if ( preg_match ( '{^ssh://[^@]+@[^:]+:[^0-9]+}' , $url )) {
throw new \InvalidArgumentException ( 'The source URL ' . $url . ' is invalid, ssh URLs should have a port number after ":".' . " \n " . 'Use ssh://git@example.com:22/path or just git@example.com:path if you do not want to provide a password or custom port.' );
}
2012-06-27 16:00:52 +00:00
// public github, autoswitch protocols
2012-09-07 22:45:18 +00:00
if ( preg_match ( '{^(?:https?|git)(://github.com/.*)}' , $url , $match )) {
$protocols = $this -> config -> get ( 'github-protocols' );
if ( ! is_array ( $protocols )) {
throw new \RuntimeException ( 'Config value "github-protocols" must be an array, got ' . gettype ( $protocols ));
}
2012-05-18 12:41:57 +00:00
$messages = array ();
2012-03-10 16:49:08 +00:00
foreach ( $protocols as $protocol ) {
2012-04-04 15:11:50 +00:00
$url = $protocol . $match [ 1 ];
2013-04-28 09:12:09 +00:00
if ( 0 === $this -> process -> execute ( call_user_func ( $commandCallable , $url ), $ignoredOutput , $cwd )) {
2012-03-10 16:49:08 +00:00
return ;
}
2012-05-18 12:41:57 +00:00
$messages [] = '- ' . $url . " \n " . preg_replace ( '#^#m' , ' ' , $this -> process -> getErrorOutput ());
2013-04-28 09:12:09 +00:00
if ( $initialClone ) {
$this -> filesystem -> removeDirectory ( $origCwd );
2012-03-10 16:49:08 +00:00
}
}
2012-04-05 15:30:50 +00:00
2012-04-06 11:21:04 +00:00
// failed to checkout, first check git accessibility
2012-10-10 21:47:53 +00:00
$this -> throwException ( 'Failed to clone ' . $this -> sanitizeUrl ( $url ) . ' via git, https and http protocols, aborting.' . " \n \n " . implode ( " \n " , $messages ), $url );
2012-04-05 15:26:15 +00:00
}
2012-03-10 16:49:08 +00:00
$command = call_user_func ( $commandCallable , $url );
2013-04-28 09:12:09 +00:00
if ( 0 !== $this -> process -> execute ( $command , $ignoredOutput , $cwd )) {
2012-10-21 15:56:57 +00:00
// private github repository without git access, try https with auth
2012-10-22 15:11:34 +00:00
if ( preg_match ( '{^git@(github.com):(.+?)\.git$}i' , $url , $match )) {
2012-11-07 12:33:50 +00:00
if ( ! $this -> io -> hasAuthentication ( $match [ 1 ])) {
2012-10-21 15:56:57 +00:00
$gitHubUtil = new GitHub ( $this -> io , $this -> config , $this -> process );
2012-10-22 15:11:34 +00:00
$message = 'Cloning failed using an ssh key for authentication, enter your GitHub credentials to access private repos' ;
if ( ! $gitHubUtil -> authorizeOAuth ( $match [ 1 ]) && $this -> io -> isInteractive ()) {
$gitHubUtil -> authorizeOAuthInteractively ( $match [ 1 ], $message );
}
2012-10-21 15:56:57 +00:00
}
2012-05-06 15:19:30 +00:00
2012-11-07 12:33:50 +00:00
if ( $this -> io -> hasAuthentication ( $match [ 1 ])) {
$auth = $this -> io -> getAuthentication ( $match [ 1 ]);
2013-03-10 13:47:36 +00:00
$url = 'https://' . urlencode ( $auth [ 'username' ]) . ':' . urlencode ( $auth [ 'password' ]) . '@' . $match [ 1 ] . '/' . $match [ 2 ] . '.git' ;
2012-05-06 15:19:30 +00:00
2012-10-22 15:11:34 +00:00
$command = call_user_func ( $commandCallable , $url );
2013-04-28 09:12:09 +00:00
if ( 0 === $this -> process -> execute ( $command , $ignoredOutput , $cwd )) {
2012-10-22 15:11:34 +00:00
return ;
}
2012-10-21 15:56:57 +00:00
}
2013-03-10 13:47:36 +00:00
} elseif ( // private non-github repo that failed to authenticate
2012-09-30 16:12:29 +00:00
$this -> io -> isInteractive () &&
2012-10-01 17:56:41 +00:00
preg_match ( '{(https?://)([^/]+)(.*)$}i' , $url , $match ) &&
2012-10-01 15:14:05 +00:00
strpos ( $this -> process -> getErrorOutput (), 'fatal: Authentication failed' ) !== false
2012-09-30 16:12:29 +00:00
) {
2013-03-11 09:04:45 +00:00
if ( $this -> io -> hasAuthentication ( $match [ 2 ])) {
$auth = $this -> io -> getAuthentication ( $match [ 2 ]);
2012-09-30 16:12:29 +00:00
} else {
2013-03-10 13:47:36 +00:00
$this -> io -> write ( $url . ' requires Authentication' );
2012-09-30 16:12:29 +00:00
$auth = array (
'username' => $this -> io -> ask ( 'Username: ' ),
'password' => $this -> io -> askAndHideAnswer ( 'Password: ' ),
);
}
2013-03-10 13:47:36 +00:00
$url = $match [ 1 ] . urlencode ( $auth [ 'username' ]) . ':' . urlencode ( $auth [ 'password' ]) . '@' . $match [ 2 ] . $match [ 3 ];
2012-09-30 16:12:29 +00:00
$command = call_user_func ( $commandCallable , $url );
2013-04-28 09:12:09 +00:00
if ( 0 === $this -> process -> execute ( $command , $ignoredOutput , $cwd )) {
2013-03-11 09:04:45 +00:00
$this -> io -> setAuthentication ( $match [ 2 ], $auth [ 'username' ], $auth [ 'password' ]);
2013-03-10 13:47:36 +00:00
2012-09-30 16:12:29 +00:00
return ;
}
2012-05-06 15:19:30 +00:00
}
2012-05-12 16:24:07 +00:00
2013-04-28 09:12:09 +00:00
if ( $initialClone ) {
$this -> filesystem -> removeDirectory ( $origCwd );
2012-05-12 16:24:07 +00:00
}
2012-10-10 21:47:53 +00:00
$this -> throwException ( 'Failed to execute ' . $this -> sanitizeUrl ( $command ) . " \n \n " . $this -> process -> getErrorOutput (), $url );
2012-03-10 16:49:08 +00:00
}
}
2012-04-03 17:49:57 +00:00
2012-04-06 11:21:04 +00:00
protected function throwException ( $message , $url )
{
if ( 0 !== $this -> process -> execute ( 'git --version' , $ignoredOutput )) {
2012-10-10 21:47:53 +00:00
throw new \RuntimeException ( 'Failed to clone ' . $this -> sanitizeUrl ( $url ) . ', git was not found, check that it is installed and in your PATH env.' . " \n \n " . $this -> process -> getErrorOutput ());
2012-04-06 11:21:04 +00:00
}
throw new \RuntimeException ( $message );
}
2012-10-10 21:47:53 +00:00
protected function sanitizeUrl ( $message )
{
2012-10-18 14:02:24 +00:00
return preg_replace ( '{://(.+?):.+?@}' , '://$1:***@' , $message );
2012-10-10 21:47:53 +00:00
}
2012-04-03 17:49:57 +00:00
protected function setPushUrl ( PackageInterface $package , $path )
{
// set push url for github projects
if ( preg_match ( '{^(?:https?|git)://github.com/([^/]+)/([^/]+?)(?:\.git)?$}' , $package -> getSourceUrl (), $match )) {
$pushUrl = 'git@github.com:' . $match [ 1 ] . '/' . $match [ 2 ] . '.git' ;
2012-04-04 15:11:10 +00:00
$cmd = sprintf ( 'git remote set-url --push origin %s' , escapeshellarg ( $pushUrl ));
$this -> process -> execute ( $cmd , $ignoredOutput , $path );
2012-04-03 17:49:57 +00:00
}
}
2012-06-25 13:23:54 +00:00
2012-08-18 14:01:44 +00:00
/**
* { @ inheritDoc }
*/
protected function getCommitLogs ( $fromReference , $toReference , $path )
2012-06-25 13:23:54 +00:00
{
2013-06-08 15:49:51 +00:00
$path = $this -> normalizePath ( $path );
2013-04-28 09:12:09 +00:00
$command = sprintf ( 'git log %s..%s --pretty=format:"%%h - %%an: %%s"' , $fromReference , $toReference );
2012-06-25 13:23:54 +00:00
2013-04-28 09:12:09 +00:00
if ( 0 !== $this -> process -> execute ( $command , $output , $path )) {
2012-06-25 13:23:54 +00:00
throw new \RuntimeException ( 'Failed to execute ' . $command . " \n \n " . $this -> process -> getErrorOutput ());
}
return $output ;
}
2013-02-28 16:10:04 +00:00
/**
* @ param $path
* @ throws \RuntimeException
*/
protected function discardChanges ( $path )
{
2013-06-08 15:49:51 +00:00
$path = $this -> normalizePath ( $path );
2013-02-28 16:10:04 +00:00
if ( 0 !== $this -> process -> execute ( 'git reset --hard' , $output , $path )) {
throw new \RuntimeException ( " Could not reset changes \n \n : " . $this -> process -> getErrorOutput ());
}
}
/**
* @ param $path
* @ throws \RuntimeException
*/
protected function stashChanges ( $path )
{
2013-06-08 15:49:51 +00:00
$path = $this -> normalizePath ( $path );
2013-02-28 16:10:04 +00:00
if ( 0 !== $this -> process -> execute ( 'git stash' , $output , $path )) {
throw new \RuntimeException ( " Could not stash changes \n \n : " . $this -> process -> getErrorOutput ());
}
$this -> hasStashedChanges = true ;
}
2013-05-27 17:54:46 +00:00
protected function cleanEnv ()
{
// clean up rogue git env vars in case this is running in a git hook
putenv ( 'GIT_DIR' );
putenv ( 'GIT_WORK_TREE' );
// added in git 1.7.1, prevents prompting the user for username/password
putenv ( 'GIT_ASKPASS=echo' );
}
2013-06-08 15:49:51 +00:00
protected function normalizePath ( $path )
{
if ( defined ( 'PHP_WINDOWS_VERSION_MAJOR' ) && strlen ( $path ) > 0 ) {
$basePath = $path ;
$removed = array ();
while ( ! is_dir ( $basePath ) && $basePath !== '\\' ) {
array_unshift ( $removed , basename ( $basePath ));
$basePath = dirname ( $basePath );
}
if ( $basePath === '\\' ) {
return $path ;
}
$path = rtrim ( realpath ( $basePath ) . '/' . implode ( '/' , $removed ), '/' );
}
return $path ;
}
2011-09-17 13:12:45 +00:00
}