--- /dev/null
+<p><?php
+if($_GET["p"]){
+ $hash = shell_exec("git --git-dir=/home/git/".$_GET["p"]." rev-list -n 1 --pretty='format:%h' --header master | grep '^[0-9a-f]*$'");
+ if(!$hash){
+ echo "<b>unknown project or no bugtracker for this project</b>";
+ }else{
+ echo "<b>under construction</b>";
+ }
+}else{
+ echo "<b>unknown project or no bugtracker for this project</b";
+}
+?></p>
\ No newline at end of file
--- /dev/null
+<?php
+if(isset($_GET['p'])){
+ if(file_exists("/home/git/".$_GET['p'])){
+ $hash = shell_exec("git --git-dir=/home/git/".$_GET["p"]." rev-list -n 1 --pretty='format:%h' --header master | grep '^[0-9a-f]*$'");
+ $con= shell_exec('git --git-dir=/home/git/'.$_GET["p"].' rev-list --oneline --header master | wc -l | sed "s/[ \t]//g"');
+ if(!$hash){
+ echo "<p>".$_GET["p"].": No Download available</p>";
+ }else{
+ $name=substr($_GET["p"],0,strlen($_GET["p"])-4);
+ if(file_exists("/usr/share/gitweb/dl/".$name."-git-".substr($con, 0, -1)."-".substr($hash, 0, -1).".tar.gz")) {
+ echo "<p>".$_GET["p"].": Download <a href='http://git.nexus-irc.de/dl/".$name."-git-".substr($con, 0, -1)."-".substr($hash, 0, -1).".tar.gz'>git-".substr($con, 0, -1)."-".substr($hash, 0, -1)."</a></p>";
+ } else {
+ echo "<p>".$_GET["p"].": No Download available (<a href='http://git.nexus-irc.de/git_download.php?build2=".$_GET["p"]."'>Build snapshot</a>)</p>";
+ }
+ }
+ }else{
+ echo "unknown project";
+ }
+}elseif(isset($_GET['build'])){
+ if(file_exists("/home/git/".$_GET['build'])){
+ $name=substr($_GET['build'],0,strlen($_GET['build'])-4);
+ if(file_exists("/usr/share/gitweb/dl/".$name."-git-".substr($con, 0, -1)."-".substr($hash, 0, -1).".tar.gz")) {
+ echo '<meta http-equiv="refresh" content="0; URL=http://git.nexus-irc.de/?a=downloads"> ';
+ }else{
+ $hash = shell_exec("git --git-dir=/home/git/".$_GET['build']." rev-list -n 1 --pretty='format:%h' --header master | grep '^[0-9a-f]*$'");
+ $con= shell_exec('git --git-dir=/home/git/'.$_GET['build'].' rev-list --oneline --header master | wc -l | sed "s/[ \t]//g"');
+ $b = shell_exec("cd /usr/share/gitweb/dl; git clone git://git.nexus-irc.de/".$_GET['build']);
+ $c = shell_exec("cd /usr/share/gitweb/dl; tar czfv ".$name."-git-".substr($con, 0, -1)."-".substr($hash, 0, -1).".tar.gz ".$name);
+ $d = shell_exec("rm -r /usr/share/gitweb/dl/".$name);
+ echo '<meta http-equiv="refresh" content="0; URL=http://git.nexus-irc.de/?a=downloads"> ';
+ }
+ }else{
+ echo "unknown project";
+ }
+}elseif(isset($_GET['build2'])){
+ if(file_exists("/home/git/".$_GET['build2'])){
+ $name=substr($_GET['build2'],0,strlen($_GET['build2'])-4);
+ if(file_exists("/usr/share/gitweb/dl/".$name."-git-".substr($con, 0, -1)."-".substr($hash, 0, -1).".tar.gz")) {
+ echo '<meta http-equiv="refresh" content="0; URL=http://git.nexus-irc.de/?p='.$_GET['build2'].';a=download"> ';
+ }else{
+ $hash = shell_exec("git --git-dir=/home/git/".$_GET['build2']." rev-list -n 1 --pretty='format:%h' --header master | grep '^[0-9a-f]*$'");
+ $con= shell_exec('git --git-dir=/home/git/'.$_GET['build2'].' rev-list --oneline --header master | wc -l | sed "s/[ \t]//g"');
+ $b = shell_exec("cd /usr/share/gitweb/dl/; git clone git://git.nexus-irc.de/".$_GET['build2']);
+ $c = shell_exec("cd /usr/share/gitweb/dl; tar czfv ".$name."-git-".substr($con, 0, -1)."-".substr($hash, 0, -1).".tar.gz ".$name);
+ $d = shell_exec("rm -r /usr/share/gitweb/dl/".$name);
+ echo '<meta http-equiv="refresh" content="0; URL=http://git.nexus-irc.de/?p='.$_GET['build2'].';a=download"> ';
+ }
+ }else{
+ echo "unknown project";
+ }
+}else{
+ $a = file_get_contents("http://git.nexus-irc.de/index.cgi?a=project_index2");
+ $b = explode("\n",$a);
+ foreach($b as $id => $v) {
+ if($v == ""){ }else{
+ $hash = shell_exec("git --git-dir=/home/git/".$v." rev-list -n 1 --pretty='format:%h' --header master | grep '^[0-9a-f]*$'");
+ $con= shell_exec('git --git-dir=/home/git/'.$v.' rev-list --oneline --header master | wc -l | sed "s/[ \t]//g"');
+ if(!$hash){
+ echo "<p>".$v.": No Download available</p>";
+ }else{
+ $name=substr($v,0,strlen($v)-4);
+ if(file_exists("/usr/share/gitweb/dl/".$name."-git-".substr($con, 0, -1)."-".substr($hash, 0, -1).".tar.gz")) {
+ echo "<p>".$v.": Download <a href='http://git.nexus-irc.de/dl/".$name."-git-".substr($con, 0, -1)."-".substr($hash, 0, -1).".tar.gz'>git-".substr($con, 0, -1)."-".substr($hash, 0, -1)."</a></p>";
+ } else {
+ echo "<p>".$v.": No Download available (<a href='http://git.nexus-irc.de/git_download.php?build=".$v."'>Build snapshot</a>)</p>";
+ }
+ }
+ }
+ }
+}
+?>
\ No newline at end of file
--- /dev/null
+<?php
+
+/* CONFIG */
+$repo_path = "/home/git/";
+$project_list = null;
+
+$size = 20;
+$tile_size = 20; /* do not edit */
+
+$max_branches = 30;
+$use_local_branches = true;
+$use_remote_branches = true;
+
+$colors = array(
+ NULL,
+ array(255, 0, 0),
+ array(0, 255, 0),
+ array(0, 0, 255),
+ array(128, 128, 128),
+ array(128, 128, 0),
+ array(0, 128, 128),
+ array(128, 0, 128)
+);
+/* END CONFIG */
+
+session_start();
+
+//parse ; seprated query args
+$args = explode(";", $_SERVER["QUERY_STRING"]);
+foreach($args as $arg) {
+ $arg = explode("=", $arg, 2);
+ $_GET[$arg[0]] = $arg[1];
+}
+
+if($_SESSION['gitgraph_maxbranch'])
+ $max_branches = $_SESSION['gitgraph_maxbranch'];
+if($_GET['maxbranch']) {
+ $_SESSION['gitgraph_maxbranch'] = $_GET['maxbranch'];
+ die("maxbranch set.");
+}
+
+//check if project is in $project_list
+$project = NULL;
+if($project_list) {
+ $projects = file_get_contents($project_list);
+ foreach(explode("\n", $projects) as $cproject) {
+ $cproject = explode(" ", $cproject);
+ if(strtolower($_GET['p']) == strtolower($cproject[0])) {
+ if(file_exists($repo_path.$cproject[0]))
+ $project = $cproject[0];
+ break;
+ }
+ }
+} else {
+ if(!preg_match('#^[a-z0-9.-_]*$#i', $_GET['p']))
+ die("ERROR 0x01");
+ if(file_exists($repo_path.$_GET['p']))
+ $project = $_GET['p'];
+}
+if(!$project)
+ die("ERROR 0x02");
+
+//check other args
+if(!preg_match('#^[a-z0-9/.-_]*$#i', $_GET['h']))
+ die("ERROR 0x03");
+if(!preg_match('#^[a-z0-9]*$#i', $_GET['c']))
+ die("ERROR 0x04");
+if(!preg_match('#^[0-9]*$#i', $_GET['from']))
+ die("ERROR 0x05");
+if(!preg_match('#^[0-9]*$#i', $_GET['to']))
+ die("ERROR 0x06");
+
+//load old cache
+$data = array();
+if($_SESSION['git_graph']) {
+ $old_data = unserialize($_SESSION['git_graph']);
+ if($old_data['r'] == $_GET['r'])
+ $data = $old_data;
+}
+
+function parse_commit($commit_data) {
+ $commit = array();
+ $rev_lines = explode("\n", str_replace("\r", "", $commit_data));
+ $commit['id'] = $rev_lines[0];
+ foreach($rev_lines as $rev_line) {
+ if(substr($rev_line, 0, 4) == " ") {
+ if($commit['text'])
+ $commit['text'] .= "\n";
+ $commit['text'] .= substr($rev_line, 4);
+ } else {
+ $opt = explode(" ", $rev_line);
+ if($opt[0] == "tree")
+ $commit['tree'] = $opt[1];
+ else if($opt[0] == "parent")
+ $commit['parent'][] = $opt[1];
+ else if($opt[0] == "author") {
+ $commit['author'] = $opt[1];
+ $commit['author_mail'] = $opt[2];
+ $commit['author_time'] = $opt[3];
+ } else if($opt[0] == "committer") {
+ $commit['committer'] = $opt[1];
+ $commit['committer_mail'] = $opt[2];
+ $commit['committer_time'] = $opt[3];
+ }
+ }
+ }
+ return $commit;
+}
+
+//load rev-list
+if(!$data['commits']) {
+ $cmd = "git --git-dir=".$repo_path.$project." rev-list --header --max-count=".($_GET['to'] + 1)." ".($_GET['h'] =="all" ? "--all" : $_GET['h']);
+ $rev_list = shell_exec($cmd);
+ foreach(explode("\000", $rev_list) as $rev) {
+ $data['commits'][] = parse_commit($rev);
+ }
+}
+
+//save cache
+$_SESSION['git_graph'] = serialize($data);
+
+//generate graph data
+$data['branches'] = array();
+$data['ubranches'] = array();
+$brach_id = 1;
+$brach_uid = 1;
+$graph_commit = NULL;
+$first_commit = true;
+
+if($_GET['h'] == "all") {
+ //set master branch as first branch
+ $cmd = "git --git-dir=".$repo_path.$project." rev-list --header --max-count=1 HEAD";
+ $head_list = shell_exec($cmd);
+ $head = parse_commit($head_list);
+ $first_commit = false;
+ $data['branches'][count($data['branches'])] = array();
+ $branch = &$data['branches'][count($data['branches'])-1];
+ $branch['id'] = $brach_id++;
+ $branch['uid'] = $branch_uid++;
+ $branch['active'] = true;
+ $branch['next'] = $head['id'];
+ unset($branch);
+ if($use_local_branches) {
+ $cmd = "git --git-dir=".$repo_path.$project." for-each-ref --sort=-committerdate refs/heads/";
+ $head_list = shell_exec($cmd);
+ foreach(explode("\n", str_replace("\r", "", $head_list)) as $head) {
+ $head = explode(" ", $head);
+ if(!$head[0])
+ continue;
+ $existing = false;
+ foreach($data['branches'] as $branch) {
+ if($branch['next'] == $head[0]) {
+ $existing = true;
+ break;
+ }
+ }
+ if($existing)
+ continue;
+ $data['branches'][count($data['branches'])] = array(
+ "id" => $brach_id++,
+ "uid" => $brach_uid++,
+ "active" => true,
+ "next" => $head[0]
+ );
+ }
+ }
+ if($use_remote_branches) {
+ $cmd = "git --git-dir=".$repo_path.$project." for-each-ref --sort=-committerdate refs/remotes/";
+ $head_list = shell_exec($cmd);
+ foreach(explode("\n", str_replace("\r", "", $head_list)) as $head) {
+ $head = explode(" ", $head);
+ if(!$head[0])
+ continue;
+ $existing = false;
+ foreach($data['branches'] as $branch) {
+ if($branch['next'] == $head[0]) {
+ $existing = true;
+ break;
+ }
+ }
+ if($existing)
+ continue;
+ $data['branches'][count($data['branches'])] = array(
+ "id" => $brach_id++,
+ "uid" => $brach_uid++,
+ "active" => true,
+ "next" => $head[0]
+ );
+ }
+ }
+}
+
+for($i = 0; $i <= intval($_GET['to']); $i++) {
+//for($i = 0; $i < count($data['commits']); $i++) {
+ $commit = &$data['commits'][$i];
+ //get current branch
+ if($first_commit) {
+ $first_commit = false;
+ $data['branches'][0] = array();
+ $branch = &$data['branches'][0];
+ $branch['id'] = $brach_id++;
+ $branch['uid'] = $branch_uid++;
+ $branch['active'] = true;
+ } else {
+ $first = true;
+ foreach($data['branches'] as $id => &$cbranch) {
+ if($cbranch['next'] == $commit['id']) {
+ if($first && !$cbranch['pre_merge']) {
+ $branch = &$data['branches'][$id];
+ $first = false;
+ }
+ }
+ }
+ foreach($data['branches'] as $id => &$cbranch) {
+ if($cbranch['next'] == $commit['id']) {
+ if($first) {
+ $branch = &$data['branches'][$id];
+ $first = false;
+ } else if($cbranch['id'] == $branch['id']) {
+ } else {
+ $commit['merge'][] = array("point" => $cbranch['id'], "start" => true);
+ $cbranch['active'] = false;
+ if($cbranch['pre_merge']) {
+ $cbranch['pre_merge_start'] = true;
+ $cbranch['pre_merge_id'] = $branch['id'];
+ $data['ubranches'][$cbranch['uid']] = $data['branches'][$cbranch['id']-1];
+ }
+ }
+ }
+ }
+ unset($cbranch);
+ if($first) {
+ $data['branches'][count($data['branches'])] = array();
+ $branch = &$data['branches'][count($data['branches'])-1];
+ $branch['id'] = $brach_id++;
+ $branch['uid'] = $branch_uid++;
+ $branch['active'] = true;
+ }
+ }
+
+ if(count($commit['parent']) > 1) {
+ //merge(s)
+ for($j = 1; $j < count($commit['parent']); $j++) {
+ $add = true;
+ foreach($data['branches'] as $cbranch) {
+ if($cbranch['next'] == $commit['parent'][$j]) {
+ $add = false;
+ break;
+ }
+ }
+ if($add) {
+ $cadd = true;
+ foreach($data['branches'] as $bid => &$cbranch) {
+ if(!$cbranch['active']) {
+ $cadd = false;
+ break;
+ }
+ }
+ if($cadd) {
+ $data['branches'][count($data['branches'])] = array();
+ $cbranch = &$data['branches'][count($data['branches'])-1];
+ $cbranch['id'] = $brach_id++;
+ }
+ $cbranch['uid'] = $branch_uid++;
+ $cbranch['active'] = true;
+ $cbranch['pre_merge'] = true;
+ $cbranch['next'] = $commit['parent'][$j];
+ }
+ $commit['merge'][] = array("point" => $cbranch['id'], "end" => $add);
+ $commit['dot_merge'] = true;
+ $data['ubranches'][$cbranch['uid']] = $data['branches'][$cbranch['id']-1];
+ unset($cbranch);
+ }
+ } else if(count($commit['parent']) == 0) {
+ $branch['active'] = false;
+ $commit['dot_init'] = true;
+ }
+ $branch['next'] = $commit['parent'][0];
+ $branch['pre_merge'] = false;
+ $data['ubranches'][$branch['uid']] = $data['branches'][$branch['id']-1];
+
+ $commit['dot'] = $branch['id'];
+
+ foreach($data['branches'] as $id => $cbranch) {
+ $commit['branches'][$id] = $cbranch;
+ }
+
+ if($commit['id'] == $_GET['c']) {
+ //yeaaa i've found a PHP Bug :D
+ //$graph_commit['branches'] still gets updated.. (damn references)
+ //we need a fully independent copy of the array....
+ $graph_commit = $commit;
+ }
+}
+
+if($graph_commit == NULL)
+ die("ERROR 0x07");
+
+//DEV Breakpoint
+//print_r($data);
+//die();
+
+//generate image
+$count = count($data['branches']);
+if($count > $max_branches)
+ $count = $max_branches;
+$image = imagecreatetruecolor($count * $size, $size);
+$transparentIndex = imagecolorallocate($image, 0xFF, 0xFF, 0xFF);
+imagefill($image, 0, 0, $transparentIndex);
+
+function image_set_color($src, $color) {
+ global $size;
+ imagesavealpha($src, true);
+ imagealphablending($src, false);
+ // scan image pixels
+ for ($x = 0; $x < $size; $x++) {
+ for ($y = 0; $y < $size; $y++) {
+ $src_pix = imagecolorat($src,$x,$y);
+ $src_pix_array = imagecolorsforindex($src, $src_pix);
+
+ imagesetpixel($src, $x, $y, imagecolorallocatealpha($src, $color[0], $color[1], $color[2], $src_pix_array['alpha']));
+ }
+ }
+}
+
+function overlay_image($name, $left, $color = false) {
+ global $image, $size, $tile_size;
+ $image2 = imagecreatefrompng($name);
+
+ if($color) {
+ image_set_color($image2, $color);
+ }
+ imagecopyresampled($image, $image2, $left, 0, 0, 0, $size, $size, $tile_size, $tile_size);
+}
+
+function get_color($id) {
+ global $colors, $graph_commit, $data;
+ if($graph_commit['branches'][($id-1)]['pre_merge']) {
+ $branch = $data['ubranches'][$graph_commit['branches'][($id-1)]['uid']];
+ if($branch['pre_merge'] && $branch['pre_merge_start'])
+ $id = $branch['pre_merge_id'];
+ }
+ return $colors[($id - 1) % count($colors)];
+}
+
+foreach($graph_commit['branches'] as $branch) {
+ $left = ($branch['id']-1) * $size;
+ if($branch['active']) {
+ if($graph_commit['dot'] == $branch['id']) continue;
+ $show = true;
+ if($graph_commit['merge']) {
+ foreach($graph_commit['merge'] as $merge) {
+ if($merge['point'] == $branch['id']) {
+ $show = false;
+ break;
+ }
+ }
+ }
+ if(!$show) continue;
+ if($branch['id'] > $max_branches) continue;
+ overlay_image("images/line.png", $left, get_color($branch['id']));
+ }
+}
+
+if($graph_commit['merge']) {
+ foreach($graph_commit['merge'] as $merge) {
+ $dot_dir = ($graph_commit['dot'] < $merge['point'] ? "right" : "left");
+ $merge_dir = ($graph_commit['dot'] < $merge['point'] ? "left" : "right");
+
+ if($graph_commit['dot'] <= $max_branches)
+ overlay_image("images/dot_merge_".$dot_dir.".png", ($graph_commit['dot'] - 1) * $size, get_color($merge['point']));
+
+ if($merge['point'] <= $max_branches) {
+ overlay_image("images/".($merge['start'] ? "branch" : "merge")."_".$merge_dir.".png", ($merge['point'] - 1) * $size, get_color($merge['point']));
+ if(!$merge['start'] && !$merge['end'])
+ overlay_image("images/line.png", ($merge['point'] - 1) * $size, get_color($merge['point']));
+ }
+ $min = ($graph_commit['dot'] < $merge['point'] ? $graph_commit['dot'] : $merge['point']) + 1;
+ $max = ($graph_commit['dot'] < $merge['point'] ? $merge['point'] : $graph_commit['dot']);
+ for($i = $min; $i < $max; $i++) {
+ if($i > $max_branches) continue;
+ overlay_image("images/line_h.png", ($i - 1) * $size, get_color($merge['point']));
+ }
+ }
+ if($graph_commit['dot'] <= $max_branches) {
+ if($graph_commit['dot_merge'])
+ overlay_image("images/dot_merge.png", ($graph_commit['dot'] - 1) * $size, get_color($graph_commit['dot']));
+ else
+ overlay_image("images/dot.png", ($graph_commit['dot'] - 1) * $size, get_color($graph_commit['dot']));
+ }
+} else if($graph_commit['dot_init']) {
+ if($graph_commit['dot'] <= $max_branches)
+ overlay_image("images/dot_init.png", ($graph_commit['dot'] - 1) * $size, get_color($graph_commit['dot']));
+} else if($graph_commit['dot']) {
+ if($graph_commit['dot'] <= $max_branches)
+ overlay_image("images/dot.png", ($graph_commit['dot'] - 1) * $size, get_color($graph_commit['dot']));
+}
+
+imagecolortransparent($image, $transparentIndex);
+
+header('Content-Type: image/png');
+imagepng($image);
+imagedestroy($image);
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+if($_GET["git"]){
+ $hash = shell_exec("git --git-dir=/home/git/".$_GET["git"]." rev-list -n 1 --pretty='format:%h' --header master | grep '^[0-9a-f]*$'");
+ $con= shell_exec('git --git-dir=/home/git/'.$_GET["git"].' rev-list --oneline --header master | wc -l | sed "s/[ \t]//g"');
+ if(!$hash){
+ echo "git-0-0";
+ }else{
+ echo "git-".substr($con, 0, -1)."-".substr($hash, 0, -1);
+ }
+}else{
+ echo "404 - No such project";
+}
+?>
--- /dev/null
+body {
+ font-family: sans-serif;
+ font-size: small;
+ border: solid #d9d8d1;
+ border-width: 1px;
+ margin: 10px;
+ background-color: #ffffff;
+ color: #000000;
+}
+
+a {
+ color: #0000cc;
+}
+
+a:hover, a:visited, a:active {
+ color: #880000;
+}
+
+span.cntrl {
+ border: dashed #aaaaaa;
+ border-width: 1px;
+ padding: 0px 2px 0px 2px;
+ margin: 0px 2px 0px 2px;
+}
+
+img.logo {
+ float: right;
+ border-width: 0px;
+}
+
+img.avatar {
+ vertical-align: middle;
+}
+
+a.list img.avatar {
+ border-style: none;
+}
+
+div.page_header {
+ height: 25px;
+ padding: 8px;
+ font-size: 150%;
+ font-weight: bold;
+ background-color: #d9d8d1;
+}
+
+div.page_header a:visited, a.header {
+ color: #0000cc;
+}
+
+div.page_header a:hover {
+ color: #880000;
+}
+
+div.page_nav {
+ padding: 8px;
+}
+
+div.page_nav a:visited {
+ color: #0000cc;
+}
+
+div.page_path {
+ padding: 8px;
+ font-weight: bold;
+ border: solid #d9d8d1;
+ border-width: 0px 0px 1px;
+}
+
+div.page_footer {
+ height: 17px;
+ padding: 4px 8px;
+ background-color: #d9d8d1;
+}
+
+div.page_footer_text {
+ float: left;
+ color: #555555;
+ font-style: italic;
+}
+
+div#generating_info {
+ margin: 4px;
+ font-size: smaller;
+ text-align: center;
+ color: #505050;
+}
+
+div.page_body {
+ padding: 8px;
+ font-family: monospace;
+}
+
+div.title, a.title {
+ display: block;
+ padding: 6px 8px;
+ font-weight: bold;
+ background-color: #edece6;
+ text-decoration: none;
+ color: #000000;
+}
+
+div.readme {
+ padding: 8px;
+}
+
+a.title:hover {
+ background-color: #d9d8d1;
+}
+
+div.title_text {
+ padding: 6px 0px;
+ border: solid #d9d8d1;
+ border-width: 0px 0px 1px;
+ font-family: monospace;
+}
+
+div.log_body {
+ padding: 8px 8px 8px 150px;
+}
+
+span.age {
+ position: relative;
+ float: left;
+ width: 142px;
+ font-style: italic;
+}
+
+span.signoff {
+ color: #888888;
+}
+
+div.log_link {
+ padding: 0px 8px;
+ font-size: 70%;
+ font-family: sans-serif;
+ font-style: normal;
+ position: relative;
+ float: left;
+ width: 136px;
+}
+
+div.list_head {
+ padding: 6px 8px 4px;
+ border: solid #d9d8d1;
+ border-width: 1px 0px 0px;
+ font-style: italic;
+}
+
+.author_date, .author {
+ font-style: italic;
+}
+
+div.author_date {
+ padding: 8px;
+ border: solid #d9d8d1;
+ border-width: 0px 0px 1px 0px;
+}
+
+a.list {
+ text-decoration: none;
+ color: #000000;
+}
+
+a.subject, a.name {
+ font-weight: bold;
+}
+
+table.tags a.subject {
+ font-weight: normal;
+}
+
+a.list:hover {
+ text-decoration: underline;
+ color: #880000;
+}
+
+a.text {
+ text-decoration: none;
+ color: #0000cc;
+}
+
+a.text:visited {
+ text-decoration: none;
+ color: #880000;
+}
+
+a.text:hover {
+ text-decoration: underline;
+ color: #880000;
+}
+
+table {
+ padding: 8px 4px;
+ border-spacing: 0;
+}
+
+table.shortlog td {
+ padding: 0px 8px;
+ vertical-align: middle;
+ height:20px;
+}
+
+img.graph {
+ padding: 0px;
+ margin: 0px;
+ display: block;
+}
+
+table.diff_tree {
+ font-family: monospace;
+}
+
+table.combined.diff_tree th {
+ text-align: center;
+}
+
+table.combined.diff_tree td {
+ padding-right: 24px;
+}
+
+table.combined.diff_tree th.link,
+table.combined.diff_tree td.link {
+ padding: 0px 2px;
+}
+
+table.combined.diff_tree td.nochange a {
+ color: #6666ff;
+}
+
+table.combined.diff_tree td.nochange a:hover,
+table.combined.diff_tree td.nochange a:visited {
+ color: #d06666;
+}
+
+table.blame {
+ border-collapse: collapse;
+}
+
+table.blame td {
+ padding: 0px 5px;
+ font-size: 100%;
+ vertical-align: top;
+}
+
+th {
+ padding: 2px 5px;
+ font-size: 100%;
+ text-align: left;
+}
+
+/* do not change row style on hover for 'blame' view */
+tr.light,
+table.blame .light:hover {
+ background-color: #ffffff;
+}
+
+tr.dark,
+table.blame .dark:hover {
+ background-color: #f6f6f0;
+}
+
+/* currently both use the same, but it can change */
+tr.light:hover,
+tr.dark:hover {
+ background-color: #edece6;
+}
+
+/* boundary commits in 'blame' view */
+/* and commits without "previous" */
+tr.boundary td.sha1,
+tr.no-previous td.linenr {
+ font-weight: bold;
+}
+
+/* for 'blame_incremental', during processing */
+tr.color1 { background-color: #f6fff6; }
+tr.color2 { background-color: #f6f6ff; }
+tr.color3 { background-color: #fff6f6; }
+
+td {
+ padding: 2px 5px;
+ font-size: 100%;
+ vertical-align: top;
+}
+
+td.link, td.selflink {
+ padding: 2px 5px;
+ font-family: sans-serif;
+ font-size: 70%;
+}
+
+td.selflink {
+ padding-right: 0px;
+}
+
+td.sha1 {
+ font-family: monospace;
+}
+
+.error {
+ color: red;
+ background-color: yellow;
+}
+
+td.current_head {
+ text-decoration: underline;
+}
+
+table.diff_tree span.file_status.new {
+ color: #008000;
+}
+
+table.diff_tree span.file_status.deleted {
+ color: #c00000;
+}
+
+table.diff_tree span.file_status.moved,
+table.diff_tree span.file_status.mode_chnge {
+ color: #777777;
+}
+
+table.diff_tree span.file_status.copied {
+ color: #70a070;
+}
+
+/* noage: "No commits" */
+table.project_list td.noage {
+ color: #808080;
+ font-style: italic;
+}
+table.shortlog td.noage, table.history td.noage {
+ color: #808080;
+ font-style: italic;
+}
+
+/* age2: 60*60*24*2 <= age */
+table.project_list td.age2, table.blame td.age2 {
+ font-style: italic;
+}
+table.shortlog td.age2, table.history td.age2 {
+ font-style: italic;
+}
+
+/* age1: 60*60*2 <= age < 60*60*24*2 */
+table.shortlog td.age1, table.project_list td.age1, table.history td.age1 {
+ color: #009900;
+ font-style: italic;
+}
+
+table.blame td.age1 {
+ color: #009900;
+ background: transparent;
+}
+
+/* age0: age < 60*60*2 */
+table.project_list td.age0 {
+ color: #009900;
+ font-style: italic;
+ font-weight: bold;
+}
+table.shortlog td.age0, table.history td.age0 {
+ color: #009900;
+ font-style: italic;
+ font-weight: bold;
+}
+
+table.blame td.age0 {
+ color: #009900;
+ background: transparent;
+ font-weight: bold;
+}
+
+td.pre, div.pre, div.diff {
+ font-family: monospace;
+ font-size: 12px;
+ white-space: pre;
+}
+
+td.mode {
+ font-family: monospace;
+}
+
+/* progress of blame_interactive */
+div#progress_bar {
+ height: 2px;
+ margin-bottom: -2px;
+ background-color: #d8d9d0;
+}
+div#progress_info {
+ float: right;
+ text-align: right;
+}
+
+/* format of (optional) objects size in 'tree' view */
+td.size {
+ font-family: monospace;
+ text-align: right;
+}
+
+/* styling of diffs (patchsets): commitdiff and blobdiff views */
+div.diff.header,
+div.diff.extended_header {
+ white-space: normal;
+}
+
+div.diff.header {
+ font-weight: bold;
+
+ background-color: #edece6;
+
+ margin-top: 4px;
+ padding: 4px 0px 2px 0px;
+ border: solid #d9d8d1;
+ border-width: 1px 0px 1px 0px;
+}
+
+div.diff.header a.path {
+ text-decoration: underline;
+}
+
+div.diff.extended_header,
+div.diff.extended_header a.path,
+div.diff.extended_header a.hash {
+ color: #777777;
+}
+
+div.diff.extended_header .info {
+ color: #b0b0b0;
+}
+
+div.diff.extended_header {
+ background-color: #f6f5ee;
+ padding: 2px 0px 2px 0px;
+}
+
+div.diff a.list,
+div.diff a.path,
+div.diff a.hash {
+ text-decoration: none;
+}
+
+div.diff a.list:hover,
+div.diff a.path:hover,
+div.diff a.hash:hover {
+ text-decoration: underline;
+}
+
+div.diff.to_file a.path,
+div.diff.to_file {
+ color: #007000;
+}
+
+div.diff.add {
+ color: #008800;
+}
+
+div.diff.from_file a.path,
+div.diff.from_file {
+ color: #aa0000;
+}
+
+div.diff.rem {
+ color: #cc0000;
+}
+
+div.diff.chunk_header a,
+div.diff.chunk_header {
+ color: #990099;
+}
+
+div.diff.chunk_header {
+ border: dotted #ffe0ff;
+ border-width: 1px 0px 0px 0px;
+ margin-top: 2px;
+}
+
+div.diff.chunk_header span.chunk_info {
+ background-color: #ffeeff;
+}
+
+div.diff.chunk_header span.section {
+ color: #aa22aa;
+}
+
+div.diff.incomplete {
+ color: #cccccc;
+}
+
+div.diff.nodifferences {
+ font-weight: bold;
+ color: #600000;
+}
+
+div.index_include {
+ border: solid #d9d8d1;
+ border-width: 0px 0px 1px;
+ padding: 12px 8px;
+}
+
+div.search {
+ font-size: 100%;
+ font-weight: normal;
+ margin: 4px 8px;
+ float: right;
+ top: 56px;
+ right: 12px
+}
+
+p.projsearch {
+ text-align: center;
+}
+
+td.linenr {
+ text-align: right;
+}
+
+a.linenr {
+ color: #999999;
+ text-decoration: none
+}
+
+a.rss_logo {
+ float: right;
+ padding: 3px 0px;
+ width: 35px;
+ line-height: 10px;
+ border: 1px solid;
+ border-color: #fcc7a5 #7d3302 #3e1a01 #ff954e;
+ color: #ffffff;
+ background-color: #ff6600;
+ font-weight: bold;
+ font-family: sans-serif;
+ font-size: 70%;
+ text-align: center;
+ text-decoration: none;
+}
+a.rss_logo2 {
+ float: right;
+ padding: 3px 0px;
+ width: 60px;
+ line-height: 10px;
+ border: 1px solid;
+ border-color: #fcc7a5 #7d3302 #3e1a01 #ff954e;
+ color: #ffffff;
+ background-color: #ff6600;
+ font-weight: bold;
+ font-family: sans-serif;
+ font-size: 70%;
+ text-align: center;
+ text-decoration: none;
+}
+
+a.rss_logo:hover {
+ background-color: #ee5500;
+}
+
+a.rss_logo.generic {
+ background-color: #ff8800;
+}
+
+a.rss_logo.generic:hover {
+ background-color: #ee7700;
+}
+
+span.refs span {
+ padding: 0px 4px;
+ font-size: 70%;
+ font-weight: normal;
+ border: 1px solid;
+ background-color: #ffaaff;
+ border-color: #ffccff #ff00ee #ff00ee #ffccff;
+}
+
+span.refs span a {
+ text-decoration: none;
+ color: inherit;
+}
+
+span.refs span a:hover {
+ text-decoration: underline;
+}
+
+span.refs span.indirect {
+ font-style: italic;
+}
+
+span.refs span.ref {
+ background-color: #aaaaff;
+ border-color: #ccccff #0033cc #0033cc #ccccff;
+}
+
+span.refs span.tag {
+ background-color: #ffffaa;
+ border-color: #ffffcc #ffee00 #ffee00 #ffffcc;
+}
+
+span.refs span.head {
+ background-color: #aaffaa;
+ border-color: #ccffcc #00cc33 #00cc33 #ccffcc;
+}
+
+span.atnight {
+ color: #cc0000;
+}
+
+span.match {
+ color: #e00000;
+}
+
+div.binary {
+ font-style: italic;
+}
+
+/* Style definition generated by highlight 2.4.5, http://www.andre-simon.de/ */
+
+/* Highlighting theme definition: */
+
+.num { color:#2928ff; }
+.esc { color:#ff00ff; }
+.str { color:#ff0000; }
+.dstr { color:#818100; }
+.slc { color:#838183; font-style:italic; }
+.com { color:#838183; font-style:italic; }
+.dir { color:#008200; }
+.sym { color:#000000; }
+.line { color:#555555; }
+.kwa { color:#000000; font-weight:bold; }
+.kwb { color:#830000; }
+.kwc { color:#000000; font-weight:bold; }
+.kwd { color:#010181; }
use Fcntl ':mode';
use File::Find qw();
use File::Basename qw(basename);
+use LWP::Simple;
binmode STDOUT, ':utf8';
our $t0;
"opml" => \&git_opml,
"project_list" => \&git_project_list,
"project_index" => \&git_project_index,
+ "project_index2" => \&git_project_index2,
+ "download" => \&git_download,
+ "downloads" => \&git_downloads,
+ "bugtracker" => \&git_project_bugtracker,
);
# finally, we have the hash of allowed extra_options for the commands that
if (!defined($actions{$action})) {
die_error(400, "Unknown action");
}
- if ($action !~ m/^(?:opml|project_list|project_index)$/ &&
+ if ($action !~ m/^(?:opml|project_list|project_index2|project_index|downloads)$/ &&
!$project) {
die_error(400, "Project needed");
}
'refs/heads') or return;
my $most_recent = <$fd>;
close $fd or return;
- if (defined $most_recent &&
- $most_recent =~ / (\d+) [-+][01]\d\d\d$/) {
+ if (defined $most_recent && $most_recent =~ / (\d+) [-+][01]\d\d\d$/) {
my $timestamp = $1;
my $age = time - $timestamp;
return ($age, age_string($age));
sub git_footer_html {
my $feed_class = 'rss_logo';
+ my $feed_class2 = 'rss_logo2';
print "<div class=\"page_footer\">\n";
if (defined $project) {
}
} else {
+ print "<div class=\"page_footer_text\">Copyright © 2012, <a href=\"http://nexus-irc.de\">Nexus-IRC.de</a></div>\n";
print $cgi->a({-href => href(project=>undef, action=>"opml"),
-class => $feed_class}, "OPML") . " ";
print $cgi->a({-href => href(project=>undef, action=>"project_index"),
- -class => $feed_class}, "TXT") . "\n";
+ -class => $feed_class}, "TXT") . " ";
+ print $cgi->a({-href => href(project=>undef, action=>"downloads"),
+ -class => $feed_class2}, "Downloads") . "\n";
}
print "</div>\n"; # class="page_footer"
my ($current, $suppress, $head, $treehead, $treebase, $extra) = @_;
$extra = '' if !defined $extra; # pager or formats
- my @navs = qw(summary shortlog log commit commitdiff tree);
+ my @navs = qw(summary bugtracker shortlog log commit commitdiff tree download);
if ($suppress) {
@navs = grep { $_ ne $suppress } @navs;
}
my $cloud = git_populate_project_tagcloud(\%ctags);
print git_show_project_tagcloud($cloud, 64);
}
-
print "<table class=\"project_list\">\n";
unless ($no_header) {
print "<tr>\n";
(defined $pr->{'age_string'} ? $pr->{'age_string'} : "No commits") . "</td>\n" .
"<td class=\"link\">" .
$cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary")}, "summary") . " | " .
+ #$cgi->a({-href => href(project=>$pr->{'path'}, action=>"bugtrack")}, "bugtrack") . " | " .
$cgi->a({-href => href(project=>$pr->{'path'}, action=>"shortlog")}, "shortlog") . " | " .
$cgi->a({-href => href(project=>$pr->{'path'}, action=>"log")}, "log") . " | " .
- $cgi->a({-href => href(project=>$pr->{'path'}, action=>"tree")}, "tree") .
+ $cgi->a({-href => href(project=>$pr->{'path'}, action=>"tree")}, "tree") . " | " .
+ $cgi->a({-href => href(project=>$pr->{'path'}, action=>"download")}, "download") .
($pr->{'forks'} ? " | " . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"forks")}, "forks") : '') .
"</td>\n" .
"</tr>\n";
$from = 0 unless defined $from;
$to = $#{$commitlist} if (!defined $to || $#{$commitlist} < $to);
- print "<table class=\"shortlog\">\n";
+ print "<table class=\"shortlog\" cellspacing=\"0\" cellpadding=\"0\">\n";
my $alternate = 1;
+ my $graph_rand = int(rand(99999));
for (my $i = $from; $i <= $to; $i++) {
my %co = %{$commitlist->[$i]};
my $commit = $co{'id'};
+
+ my $head = git_get_head_hash($project);
+ if (!defined $hash) {
+ $hash = $head;
+ }
+ if (!defined $page) {
+ $page = 0;
+ }
+
my $ref = format_ref_marker($refs, $commit);
if ($alternate) {
print "<tr class=\"dark\">\n";
}
$alternate ^= 1;
# git_summary() used print "<td><i>$co{'age_string'}</i></td>\n" .
- print "<td title=\"$co{'age_string_age'}\"><i>$co{'age_string_date'}</i></td>\n" .
+ print "<td><img class=\"graph\" src=\"git_graph.php?r=".$graph_rand.";p=".$project.";h=".$hash.";from=".($from + (100 * $page)).";to=".($to + (100 * $page)).";c=".$commit."\" /></td>";
+ print "<td class=\"". age_class($co{'age'}) . "\" title=\"$co{'age_string_age'}\"><i>$co{'age_string_date'}</i></td>\n" .
format_author_html('td', \%co, 10) . "<td>";
print format_subject_html($co{'title'}, $co{'title_short'},
href(action=>"commit", hash=>$commit), $ref);
print "<tr class=\"light\">\n";
}
$alternate ^= 1;
- print "<td title=\"$co{'age_string_age'}\"><i>$co{'age_string_date'}</i></td>\n" .
+ print "<td class=\"". age_class($co{'age'}) . "\" title=\"$co{'age_string_age'}\"><i>$co{'age_string_date'}</i></td>\n" .
# shortlog: format_author_html('td', \%co, 10)
format_author_html('td', \%co, 15, 3) . "<td>";
# originally git_history used chop_str($co{'title'}, 50)
print "$path $owner\n";
}
}
+sub git_project_index2 {
+ my @projects = git_get_projects_list($project);
-sub git_summary {
+ print $cgi->header(
+ -type => 'text/plain',
+ -charset => 'utf-8',
+ -content_disposition => 'inline; filename="index.aux"');
+
+ foreach my $pr (@projects) {
+ if (!exists $pr->{'owner'}) {
+ $pr->{'owner'} = git_get_project_owner("$pr->{'path'}");
+ }
+
+ my ($path, $owner) = ($pr->{'path'}, $pr->{'owner'});
+ # quote as in CGI::Util::encode, but keep the slash, and use '+' for ' '
+ $path =~ s/([^a-zA-Z0-9_.\-\/ ])/sprintf("%%%02X", ord($1))/eg;
+ $owner =~ s/([^a-zA-Z0-9_.\-\/ ])/sprintf("%%%02X", ord($1))/eg;
+ $path =~ s/ /\+/g;
+ $owner =~ s/ /\+/g;
+
+ print "$path\n";
+ }
+}
+sub git_downloads {
+ my $dl = get("http://git.nexus-irc.de/git_download.php");
+ git_header_html();
+ print "<div class=\"title\">Downloads</div>\n";
+ print $dl;
+ git_footer_html();
+}
+
+sub git_download {
+ my $dl1 = get("http://git.nexus-irc.de/git_download.php?p=".$project);
+ my %co = parse_commit("HEAD");
+ my $head = $co{'id'};
+ git_header_html();
+ git_print_page_nav('download','', $head);
+ print "<div class=\"title\">Download</div>\n";
+ print $dl1;
+ git_footer_html();
+}
+
+sub git_project_bugtracker {
my $descr = git_get_project_description($project) || "none";
+ my $bugtrack = get("http://git.nexus-irc.de/git_bugtrack.php?p=".$project);
my %co = parse_commit("HEAD");
my %cd = %co ? parse_date($co{'committer_epoch'}, $co{'committer_tz'}) : ();
my $head = $co{'id'};
+ my $owner = git_get_project_owner($project);
+ my $version = get("http://git.nexus-irc.de/git_version.php?git=".$project);
+ git_header_html();
+ git_print_page_nav('bugtracker','', $head);
+ print "<div class=\"title\"> </div>\n";
+ print "<table class=\"projects_list\">\n" .
+ "<tr id=\"metadata_desc\"><td>description</td><td>" . esc_html($descr) . "</td></tr>\n" .
+ "<tr id=\"metadata_owner\"><td>owner</td><td>" . esc_html($owner) . "</td></tr>\n";
+ if (defined $cd{'rfc2822'}) {
+ print "<tr id=\"metadata_lchange\"><td>last change</td><td>$cd{'rfc2822'}</td></tr>\n";
+ }
+ my $url_tag = "URL";
+ my @url_list = git_get_project_url_list($project);
+ @url_list = map { "$_/$project" } @git_base_url_list unless @url_list;
+ foreach my $git_url (@url_list) {
+ next unless $git_url;
+ print "<tr class=\"metadata_url\"><td>$url_tag</td><td>$git_url</td></tr>\n";
+ $url_tag = "";
+ }
+ print "<tr id=\"metadata_owner\"><td>version</td><td>" . esc_html($version) . "</td></tr>\n";
+ print "</table>\n";
+ git_print_header_div('bugtracker');
+ print $bugtrack;
+ git_footer_html();
+}
+sub git_summary {
+ my $descr = git_get_project_description($project) || "none";
+ my %co = parse_commit("HEAD");
+ my %cd = %co ? parse_date($co{'committer_epoch'}, $co{'committer_tz'}) : ();
+ my $head = $co{'id'};
+
my $owner = git_get_project_owner($project);
-
+
+ my $version = get("http://git.nexus-irc.de/git_version.php?git=".$project);
+
my $refs = git_get_references();
# These get_*_list functions return one more to allow us to see if
# there are more ...
git_header_html();
git_print_page_nav('summary','', $head);
-
print "<div class=\"title\"> </div>\n";
print "<table class=\"projects_list\">\n" .
"<tr id=\"metadata_desc\"><td>description</td><td>" . esc_html($descr) . "</td></tr>\n" .
print "<tr class=\"metadata_url\"><td>$url_tag</td><td>$git_url</td></tr>\n";
$url_tag = "";
}
-
+ print "<tr id=\"metadata_owner\"><td>version</td><td>" . esc_html($version) . "</td></tr>\n";
# Tag cloud
my $show_ctags = gitweb_check_feature('ctags');
if ($show_ctags) {