diff --git a/src/Composer/Repository/Vcs/GitDriver.php b/src/Composer/Repository/Vcs/GitDriver.php index 8a8d1f8c6..e99a0e5f8 100644 --- a/src/Composer/Repository/Vcs/GitDriver.php +++ b/src/Composer/Repository/Vcs/GitDriver.php @@ -15,6 +15,7 @@ class GitDriver extends VcsDriver implements VcsDriverInterface protected $branches; protected $rootIdentifier; protected $infoCache = array(); + protected $isLocal = false; public function __construct($url, IOInterface $io, ProcessExecutor $process = null) { @@ -30,10 +31,15 @@ class GitDriver extends VcsDriver implements VcsDriverInterface { $url = escapeshellarg($this->url); $tmpDir = escapeshellarg($this->tmpDir); - if (is_dir($this->tmpDir)) { - $this->process->execute(sprintf('cd %s && git fetch origin', $tmpDir), $output); + + if (static::isLocalUrl($url)) { + $this->isLocal = true; } else { - $this->process->execute(sprintf('git clone %s %s', $url, $tmpDir), $output); + if (is_dir($this->tmpDir)) { + $this->process->execute(sprintf('cd %s && git fetch origin', $tmpDir), $output); + } else { + $this->process->execute(sprintf('git clone %s %s', $url, $tmpDir), $output); + } } $this->getTags(); @@ -47,11 +53,27 @@ class GitDriver extends VcsDriver implements VcsDriverInterface { if (null === $this->rootIdentifier) { $this->rootIdentifier = 'master'; - $this->process->execute(sprintf('cd %s && git branch --no-color -r', escapeshellarg($this->tmpDir)), $output); - foreach ($this->process->splitLines($output) as $branch) { - if ($branch && preg_match('{/HEAD +-> +[^/]+/(\S+)}', $branch, $match)) { - $this->rootIdentifier = $match[1]; - break; + + if ($this->isLocal) { + // select currently checked out branch if master is not available + $this->process->execute(sprintf('cd %s && git branch --no-color', escapeshellarg($this->tmpDir)), $output); + $branches = $this->process->splitLines($output); + if (!in_array('* master', $branches)) { + foreach ($branches as $branch) { + if ($branch && preg_match('{^\* +(\S+)}', $branch, $match)) { + $this->rootIdentifier = $match[1]; + break; + } + } + } + } else { + // try to find a non-master remote HEAD branch + $this->process->execute(sprintf('cd %s && git branch --no-color -r', escapeshellarg($this->tmpDir)), $output); + foreach ($this->process->splitLines($output) as $branch) { + if ($branch && preg_match('{/HEAD +-> +[^/]+/(\S+)}', $branch, $match)) { + $this->rootIdentifier = $match[1]; + break; + } } } } @@ -132,7 +154,11 @@ class GitDriver extends VcsDriver implements VcsDriverInterface if (null === $this->branches) { $branches = array(); - $this->process->execute(sprintf('cd %s && git branch --no-color -rv', escapeshellarg($this->tmpDir)), $output); + $this->process->execute(sprintf( + 'cd %s && git branch --no-color --no-abbrev -v %s', + escapeshellarg($this->tmpDir), + $this->isLocal ? '' : '-r' + ), $output); foreach ($this->process->splitLines($output) as $branch) { if ($branch && !preg_match('{^ *[^/]+/HEAD }', $branch)) { preg_match('{^ *[^/]+/(\S+) *([a-f0-9]+) .*$}', $branch, $match); @@ -170,7 +196,7 @@ class GitDriver extends VcsDriver implements VcsDriverInterface } // local filesystem - if (preg_match('{^(file://|/|[a-z]:[\\\\/])}i', $url)) { + if (static::isLocalUrl($url)) { $process = new ProcessExecutor(); // check whether there is a git repo in that path if ($process->execute(sprintf('cd %s && git show', escapeshellarg($url)), $output) === 0) { diff --git a/src/Composer/Repository/Vcs/VcsDriver.php b/src/Composer/Repository/Vcs/VcsDriver.php index 7008f41be..75b631a42 100644 --- a/src/Composer/Repository/Vcs/VcsDriver.php +++ b/src/Composer/Repository/Vcs/VcsDriver.php @@ -68,4 +68,9 @@ abstract class VcsDriver $rfs = new RemoteFilesystem($this->io); return $rfs->getContents($this->url, $url, false); } + + protected static function isLocalUrl($url) + { + return (Boolean) preg_match('{^(file://|/|[a-z]:[\\\\/])}i', $url); + } }