From ef12e42bdb04dcc564ab7c957e47341570a14a0c Mon Sep 17 00:00:00 2001 From: Stephan Date: Fri, 1 Apr 2022 16:13:22 +0100 Subject: [PATCH] GitDriver: try to fetch default branch from remote (#10687) The initial clone determined what the default branch of the cache git repository was. Changing it on the remote didn't have any impact on the local data. However, cloning it on a different machine would then store a different default branch on that machine. This could lead to different results for the same command on different machines. --- src/Composer/Repository/Vcs/GitDriver.php | 12 +++ .../Test/Repository/Vcs/GitDriverTest.php | 95 +++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 tests/Composer/Test/Repository/Vcs/GitDriverTest.php diff --git a/src/Composer/Repository/Vcs/GitDriver.php b/src/Composer/Repository/Vcs/GitDriver.php index 182d2816b..6397d3abe 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,17 @@ class GitDriver extends VcsDriver 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); + if (Preg::isMatch('{^\s*HEAD branch:\s(.+)\s*$}m', $output, $matches)) { + 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 000000000..e4e3c86b7 --- /dev/null +++ b/tests/Composer/Test/Repository/Vcs/GitDriverTest.php @@ -0,0 +1,95 @@ +home = self::getUniqueTmpDirectory(); + $this->config = new Config(); + $this->config->merge([ + 'config' => [ + '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); + + $stdout = <<expects([[ + 'cmd' => 'git remote show origin', + 'stdout' => $stdout, + ]]); + + $this->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); + + $stdout = <<expects([[ + 'cmd' => 'git branch --no-color', + 'stdout' => $stdout, + ]]); + + $this->assertSame('main', $driver->getRootIdentifier()); + } +}