Skip to content

Commit

Permalink
GitDriver: try to fetch default branch from remote
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 17de5f7 commit 89af7e5
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 0 deletions.
15 changes: 15 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,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('<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
93 changes: 93 additions & 0 deletions tests/Composer/Test/Repository/Vcs/GitDriverTest.php
@@ -0,0 +1,93 @@
<?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(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' => <<<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,
]]);


$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);

$process
->expects([[
'cmd' => 'git branch --no-color',
'stdout' => <<<GIT
* main
2.2
1.10
GIT,
]]);


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

0 comments on commit 89af7e5

Please sign in to comment.