mirror of
https://github.com/klaussilveira/gitlist.git
synced 2025-11-18 03:30:55 +01:00
Merged with master main repo.
This commit is contained in:
@@ -2,6 +2,8 @@
|
|||||||
Options -MultiViews
|
Options -MultiViews
|
||||||
|
|
||||||
RewriteEngine On
|
RewriteEngine On
|
||||||
|
#RewriteBase /path/to/gitlist/
|
||||||
|
|
||||||
RewriteCond %{REQUEST_FILENAME} !-f
|
RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
RewriteRule ^(.*)$ index.php [L,NC]
|
RewriteRule ^(.*)$ index.php [L,NC]
|
||||||
</IfModule>
|
</IfModule>
|
||||||
|
|||||||
18
INSTALL.md
18
INSTALL.md
@@ -1,5 +1,5 @@
|
|||||||
# GitList Installation
|
# GitList Installation
|
||||||
* Download GitList from [gitlist.org](http://gitlist.org/) and decompress to your `/var/www/gitlist` folder, or anywhere else you want to place GitList.
|
* Download GitList from [gitlist.org](http://gitlist.org/) and decompress to your `/var/www/gitlist` folder, or anywhere else you want to place GitList.
|
||||||
* Rename the `config.ini-example` file to `config.ini`.
|
* Rename the `config.ini-example` file to `config.ini`.
|
||||||
* Open up the `config.ini` and configure your installation. You'll have to provide where your repositories are located and the base GitList URL (in our case, http://localhost/gitlist).
|
* Open up the `config.ini` and configure your installation. You'll have to provide where your repositories are located and the base GitList URL (in our case, http://localhost/gitlist).
|
||||||
* Create the cache folder and give read/write permissions to your web server user:
|
* Create the cache folder and give read/write permissions to your web server user:
|
||||||
@@ -13,7 +13,7 @@ chmod 777 cache
|
|||||||
That's it, installation complete!
|
That's it, installation complete!
|
||||||
|
|
||||||
## Webserver configuration
|
## Webserver configuration
|
||||||
Apache is the "default" webserver for GitList. You will find the configuration inside the `.htaccess` file. However, nginx and lighttpd are also supported.
|
Apache is the "default" webserver for GitList. You will find the configuration inside the `.htaccess` file. However, nginx and lighttpd are also supported.
|
||||||
|
|
||||||
### nginx server.conf
|
### nginx server.conf
|
||||||
|
|
||||||
@@ -73,4 +73,16 @@ url.rewrite-once = (
|
|||||||
"^/gitlist/favicon\.ico$" => "$0",
|
"^/gitlist/favicon\.ico$" => "$0",
|
||||||
"^/gitlist(/[^\?]*)(\?.*)?" => "/gitlist/index.php$1$2"
|
"^/gitlist(/[^\?]*)(\?.*)?" => "/gitlist/index.php$1$2"
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### hiawatha
|
||||||
|
|
||||||
|
```
|
||||||
|
UrlToolkit {
|
||||||
|
ToolkitID = gitlist
|
||||||
|
RequestURI isfile Return
|
||||||
|
# If you have example.com/gitlist/ ; Otherwise remove "/gitlist" below
|
||||||
|
Match ^/gitlist/.* Rewrite /gitlist/index.php
|
||||||
|
Match ^/gitlist/.*\.ini DenyAccess
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|||||||
2
composer.lock
generated
2
composer.lock
generated
@@ -618,4 +618,4 @@
|
|||||||
"stability-flags": {
|
"stability-flags": {
|
||||||
"klaussilveira/gitter": 20
|
"klaussilveira/gitter": 20
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,10 @@ if (!ini_get('date.timezone')) {
|
|||||||
date_default_timezone_set('UTC');
|
date_default_timezone_set('UTC');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(php_sapi_name() == 'cli-server' && file_exists(substr($_SERVER['REQUEST_URI'], 1))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
require 'vendor/autoload.php';
|
require 'vendor/autoload.php';
|
||||||
|
|
||||||
// Load configuration
|
// Load configuration
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ class Application extends SilexApplication
|
|||||||
$this->register(new RoutingUtilServiceProvider());
|
$this->register(new RoutingUtilServiceProvider());
|
||||||
|
|
||||||
$this['twig'] = $this->share($this->extend('twig', function($twig, $app) {
|
$this['twig'] = $this->share($this->extend('twig', function($twig, $app) {
|
||||||
|
$twig->addFilter('htmlentities', new \Twig_Filter_Function('htmlentities'));
|
||||||
$twig->addFilter('md5', new \Twig_Filter_Function('md5'));
|
$twig->addFilter('md5', new \Twig_Filter_Function('md5'));
|
||||||
|
|
||||||
return $twig;
|
return $twig;
|
||||||
|
|||||||
@@ -16,11 +16,16 @@ class CommitController implements ControllerProviderInterface
|
|||||||
$repotmp = $app['git']->getRepositoryCached($app['git.repos'], $repo);
|
$repotmp = $app['git']->getRepositoryCached($app['git.repos'], $repo);
|
||||||
$repository = $app['git']->getRepository($repotmp->getPath());
|
$repository = $app['git']->getRepository($repotmp->getPath());
|
||||||
|
|
||||||
|
if ($branch === null) {
|
||||||
|
$branch = $repository->getHead();
|
||||||
|
}
|
||||||
|
|
||||||
list($branch, $file) = $app['util.repository']->extractRef($repository, $branch, $file);
|
list($branch, $file) = $app['util.repository']->extractRef($repository, $branch, $file);
|
||||||
|
|
||||||
$type = $file ? "$branch -- \"$file\"" : $branch;
|
$type = $file ? "$branch -- \"$file\"" : $branch;
|
||||||
$pager = $app['util.view']->getPager($app['request']->get('page'), $repository->getTotalCommits($type));
|
$pager = $app['util.view']->getPager($app['request']->get('page'), $repository->getTotalCommits($type));
|
||||||
$commits = $repository->getPaginatedCommits($type, $pager['current']);
|
$commits = $repository->getPaginatedCommits($type, $pager['current']);
|
||||||
|
$categorized = array();
|
||||||
|
|
||||||
foreach ($commits as $commit) {
|
foreach ($commits as $commit) {
|
||||||
$date = $commit->getDate();
|
$date = $commit->getDate();
|
||||||
@@ -31,6 +36,7 @@ class CommitController implements ControllerProviderInterface
|
|||||||
$template = $app['request']->isXmlHttpRequest() ? 'commits_list.twig' : 'commits.twig';
|
$template = $app['request']->isXmlHttpRequest() ? 'commits_list.twig' : 'commits.twig';
|
||||||
|
|
||||||
return $app['twig']->render($template, array(
|
return $app['twig']->render($template, array(
|
||||||
|
'page' => 'commits',
|
||||||
'pager' => $pager,
|
'pager' => $pager,
|
||||||
'repo' => $repo,
|
'repo' => $repo,
|
||||||
'branch' => $branch,
|
'branch' => $branch,
|
||||||
@@ -42,15 +48,23 @@ class CommitController implements ControllerProviderInterface
|
|||||||
})->assert('repo', $app['util.routing']->getRepositoryRegex())
|
})->assert('repo', $app['util.routing']->getRepositoryRegex())
|
||||||
->assert('branch', '[\w-._\/]+')
|
->assert('branch', '[\w-._\/]+')
|
||||||
->assert('file', '.+')
|
->assert('file', '.+')
|
||||||
->value('branch', 'master')
|
->value('branch', null)
|
||||||
->value('file', '')
|
->value('file', '')
|
||||||
->bind('commits');
|
->bind('commits');
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
$route->post('{repo}/commits/search', function(Request $request, $repo) use ($app) {
|
$route->post('{repo}/commits/search', function(Request $request, $repo) use ($app) {
|
||||||
$repotmp = $app['git']->getRepositoryCached($app['git.repos'], $repo);
|
$repotmp = $app['git']->getRepositoryCached($app['git.repos'], $repo);
|
||||||
$repository = $app['git']->getRepository($repotmp->getPath());
|
$repository = $app['git']->getRepository($repotmp->getPath());
|
||||||
|
|
||||||
$commits = $repository->searchCommitLog($request->get('query'));
|
$commits = $repository->searchCommitLog($request->get('query'));
|
||||||
|
=======
|
||||||
|
$route->post('{repo}/commits/{branch}/search', function(Request $request, $repo, $branch = '') use ($app) {
|
||||||
|
$repository = $app['git']->getRepository($app['git.repos'] . $repo);
|
||||||
|
$query = $request->get('query');
|
||||||
|
$commits = $repository->searchCommitLog($query);
|
||||||
|
$categorized = array();
|
||||||
|
>>>>>>> ab7ffc181b3d27a13e908a4e2b331a085b09f70b
|
||||||
|
|
||||||
foreach ($commits as $commit) {
|
foreach ($commits as $commit) {
|
||||||
$date = $commit->getDate();
|
$date = $commit->getDate();
|
||||||
@@ -60,13 +74,15 @@ class CommitController implements ControllerProviderInterface
|
|||||||
|
|
||||||
return $app['twig']->render('searchcommits.twig', array(
|
return $app['twig']->render('searchcommits.twig', array(
|
||||||
'repo' => $repo,
|
'repo' => $repo,
|
||||||
'branch' => 'master',
|
'branch' => $branch,
|
||||||
'file' => '',
|
'file' => '',
|
||||||
'commits' => $categorized,
|
'commits' => $categorized,
|
||||||
'branches' => $repository->getBranches(),
|
'branches' => $repository->getBranches(),
|
||||||
'tags' => $repository->getTags(),
|
'tags' => $repository->getTags(),
|
||||||
|
'query' => $query
|
||||||
));
|
));
|
||||||
})->assert('repo', $app['util.routing']->getRepositoryRegex())
|
})->assert('repo', $app['util.routing']->getRepositoryRegex())
|
||||||
|
->assert('branch', '[\w-._\/]+')
|
||||||
->bind('searchcommits');
|
->bind('searchcommits');
|
||||||
|
|
||||||
$route->get('{repo}/commit/{commit}/', function($repo, $commit) use ($app) {
|
$route->get('{repo}/commit/{commit}/', function($repo, $commit) use ($app) {
|
||||||
@@ -74,9 +90,10 @@ class CommitController implements ControllerProviderInterface
|
|||||||
$repository = $app['git']->getRepository($repotmp->getPath());
|
$repository = $app['git']->getRepository($repotmp->getPath());
|
||||||
|
|
||||||
$commit = $repository->getCommit($commit);
|
$commit = $repository->getCommit($commit);
|
||||||
|
$branch = $repository->getHead();
|
||||||
|
|
||||||
return $app['twig']->render('commit.twig', array(
|
return $app['twig']->render('commit.twig', array(
|
||||||
'branch' => 'master',
|
'branch' => $branch,
|
||||||
'repo' => $repo,
|
'repo' => $repo,
|
||||||
'commit' => $commit,
|
'commit' => $commit,
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -25,6 +25,10 @@ class MainController implements ControllerProviderInterface
|
|||||||
|
|
||||||
$repository = $app['git']->getRepository($repotmp->getPath());
|
$repository = $app['git']->getRepository($repotmp->getPath());
|
||||||
|
|
||||||
|
if ($branch === null) {
|
||||||
|
$branch = $repository->getHead();
|
||||||
|
}
|
||||||
|
|
||||||
$stats = $repository->getStatistics($branch);
|
$stats = $repository->getStatistics($branch);
|
||||||
$authors = $repository->getAuthorStatistics();
|
$authors = $repository->getAuthorStatistics();
|
||||||
|
|
||||||
@@ -38,7 +42,7 @@ class MainController implements ControllerProviderInterface
|
|||||||
));
|
));
|
||||||
})->assert('repo', $app['util.routing']->getRepositoryRegex())
|
})->assert('repo', $app['util.routing']->getRepositoryRegex())
|
||||||
->assert('branch', '[\w-._\/]+')
|
->assert('branch', '[\w-._\/]+')
|
||||||
->value('branch', 'master')
|
->value('branch', null)
|
||||||
->bind('stats');
|
->bind('stats');
|
||||||
|
|
||||||
$route->get('{repo}/{branch}/rss/', function($repo, $branch) use ($app) {
|
$route->get('{repo}/{branch}/rss/', function($repo, $branch) use ($app) {
|
||||||
|
|||||||
@@ -58,8 +58,9 @@ class TreeController implements ControllerProviderInterface
|
|||||||
$branch = $repository->getHead();
|
$branch = $repository->getHead();
|
||||||
}
|
}
|
||||||
|
|
||||||
$breadcrumbs = $app['util.view']->getBreadcrumbs($tree);
|
$query = $request->get('query');
|
||||||
$results = $repository->searchTree($request->get('query'), $branch);
|
$breadcrumbs = array(array('dir' => 'Search results for: ' . $query, 'path' => ''));
|
||||||
|
$results = $repository->searchTree($query, $branch);
|
||||||
|
|
||||||
return $app['twig']->render('search.twig', array(
|
return $app['twig']->render('search.twig', array(
|
||||||
'results' => $results,
|
'results' => $results,
|
||||||
|
|||||||
@@ -4,10 +4,162 @@ namespace GitList\Git;
|
|||||||
|
|
||||||
use Gitter\Repository as BaseRepository;
|
use Gitter\Repository as BaseRepository;
|
||||||
use Gitter\Model\Commit\Commit;
|
use Gitter\Model\Commit\Commit;
|
||||||
|
use Gitter\Model\Commit\Diff;
|
||||||
|
use Gitter\PrettyFormat;
|
||||||
use Symfony\Component\Filesystem\Filesystem;
|
use Symfony\Component\Filesystem\Filesystem;
|
||||||
|
|
||||||
class Repository extends BaseRepository
|
class Repository extends BaseRepository
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Show the data from a specific commit
|
||||||
|
*
|
||||||
|
* @param string $commitHash Hash of the specific commit to read data
|
||||||
|
* @return array Commit data
|
||||||
|
*/
|
||||||
|
public function getCommit($commitHash)
|
||||||
|
{
|
||||||
|
$logs = $this->getClient()->run($this, "show --pretty=format:\"<item><hash>%H</hash><short_hash>%h</short_hash><tree>%T</tree><parents>%P</parents><author>%an</author><author_email>%ae</author_email><date>%at</date><commiter>%cn</commiter><commiter_email>%ce</commiter_email><commiter_date>%ct</commiter_date><message><![CDATA[%s]]></message></item>\" $commitHash");
|
||||||
|
$logs = explode("\n", $logs);
|
||||||
|
|
||||||
|
// Read commit metadata
|
||||||
|
$format = new PrettyFormat;
|
||||||
|
$data = $format->parse($logs[0]);
|
||||||
|
$commit = new Commit;
|
||||||
|
$commit->importData($data[0]);
|
||||||
|
|
||||||
|
if ($commit->getParentsHash()) {
|
||||||
|
$command = 'diff ' . $commitHash . '~1..' . $commitHash;
|
||||||
|
$logs = explode("\n", $this->getClient()->run($this, $command));
|
||||||
|
} else {
|
||||||
|
$logs = array_slice($logs, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
$commit->setDiffs($this->readDiffLogs($logs));
|
||||||
|
|
||||||
|
return $commit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blames the provided file and parses the output
|
||||||
|
*
|
||||||
|
* @param string $file File that will be blamed
|
||||||
|
* @return array Commits hashes containing the lines
|
||||||
|
*/
|
||||||
|
public function getBlame($file)
|
||||||
|
{
|
||||||
|
$blame = array();
|
||||||
|
$logs = $this->getClient()->run($this, "blame --root -sl $file");
|
||||||
|
$logs = explode("\n", $logs);
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
$previousCommit = '';
|
||||||
|
foreach ($logs as $log) {
|
||||||
|
if ($log == '') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
preg_match_all("/([a-zA-Z0-9]{40})\s+.*?([0-9]+)\)(.+)/", $log, $match);
|
||||||
|
|
||||||
|
$currentCommit = $match[1][0];
|
||||||
|
if ($currentCommit != $previousCommit) {
|
||||||
|
++$i;
|
||||||
|
$blame[$i] = array(
|
||||||
|
'line' => '',
|
||||||
|
'commit' => $currentCommit,
|
||||||
|
'commitShort' => substr($currentCommit, 0, 8)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$blame[$i]['line'] .= PHP_EOL . $match[3][0];
|
||||||
|
$previousCommit = $currentCommit;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $blame;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read diff logs and generate a collection of diffs
|
||||||
|
*
|
||||||
|
* @param array $logs Array of log rows
|
||||||
|
* @return array Array of diffs
|
||||||
|
*/
|
||||||
|
public function readDiffLogs(array $logs)
|
||||||
|
{
|
||||||
|
$diffs = array();
|
||||||
|
$lineNumOld = 0;
|
||||||
|
$lineNumNew = 0;
|
||||||
|
foreach ($logs as $log) {
|
||||||
|
if ('diff' === substr($log, 0, 4)) {
|
||||||
|
if (isset($diff)) {
|
||||||
|
$diffs[] = $diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
$diff = new Diff;
|
||||||
|
if (preg_match('/^diff --[\S]+ a\/?(.+) b\/?/', $log, $name)) {
|
||||||
|
$diff->setFile($name[1]);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('index' === substr($log, 0, 5)) {
|
||||||
|
$diff->setIndex($log);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('---' === substr($log, 0, 3)) {
|
||||||
|
$diff->setOld($log);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('+++' === substr($log, 0, 3)) {
|
||||||
|
$diff->setNew($log);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle binary files properly.
|
||||||
|
if ('Binary' === substr($log, 0, 6)) {
|
||||||
|
$m = array();
|
||||||
|
if (preg_match('/Binary files (.+) and (.+) differ/', $log, $m)) {
|
||||||
|
$diff->setOld($m[1]);
|
||||||
|
$diff->setNew(" {$m[2]}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($log)) {
|
||||||
|
switch ($log[0]) {
|
||||||
|
case "@":
|
||||||
|
// Set the line numbers
|
||||||
|
preg_match('/@@ -([0-9]+)/', $log, $matches);
|
||||||
|
$lineNumOld = $matches[1] - 1;
|
||||||
|
$lineNumNew = $matches[1] - 1;
|
||||||
|
break;
|
||||||
|
case "-":
|
||||||
|
$lineNumOld++;
|
||||||
|
break;
|
||||||
|
case "+":
|
||||||
|
$lineNumNew++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$lineNumOld++;
|
||||||
|
$lineNumNew++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$lineNumOld++;
|
||||||
|
$lineNumNew++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($diff)) {
|
||||||
|
$diff->addLine($log, $lineNumOld, $lineNumNew);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($diff)) {
|
||||||
|
$diffs[] = $diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $diffs;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the repository commit log with pagination
|
* Show the repository commit log with pagination
|
||||||
*
|
*
|
||||||
@@ -24,7 +176,11 @@ class Repository extends BaseRepository
|
|||||||
$command .= " $file";
|
$command .= " $file";
|
||||||
}
|
}
|
||||||
|
|
||||||
$logs = $this->getPrettyFormat($command);
|
try {
|
||||||
|
$logs = $this->getPrettyFormat($command);
|
||||||
|
} catch (\RuntimeException $e) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($logs as $log) {
|
foreach ($logs as $log) {
|
||||||
$commit = new Commit;
|
$commit = new Commit;
|
||||||
@@ -37,9 +193,14 @@ class Repository extends BaseRepository
|
|||||||
|
|
||||||
public function searchCommitLog($query)
|
public function searchCommitLog($query)
|
||||||
{
|
{
|
||||||
$command = "log --grep='$query' --pretty=format:\"<item><hash>%H</hash><short_hash>%h</short_hash><tree>%T</tree><parent>%P</parent><author>%an</author><author_email>%ae</author_email><date>%at</date><commiter>%cn</commiter><commiter_email>%ce</commiter_email><commiter_date>%ct</commiter_date><message><![CDATA[%s]]></message></item>\"";
|
$query = escapeshellarg($query);
|
||||||
|
$command = "log --grep={$query} --pretty=format:\"<item><hash>%H</hash><short_hash>%h</short_hash><tree>%T</tree><parent>%P</parent><author>%an</author><author_email>%ae</author_email><date>%at</date><commiter>%cn</commiter><commiter_email>%ce</commiter_email><commiter_date>%ct</commiter_date><message><![CDATA[%s]]></message></item>\"";
|
||||||
|
|
||||||
$logs = $this->getPrettyFormat($command);
|
try {
|
||||||
|
$logs = $this->getPrettyFormat($command);
|
||||||
|
} catch (\RuntimeException $e) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($logs as $log) {
|
foreach ($logs as $log) {
|
||||||
$commit = new Commit;
|
$commit = new Commit;
|
||||||
@@ -52,8 +213,10 @@ class Repository extends BaseRepository
|
|||||||
|
|
||||||
public function searchTree($query, $branch)
|
public function searchTree($query, $branch)
|
||||||
{
|
{
|
||||||
|
$query = escapeshellarg($query);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$results = $this->getClient()->run($this, "grep -I --line-number '$query' $branch");
|
$results = $this->getClient()->run($this, "grep -I --line-number {$query} $branch");
|
||||||
} catch (\RuntimeException $e) {
|
} catch (\RuntimeException $e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -65,11 +228,13 @@ class Repository extends BaseRepository
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
preg_match_all('/([\w-._]+):(.+):([0-9]+):(.+)/', $result, $matches, PREG_SET_ORDER);
|
preg_match_all('/([\w-._]+):([^:]+):([0-9]+):(.+)/', $result, $matches, PREG_SET_ORDER);
|
||||||
|
|
||||||
$data['branch'] = $matches[0][1];
|
$data['branch'] = $matches[0][1];
|
||||||
$data['file'] = $matches[0][2];
|
$data['file'] = $matches[0][2];
|
||||||
$data['line'] = $matches[0][3];
|
$data['line'] = $matches[0][3];
|
||||||
$data['match'] = $matches[0][4];
|
$data['match'] = $matches[0][4];
|
||||||
|
|
||||||
$searchResults[] = $data;
|
$searchResults[] = $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ class Repository
|
|||||||
'r' => 'r',
|
'r' => 'r',
|
||||||
'sh' => 'shell',
|
'sh' => 'shell',
|
||||||
'ss' => 'scheme',
|
'ss' => 'scheme',
|
||||||
|
'scala' => 'text/x-scala',
|
||||||
'scm' => 'scheme',
|
'scm' => 'scheme',
|
||||||
'sls' => 'scheme',
|
'sls' => 'scheme',
|
||||||
'sps' => 'scheme',
|
'sps' => 'scheme',
|
||||||
@@ -160,10 +161,12 @@ class Repository
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getReadme($repository, $branch = 'master')
|
public function getReadme($repository, $branch = null)
|
||||||
{
|
{
|
||||||
#$repository = $this->app['git']->getRepository($this->app['git.repos'][$repo ]);
|
|
||||||
$files = $repository->getTree($branch)->output();
|
$files = $repository->getTree($branch)->output();
|
||||||
|
if ($branch === null) {
|
||||||
|
$branch = $repository->getHead();
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($files as $file) {
|
foreach ($files as $file) {
|
||||||
if (preg_match('/^readme*/i', $file['name'])) {
|
if (preg_match('/^readme*/i', $file['name'])) {
|
||||||
@@ -196,25 +199,23 @@ class Repository
|
|||||||
$branch = $matches[1];
|
$branch = $matches[1];
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, attempt to detect the ref using a list of the project's branches and tags
|
// Otherwise, attempt to detect the ref using a list of the project's branches and tags
|
||||||
$valid_refs = array_merge((array) $repository->getBranches(), (array) $repository->getTags());
|
$validRefs = array_merge((array) $repository->getBranches(), (array) $repository->getTags());
|
||||||
foreach ($valid_refs as $k => $v) {
|
foreach ($validRefs as $key => $ref) {
|
||||||
if (!preg_match("#{$v}/#", $input)) {
|
if (!preg_match(sprintf("#^%s/#", preg_quote($ref, '#')), $input)) {
|
||||||
unset($valid_refs[$k]);
|
unset($validRefs[$key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// No exact ref match, so just try our best
|
// No exact ref match, so just try our best
|
||||||
if (count($valid_refs) > 1) {
|
if (count($validRefs) > 1) {
|
||||||
preg_match('/([^\/]+)(.*)/', $input, $matches);
|
preg_match('/([^\/]+)(.*)/', $input, $matches);
|
||||||
$branch = preg_replace('/^\/|\/$/', '', $matches[0]);
|
$branch = preg_replace('/^\/|\/$/', '', $matches[1]);
|
||||||
} else {
|
} else {
|
||||||
// Extract branch name
|
// Extract branch name
|
||||||
$branch = array_shift($valid_refs);
|
$branch = array_shift($validRefs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$tree = trim(str_replace($branch, "", $input), "/");
|
|
||||||
|
|
||||||
return array($branch, $tree);
|
return array($branch, $tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ class Routing
|
|||||||
{
|
{
|
||||||
if (strpos($repoPath, $this->app['git.repos']) === 0) {
|
if (strpos($repoPath, $this->app['git.repos']) === 0) {
|
||||||
$relativePath = substr($repoPath, strlen($this->app['git.repos']));
|
$relativePath = substr($repoPath, strlen($this->app['git.repos']));
|
||||||
return ltrim($relativePath, '/');
|
return ltrim(strtr($relativePath, '\\', '/'), '/');
|
||||||
} else {
|
} else {
|
||||||
throw new \InvalidArgumentException(
|
throw new \InvalidArgumentException(
|
||||||
sprintf("Path '%s' does not match configured repository directory", $repoPath)
|
sprintf("Path '%s' does not match configured repository directory", $repoPath)
|
||||||
|
|||||||
@@ -79,6 +79,22 @@ class InterfaceTest extends WebTestCase
|
|||||||
$repository->commit("Changing branch");
|
$repository->commit("Changing branch");
|
||||||
$repository->checkout("master");
|
$repository->checkout("master");
|
||||||
|
|
||||||
|
// master-less repository fixture
|
||||||
|
$git->createRepository(self::$tmpdir . 'develop');
|
||||||
|
$repository = $git->getRepository(self::$tmpdir . '/develop');
|
||||||
|
$repository->setConfig('user.name', 'Luke Skywalker');
|
||||||
|
$repository->setConfig('user.email', 'luke@rebel.org');
|
||||||
|
file_put_contents(self::$tmpdir . 'develop/README.md', "## develop\ndevelop is a *test* repository!");
|
||||||
|
$repository->addAll();
|
||||||
|
$repository->commit("First commit");
|
||||||
|
$repository->createBranch("develop");
|
||||||
|
$repository = $repository->checkout('develop');
|
||||||
|
|
||||||
|
file_put_contents(self::$tmpdir . 'develop/test.php', "<?php\necho 'Hello World'; // This is a test");
|
||||||
|
$repository->setConfig('user.name', 'Luke Skywalker');
|
||||||
|
$repository->setConfig('user.email', 'luke@rebel.org');
|
||||||
|
$repository->addAll();
|
||||||
|
$repository->commit("Initial commit");
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createApplication()
|
public function createApplication()
|
||||||
@@ -110,8 +126,8 @@ class InterfaceTest extends WebTestCase
|
|||||||
$this->assertEquals('/nested/NestedRepo/master/rss/', $crawler->filter('.repository-header a')->eq(3)->attr('href'));
|
$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-header:contains("foobar")'));
|
||||||
$this->assertCount(1, $crawler->filter('div.repository-body:contains("This is a test repo!")'));
|
$this->assertCount(1, $crawler->filter('div.repository-body:contains("This is a test repo!")'));
|
||||||
$this->assertEquals('/foobar/', $crawler->filter('.repository-header a')->eq(4)->attr('href'));
|
$this->assertEquals('/foobar/', $crawler->filter('.repository-header a')->eq(6)->attr('href'));
|
||||||
$this->assertEquals('/foobar/master/rss/', $crawler->filter('.repository-header a')->eq(5)->attr('href'));
|
$this->assertEquals('/foobar/master/rss/', $crawler->filter('.repository-header a')->eq(7)->attr('href'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testRepositoryPage()
|
public function testRepositoryPage()
|
||||||
@@ -172,12 +188,12 @@ class InterfaceTest extends WebTestCase
|
|||||||
$crawler = $client->request('GET', '/GitTest/blame/master/test.php');
|
$crawler = $client->request('GET', '/GitTest/blame/master/test.php');
|
||||||
$this->assertTrue($client->getResponse()->isOk());
|
$this->assertTrue($client->getResponse()->isOk());
|
||||||
$this->assertCount(1, $crawler->filter('.source-header .meta:contains("test.php")'));
|
$this->assertCount(1, $crawler->filter('.source-header .meta:contains("test.php")'));
|
||||||
$this->assertRegexp('/\/GitTest\/commit\/[a-zA-Z0-9%]+\//', $crawler->filter('.blame-view .commit')->eq(0)->filter('a')->attr('href'));
|
$this->assertRegexp('/\/GitTest\/commit\/[a-zA-Z0-9%]+/', $crawler->filter('.blame-view .commit')->eq(0)->filter('a')->attr('href'));
|
||||||
|
|
||||||
$crawler = $client->request('GET', '/foobar/blame/master/bar.json');
|
$crawler = $client->request('GET', '/foobar/blame/master/bar.json');
|
||||||
$this->assertTrue($client->getResponse()->isOk());
|
$this->assertTrue($client->getResponse()->isOk());
|
||||||
$this->assertCount(1, $crawler->filter('.source-header .meta:contains("bar.json")'));
|
$this->assertCount(1, $crawler->filter('.source-header .meta:contains("bar.json")'));
|
||||||
$this->assertRegexp('/\/foobar\/commit\/[a-zA-Z0-9%]+\//', $crawler->filter('.blame-view .commit')->eq(0)->filter('a')->attr('href'));
|
$this->assertRegexp('/\/foobar\/commit\/[a-zA-Z0-9%]+/', $crawler->filter('.blame-view .commit')->eq(0)->filter('a')->attr('href'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testHistoryPage()
|
public function testHistoryPage()
|
||||||
@@ -241,6 +257,14 @@ class InterfaceTest extends WebTestCase
|
|||||||
$this->assertRegexp('/NESTED TEST REPO README/', $client->getResponse()->getContent());
|
$this->assertRegexp('/NESTED TEST REPO README/', $client->getResponse()->getContent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testDevelopRepo()
|
||||||
|
{
|
||||||
|
$client = $this->createClient();
|
||||||
|
|
||||||
|
$crawler = $client->request('GET', '/develop/');
|
||||||
|
$this->assertTrue($client->getResponse()->isOk());
|
||||||
|
}
|
||||||
|
|
||||||
public function testNestedRepoBranch()
|
public function testNestedRepoBranch()
|
||||||
{
|
{
|
||||||
$client = $this->createClient();
|
$client = $this->createClient();
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
<table class="blame-view">
|
<table class="blame-view">
|
||||||
{% for blame in blames %}
|
{% for blame in blames %}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="commit"><a href="{{ path('commit', {repo: repo, commit: blame.commit}) }}">{{ blame.commit }}</a></td>
|
<td class="commit"><a href="{{ path('commit', {repo: repo, commit: blame.commit}) }}">{{ blame.commitShort }}</a></td>
|
||||||
<td><pre>{{ blame.line }}</pre></td>
|
<td><pre>{{ blame.line }}</pre></td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
{% if commits %}
|
||||||
{% for date, commit in commits %}
|
{% for date, commit in commits %}
|
||||||
<table class="table table-striped table-bordered">
|
<table class="table table-striped table-bordered">
|
||||||
<thead>
|
<thead>
|
||||||
@@ -10,7 +11,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td width="5%"><img src="http://gravatar.com/avatar/{{ item.author.email | md5 }}?s=40" /></td>
|
<td width="5%"><img src="http://gravatar.com/avatar/{{ item.author.email | md5 }}?s=40" /></td>
|
||||||
<td width="95%">
|
<td width="95%">
|
||||||
<span class="pull-right"><a class="btn btn-small" href="{{ path('commit', {repo: repo, commit: item.shortHash}) }}"><i class="icon-list-alt"></i> View {{ item.shortHash }}</a></span>
|
<span class="pull-right"><a class="btn btn-small" href="{{ path('commit', {repo: repo, commit: item.hash}) }}"><i class="icon-list-alt"></i> View {{ item.shortHash }}</a></span>
|
||||||
<h4>{{ item.message }}</h4>
|
<h4>{{ item.message }}</h4>
|
||||||
<span><a href="mailto:{{ item.author.email }}">{{ item.author.name }}</a> authored in {{ item.date | date('d/m/Y \\a\\t H:i:s') }}</span>
|
<span><a href="mailto:{{ item.author.email }}">{{ item.author.name }}</a> authored in {{ item.date | date('d/m/Y \\a\\t H:i:s') }}</span>
|
||||||
</td>
|
</td>
|
||||||
@@ -19,6 +20,9 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
<p>No results found.</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if page != 'searchcommits' %}
|
{% if page != 'searchcommits' %}
|
||||||
<ul class="pager">
|
<ul class="pager">
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
<div class="readme-view"><div id="readme-content">{{ blob }}</div></div>
|
<div class="readme-view"><div id="readme-content">{{ blob }}</div></div>
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<pre id="sourcecode" language="{{ fileType }}">{{ blob }}</pre>
|
<pre id="sourcecode" language="{{ fileType }}">{{ blob|htmlentities|raw }}</pre>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="span12">
|
<div class="span12">
|
||||||
{% if page == 'commits' %}
|
{% if page in ['commits', 'searchcommits'] %}
|
||||||
<form class="form-search pull-right" action="{{ app.request.basepath }}/{{repo}}/commits/search" method="POST">
|
<form class="form-search pull-right" action="{{ app.request.basepath }}/{{repo}}/commits/{{branch}}/search" method="POST">
|
||||||
<input type="text" name="query" class="input-medium search-query" placeholder="Search commits...">
|
<input type="text" name="query" class="input-medium search-query" placeholder="Search commits...">
|
||||||
</form>
|
</form>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<ul class="nav nav-tabs">
|
<ul class="nav nav-tabs">
|
||||||
<li{% if page == 'files' %} class="active"{% endif %}><a href="{{ path('branch', {repo: repo, branch: branch}) }}">Files</a></li>
|
<li{% if page == 'files' %} class="active"{% endif %}><a href="{{ path('branch', {repo: repo, branch: branch}) }}">Files</a></li>
|
||||||
<li{% if page == 'commits' %} class="active"{% endif %}><a href="{{ path('commits', {repo: repo, branch: branch}) }}">Commits</a></li>
|
<li{% if page in ['commits', 'searchcommits'] %} class="active"{% endif %}><a href="{{ path('commits', {repo: repo, branch: branch}) }}">Commits</a></li>
|
||||||
<li{% if page == 'stats' %} class="active"{% endif %}><a href="{{ path('stats', {repo: repo, branch: branch}) }}">Stats</a></li>
|
<li{% if page == 'stats' %} class="active"{% endif %}><a href="{{ path('stats', {repo: repo, branch: branch}) }}">Stats</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<title>{{ commit.message }}</title>
|
<title>{{ commit.message }}</title>
|
||||||
<description>{{ commit.author.name }} authored {{ commit.shortHash }} in {{ commit.date | date('d/m/Y \\a\\t H:i:s') }}</description>
|
<description>{{ commit.author.name }} authored {{ commit.shortHash }} in {{ commit.date | date('d/m/Y \\a\\t H:i:s') }}</description>
|
||||||
<link>{{ path('commit', {repo: repo, commit: commit.shortHash}) }}</link>
|
<link>{{ path('commit', {repo: repo, commit: commit.hash}) }}</link>
|
||||||
<pubDate>{{ commit.date | date('r') }}</pubDate>
|
<pubDate>{{ commit.date | date('r') }}</pubDate>
|
||||||
</item>
|
</item>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
{% block title %}GitList{% endblock %}
|
{% block title %}GitList{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% include 'breadcrumb.twig' with {breadcrumbs: [{dir: 'Commits search results', path:''}]} %}
|
{% include 'breadcrumb.twig' with {breadcrumbs: [{dir: 'Commits search results for: ' ~ query, path:''}]} %}
|
||||||
|
|
||||||
{% include 'commits_list.twig' %}
|
{% include 'commits_list.twig' %}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user