Skip to content

Commit

Permalink
GitDriver: try to fetch default branch from remote (#10687)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
glaubinix committed Apr 1, 2022
1 parent be4b70c commit ef12e42
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 0 deletions.
12 changes: 12 additions & 0 deletions src/Composer/Repository/Vcs/GitDriver.php
Expand Up @@ -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;
Expand Down Expand Up @@ -93,6 +94,17 @@ 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);
if (Preg::isMatch('{^\s*HEAD branch:\s(.+)\s*$}m', $output, $matches)) {
return $this->rootIdentifier = $matches[1];
}
} catch (\Exception $e) {
$this->io->writeError('<error>Failed to fetch root identifier from remote: ' . $e->getMessage() . '</error>', 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);
Expand Down
95 changes: 95 additions & 0 deletions tests/Composer/Test/Repository/Vcs/GitDriverTest.php
@@ -0,0 +1,95 @@
<?php declare(strict_types=1);

namespace Composer\Test\Repository\Vcs;

use Composer\Config;
use Composer\IO\IOInterface;
use Composer\Repository\Vcs\GitDriver;
use Composer\Test\TestCase;
use Composer\Util\Filesystem;
use Composer\Util\Platform;

class GitDriverTest extends TestCase
{
/** @var Config */
private $config;
/** @var string */
private $home;
/** @var false|string */
private $networkEnv;

public function setUp(): void
{
$this->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 = <<<GIT
* remote origin
Fetch URL: https://example.org/acme.git
Push URL: https://example.org/acme.git
HEAD branch: main
Remote branches:
1.10 tracked
2.2 tracked
main tracked
GIT;

$process
->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 = <<<GIT
* main
2.2
1.10
GIT;

$process
->expects([[
'cmd' => 'git branch --no-color',
'stdout' => $stdout,
]]);

$this->assertSame('main', $driver->getRootIdentifier());
}
}

0 comments on commit ef12e42

Please sign in to comment.