diff --git a/libraries/classes/Config.php b/libraries/classes/Config.php index a292c06774..e179d6d2ac 100644 --- a/libraries/classes/Config.php +++ b/libraries/classes/Config.php @@ -358,12 +358,12 @@ class Config /** * detects if Git revision - * + * @param string &$git_location (optional) verified git directory * @return boolean */ - public function isGitRevision(): bool + public function isGitRevision(&$git_location = NULL): bool { - if (!$this->get('ShowGitRevision')) { + if (! $this->get('ShowGitRevision')) { return false; } @@ -372,16 +372,41 @@ class Config if ($_SESSION['is_git_revision']) { $this->set('PMA_VERSION_GIT', 1); } + $git_location = $_SESSION['git_location']; return $_SESSION['is_git_revision']; } // find out if there is a .git folder - $git_folder = '.git'; - if (! @file_exists($git_folder) - || ! @file_exists($git_folder . '/config') - ) { + // or a .git file (--separate-git-dir) + $git = '.git'; + if (is_dir($git)) { + if (@is_file($git . '/config')) { + $git_location = $git; + } else { + $_SESSION['is_git_revision'] = false; + return false; + } + } elseif (is_file($git)) { + $contents = file_get_contents($git); + $gitmatch = array(); + // Matches expected format + if (! preg_match('/^gitdir: (.*)$/', + $contents, $gitmatch)) { + $_SESSION['is_git_revision'] = false; + return false; + } else { + if (@is_dir($gitmatch[1])) { + //Detected git external folder location + $git_location = $gitmatch[1]; + } else { + $_SESSION['is_git_revision'] = false; + return false; + } + } + } else { $_SESSION['is_git_revision'] = false; return false; } + $_SESSION['git_location'] = $git_location; $_SESSION['is_git_revision'] = true; return true; } @@ -394,8 +419,8 @@ class Config public function checkGitRevision(): void { // find out if there is a .git folder - $git_folder = '.git'; - if (! $this->isGitRevision()) { + $git_folder = ''; + if (! $this->isGitRevision($git_folder)) { return; } diff --git a/test/classes/ConfigTest.php b/test/classes/ConfigTest.php index 165117292d..f517c053ad 100644 --- a/test/classes/ConfigTest.php +++ b/test/classes/ConfigTest.php @@ -45,6 +45,7 @@ class ConfigTest extends PmaTestCase { $this->object = new Config; $GLOBALS['server'] = 0; + $_SESSION['git_location'] = '.git'; $_SESSION['is_git_revision'] = true; $GLOBALS['PMA_Config'] = new Config(CONFIG_FILE); $GLOBALS['cfg']['ProxyUrl'] = ''; @@ -835,9 +836,188 @@ class ConfigTest extends PmaTestCase */ public function testIsGitRevision() { + $git_location = ''; + $this->assertTrue( + $this->object->isGitRevision($git_location) + ); + $this->assertEquals('.git', $git_location); + } + + /** + * Test for isGitRevision + * + * @return void + */ + public function testIsGitRevisionSkipped() + { + $this->object->set('ShowGitRevision', false); + $this->assertFalse( + $this->object->isGitRevision($git_location) + ); + } + + /** + * Test for isGitRevision + * + * @return void + */ + public function testIsGitRevisionLocalGitDir() + { + $cwd = getcwd(); + $test_dir = "gittestdir"; + + unset($_SESSION['git_location']); + unset($_SESSION['is_git_revision']); + + mkdir($test_dir); + chdir($test_dir); + + $this->assertFalse( + $this->object->isGitRevision() + ); + + unset($_SESSION['git_location']); + unset($_SESSION['is_git_revision']); + + mkdir('.git'); + + $this->assertFalse( + $this->object->isGitRevision() + ); + + unset($_SESSION['git_location']); + unset($_SESSION['is_git_revision']); + + file_put_contents('.git/config',''); + $this->assertTrue( $this->object->isGitRevision() ); + + unlink('.git/config'); + rmdir('.git'); + + chdir($cwd); + rmdir($test_dir); + } + + /** + * Test for isGitRevision + * + * @return void + */ + public function testIsGitRevisionExternalGitDir() + { + $cwd = getcwd(); + $test_dir = "gittestdir"; + + unset($_SESSION['git_location']); + unset($_SESSION['is_git_revision']); + + mkdir($test_dir); + chdir($test_dir); + + file_put_contents('.git','gitdir: ./.customgitdir'); + $this->assertFalse( + $this->object->isGitRevision() + ); + + unset($_SESSION['git_location']); + unset($_SESSION['is_git_revision']); + + mkdir('.customgitdir'); + + $this->assertTrue( + $this->object->isGitRevision() + ); + + unset($_SESSION['git_location']); + unset($_SESSION['is_git_revision']); + + file_put_contents('.git','random data here'); + + $this->assertFalse( + $this->object->isGitRevision() + ); + + unlink('.git'); + rmdir('.customgitdir'); + + chdir($cwd); + rmdir($test_dir); + } + + /** + * Test for checkGitRevision + * + * @return void + */ + public function testCheckGitRevision() + { + $cwd = getcwd(); + $test_dir = "gittestdir"; + + unset($_SESSION['git_location']); + unset($_SESSION['is_git_revision']); + + mkdir($test_dir); + chdir($test_dir); + + mkdir('.git'); + file_put_contents('.git/config',''); + + $this->object->checkGitRevision(); + + $this->assertEmpty( + $this->object->get('PMA_VERSION_GIT_COMMITHASH') + ); + + + file_put_contents('.git/HEAD','ref: refs/remotes/origin/master'); + $this->object->checkGitRevision(); + $this->assertEmpty( + $this->object->get('PMA_VERSION_GIT_COMMITHASH') + ); + + file_put_contents('.git/packed-refs', + '# pack-refs with: peeled fully-peeled sorted'.PHP_EOL. + 'c1f2ff2eb0c3fda741f859913fd589379f4e4a8f refs/tags/4.3.10'.PHP_EOL. + '^6f2e60343b0a324c65f2d1411bf4bd03e114fb98'.PHP_EOL. + '17bf8b7309919f8ac593d7c563b31472780ee83b refs/remotes/origin/master'.PHP_EOL + ); + mkdir('.git/objects/pack', 0777, true);//default = 0777, recursive mode + $this->object->checkGitRevision(); + + $this->assertNotEmpty( + $this->object->get('PMA_VERSION_GIT_COMMITHASH') + ); + $this->assertNotEmpty( + $this->object->get('PMA_VERSION_GIT_BRANCH') + ); + + rmdir(".git/objects/pack"); + rmdir(".git/objects"); + unlink('.git/packed-refs'); + unlink('.git/HEAD'); + unlink('.git/config'); + rmdir('.git'); + + chdir($cwd); + rmdir($test_dir); + } + + /** + * Test for checkGitRevision + * + * @return void + */ + public function testCheckGitRevisionSkipped() + { + $this->object->set('ShowGitRevision', false); + $this->object->checkGitRevision(); + $this->assertEmpty( + $this->object->get('PMA_VERSION_GIT_COMMITHASH') + ); } /**