Do not crash when a repo has a detached HEAD

Instead, we select a default branch - master by default, but the default
branch can be configured using config.ini.

Note that if the default branch does not exist in a repo, that should
not cause any issues.

Also adds phpunit to composer.json's require-dev section.
This commit is contained in:
Nate Eagleson
2013-02-14 22:31:47 -05:00
parent 6e4e8912b0
commit dabf4d86d9
9 changed files with 747 additions and 111 deletions

View File

@@ -4,16 +4,23 @@
"twig/twig": "1.9.*",
"symfony/twig-bridge": "2.1.*",
"symfony/filesystem": "2.1.*",
"klaussilveira/gitter": "dev-master"
"klaussilveira/gitter": "dev-fix-get-branches"
},
"require-dev": {
"symfony/browser-kit": "2.1.*",
"symfony/css-selector": "2.1.*"
"symfony/css-selector": "2.1.*",
"phpunit/phpunit": "3.7.*"
},
"minimum-stability": "dev",
"autoload": {
"psr-0": {
"GitList": "src/"
}
}
},
"repositories": [
{
"type": "vcs",
"url": "https://github.com/NateEag/gitter.git"
}
]
}

771
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,7 @@
[git]
client = '/usr/bin/git' ; Your git executable path
repositories = '/var/www/projects/' ; Path to your repositories
default_branch = 'master' ; Default branch when HEAD is detached
; You can hide repositories from GitList, just copy this for each repository you want to hide
; hidden[] = '/var/www/projects/BetaTest'

View File

@@ -38,9 +38,10 @@ class Application extends SilexApplication
'twig.options' => array('cache' => $root . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'views'),
));
$this->register(new GitServiceProvider(), array(
'git.client' => $config->get('git', 'client'),
'git.repos' => $config->get('git', 'repositories'),
'git.hidden' => $config->get('git', 'hidden') ? $config->get('git', 'hidden') : array(),
'git.client' => $config->get('git', 'client'),
'git.repos' => $config->get('git', 'repositories'),
'git.hidden' => $config->get('git', 'hidden') ? $config->get('git', 'hidden') : array(),
'git.default_branch' => $config->get('git', 'default_branch') ? $config->get('git', 'default_branch') : 'master',
));
$this->register(new ViewUtilServiceProvider());
$this->register(new RepositoryUtilServiceProvider());

View File

@@ -52,6 +52,11 @@ class MainController implements ControllerProviderInterface
$route->get('{repo}/{branch}/rss/', function($repo, $branch) use ($app) {
$repository = $app['git']->getRepository($app['git.repos'] . $repo);
if ($branch === null) {
$branch = $repository->getHead();
}
$commits = $repository->getPaginatedCommits($branch);
$html = $app['twig']->render('rss.twig', array(
@@ -63,6 +68,7 @@ class MainController implements ControllerProviderInterface
return new Response($html, 200, array('Content-Type' => 'application/rss+xml'));
})->assert('repo', $app['util.routing']->getRepositoryRegex())
->assert('branch', $app['util.routing']->getBranchRegex())
->value('branch', null)
->bind('rss');
return $route;

View File

@@ -6,6 +6,39 @@ use Gitter\Client as BaseClient;
class Client extends BaseClient
{
protected $default_branch;
public function __construct($options = null)
{
parent::__construct($options);
if (!isset($options['default_branch'])) {
$options['default_branch'] = 'master';
}
$this->setDefaultBranch($options['default_branch']);
}
/**
* Set default branch as a string.
*
* @param string $branch Name of branch to use when repo's HEAD is detached.
*/
protected function setDefaultBranch($branch)
{
$this->default_branch = $branch;
return $this;
}
/**
* Return name of default branch as a string.
*/
public function getDefaultBranch()
{
return $this->default_branch;
}
/**
* Creates a new repository on the specified path
*

View File

@@ -24,6 +24,16 @@ class Repository extends BaseRepository
return strpos($logs[0], 'commit') === 0;
}
/**
* Get the current branch, returning a default value when HEAD is detached.
*/
public function getHead()
{
$client = $this->getClient();
return parent::getHead($client->getDefaultBranch());
}
/**
* Show the data from a specific commit
*

View File

@@ -19,6 +19,7 @@ class GitServiceProvider implements ServiceProviderInterface
$app['git'] = function () use ($app) {
$options['path'] = $app['git.client'];
$options['hidden'] = $app['git.hidden'];
$options['default_branch'] = $app['git.default_branch'];
return new Client($options);
};

View File

@@ -95,6 +95,16 @@ class InterfaceTest extends WebTestCase
$repository->setConfig('user.email', 'luke@rebel.org');
$repository->addAll();
$repository->commit("Initial commit");
// Detached HEAD repository fixture
$git->createRepository(self::$tmpdir . 'detached-head');
$repository = $git->getRepository(self::$tmpdir . '/detached-head');
$repository->setConfig('user.name', 'Luke Skywalker');
$repository->setConfig('user.email', 'luke@rebel.org');
file_put_contents(self::$tmpdir . 'detached-head/README.md', "## detached head\ndetached-head is a *test* repository!");
$repository->addAll();
$repository->commit("First commit");
$repository->checkout('HEAD');
}
public function createApplication()
@@ -126,8 +136,8 @@ class InterfaceTest extends WebTestCase
$this->assertEquals('/nested/NestedRepo/master/rss/', $crawler->filter('.repository-header a')->eq(3)->attr('href'));
$this->assertCount(1, $crawler->filter('div.repository-header:contains("foobar")'));
$this->assertCount(1, $crawler->filter('div.repository-body:contains("This is a test repo!")'));
$this->assertEquals('/foobar/', $crawler->filter('.repository-header a')->eq(6)->attr('href'));
$this->assertEquals('/foobar/master/rss/', $crawler->filter('.repository-header a')->eq(7)->attr('href'));
$this->assertEquals('/foobar/', $crawler->filter('.repository-header a')->eq(8)->attr('href'));
$this->assertEquals('/foobar/master/rss/', $crawler->filter('.repository-header a')->eq(9)->attr('href'));
}
public function testRepositoryPage()