From 125f83234eb17f0c270ca9b3e50b41ec64045c7e Mon Sep 17 00:00:00 2001 From: Seb35 Date: Fri, 15 Sep 2017 10:29:13 +0200 Subject: [PATCH] Improve GitInfo for reading packed refs GitInfo only reads branches in files /refs/heads/*; it should also read those in /.git/packed-refs. There are 4 tests in this commit to test this new "feature" and add some code coverage to other methods. Given this class tests Git behaviour and MediaWiki itself is versioned with Git, the test data are created during the tests and removed at the end to avoid interference with Git as CVS. Bug: T155747 Change-Id: Icccdf3ec797788582f836e2d8e267a1d714d50dc --- includes/GitInfo.php | 6 +++ tests/phpunit/includes/GitInfoTest.php | 56 ++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/includes/GitInfo.php b/includes/GitInfo.php index 4351acc0e9..3c600ed984 100644 --- a/includes/GitInfo.php +++ b/includes/GitInfo.php @@ -191,8 +191,14 @@ class GitInfo { } else { // If not a SHA1 it may be a ref: $refFile = "{$this->basedir}/{$head}"; + $packedRefs = "{$this->basedir}/packed-refs"; + $headRegex = preg_quote( $head, '/' ); if ( is_readable( $refFile ) ) { $sha1 = rtrim( file_get_contents( $refFile ) ); + } elseif ( is_readable( $packedRefs ) && + preg_match( "/^([0-9A-Fa-f]{40}) $headRegex$/m", file_get_contents( $packedRefs ), $matches ) + ) { + $sha1 = $matches[1]; } } $this->cache['headSHA1'] = $sha1; diff --git a/tests/phpunit/includes/GitInfoTest.php b/tests/phpunit/includes/GitInfoTest.php index ae858f5d5e..1037b3705e 100644 --- a/tests/phpunit/includes/GitInfoTest.php +++ b/tests/phpunit/includes/GitInfoTest.php @@ -4,6 +4,30 @@ */ class GitInfoTest extends MediaWikiTestCase { + public static function setUpBeforeClass() { + mkdir( __DIR__ . '/../data/gitrepo' ); + mkdir( __DIR__ . '/../data/gitrepo/1' ); + mkdir( __DIR__ . '/../data/gitrepo/2' ); + mkdir( __DIR__ . '/../data/gitrepo/3' ); + mkdir( __DIR__ . '/../data/gitrepo/1/.git' ); + mkdir( __DIR__ . '/../data/gitrepo/1/.git/refs' ); + mkdir( __DIR__ . '/../data/gitrepo/1/.git/refs/heads' ); + file_put_contents( __DIR__ . '/../data/gitrepo/1/.git/HEAD', + "ref: refs/heads/master\n" ); + file_put_contents( __DIR__ . '/../data/gitrepo/1/.git/refs/heads/master', + "0123456789012345678901234567890123abcdef\n" ); + file_put_contents( __DIR__ . '/../data/gitrepo/1/.git/packed-refs', + "abcdef6789012345678901234567890123456789 refs/heads/master\n" ); + file_put_contents( __DIR__ . '/../data/gitrepo/2/.git', + "gitdir: ../1/.git\n" ); + file_put_contents( __DIR__ . '/../data/gitrepo/3/.git', + 'gitdir: ' . __DIR__ . "/../data/gitrepo/1/.git\n" ); + } + + public static function tearDownAfterClass() { + wfRecursiveRemoveDir( __DIR__ . '/../data/gitrepo' ); + } + protected function setUp() { parent::setUp(); $this->setMwGlobals( 'wgGitInfoCacheDirectory', __DIR__ . '/../data/gitinfo' ); @@ -43,4 +67,36 @@ class GitInfoTest extends MediaWikiTestCase { $this->assertTrue( $fixture->cacheIsComplete() ); } + public function testReadingHead() { + $dir = __DIR__ . '/../data/gitrepo/1'; + $fixture = new GitInfo( $dir ); + + $this->assertEquals( 'refs/heads/master', $fixture->getHead() ); + $this->assertEquals( '0123456789012345678901234567890123abcdef', $fixture->getHeadSHA1() ); + } + + public function testIndirection() { + $dir = __DIR__ . '/../data/gitrepo/2'; + $fixture = new GitInfo( $dir ); + + $this->assertEquals( 'refs/heads/master', $fixture->getHead() ); + $this->assertEquals( '0123456789012345678901234567890123abcdef', $fixture->getHeadSHA1() ); + } + + public function testIndirection2() { + $dir = __DIR__ . '/../data/gitrepo/3'; + $fixture = new GitInfo( $dir ); + + $this->assertEquals( 'refs/heads/master', $fixture->getHead() ); + $this->assertEquals( '0123456789012345678901234567890123abcdef', $fixture->getHeadSHA1() ); + } + + public function testReadingPackedRefs() { + $dir = __DIR__ . '/../data/gitrepo/1'; + unlink( __DIR__ . '/../data/gitrepo/1/.git/refs/heads/master' ); + $fixture = new GitInfo( $dir ); + + $this->assertEquals( 'refs/heads/master', $fixture->getHead() ); + $this->assertEquals( 'abcdef6789012345678901234567890123456789', $fixture->getHeadSHA1() ); + } } -- 2.20.1