diff --git a/src/Composer/Repository/Vcs/GitDriver.php b/src/Composer/Repository/Vcs/GitDriver.php index 182d2816b2e5..1b481329eaba 100644 --- a/src/Composer/Repository/Vcs/GitDriver.php +++ b/src/Composer/Repository/Vcs/GitDriver.php @@ -13,6 +13,7 @@ namespace Composer\Repository\Vcs; use Composer\Pcre\Preg; +use Composer\Util\Platform; use Composer\Util\ProcessExecutor; use Composer\Util\Filesystem; use Composer\Util\Url; @@ -93,6 +94,20 @@ public function getRootIdentifier(): string if (null === $this->rootIdentifier) { $this->rootIdentifier = 'master'; + if (!(bool) Platform::getEnv('COMPOSER_DISABLE_NETWORK')) { + try { + $this->process->execute('git remote show origin', $output, $this->repoDir); + $lines = $this->process->splitLines($output); + foreach ($lines as $line) { + if (Preg::match('{^\s*HEAD branch:\s(.+)\s*$}', $line, $matches) > 0) { + return $this->rootIdentifier = $matches[1]; + } + } + } catch (\Exception $e) { + $this->io->writeError('Failed to fetch root identifier from remote: ' . $e->getMessage() . '', true, IOInterface::DEBUG); + } + } + // select currently checked out branch if master is not available $this->process->execute('git branch --no-color', $output, $this->repoDir); $branches = $this->process->splitLines($output); diff --git a/tests/Composer/Test/Repository/Vcs/GitDriverTest.php b/tests/Composer/Test/Repository/Vcs/GitDriverTest.php new file mode 100644 index 000000000000..b69ffa41b246 --- /dev/null +++ b/tests/Composer/Test/Repository/Vcs/GitDriverTest.php @@ -0,0 +1,93 @@ +home = self::getUniqueTmpDirectory(); + $this->config = new Config(); + $this->config->merge(array( + 'config' => array( + 'home' => $this->home, + ), + )); + $this->networkEnv = Platform::getEnv('COMPOSER_DISABLE_NETWORK'); + } + + protected function tearDown(): void + { + parent::tearDown(); + $fs = new Filesystem; + $fs->removeDirectory($this->home); + if ($this->networkEnv === false) { + Platform::clearEnv('COMPOSER_DISABLE_NETWORK'); + } else { + Platform::putEnv('COMPOSER_DISABLE_NETWORK', $this->networkEnv); + } + } + + public function testGetRootIdentifierFromRemote(): void + { + $process = $this->getProcessExecutorMock(); + $io = $this->getMockBuilder(IOInterface::class)->getMock(); + + $driver = new GitDriver(['url' => 'https://example.org/acme.git'], $io, $this->config, $this->getHttpDownloaderMock(), $process); + + $process + ->expects([[ + 'cmd' => 'git remote show origin', + 'stdout' => <<assertSame('main', $driver->getRootIdentifier()); + } + + public function testGetRootIdentifierFromLocalWithNetworkDisabled(): void + { + Platform::putEnv('COMPOSER_DISABLE_NETWORK', '1'); + + $process = $this->getProcessExecutorMock(); + $io = $this->getMockBuilder(IOInterface::class)->getMock(); + + $driver = new GitDriver(['url' => 'https://example.org/acme.git'], $io, $this->config, $this->getHttpDownloaderMock(), $process); + + $process + ->expects([[ + 'cmd' => 'git branch --no-color', + 'stdout' => <<assertSame('main', $driver->getRootIdentifier()); + } +}