$brach_id++, "uid" => $branch_uid++, "active" => true, "sticky" => true, "name" => array($name), "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); $name = explode("/", $head[1]); $name = $name[count($name)-2]; if(!$head[0]) continue; $existing = false; foreach($data['branches'] as &$branch) { if($branch['next'] == $head[0]) { $existing = true; $branch['name'][] = $name; break; } } unset($branch); if($existing) continue; $data['branches'][count($data['branches'])] = array( "id" => $brach_id++, "uid" => $branch_uid++, "active" => true, "sticky" => true, "name" => array($name), "next" => $head[0] ); } } } if($_GET['c'] == "header") { $count = count($data['branches']); if($count > $max_branches) $count = $max_branches; if(!$header_height) { $maxlen = 0; foreach($data['branches'] as $branch) { if($branch['sticky'] && count($branch['name'])) { if(strlen($branch['name'][0]) > $maxlen) $maxlen = strlen($branch['name'][0]); } } $header_height = $maxlen * 2 + 15; } $image = imagecreatetruecolor($count * $size + 60, $header_height); $transparentIndex = imagecolorallocate($image, 217, 216, 209); imagefill($image, 0, 0, $transparentIndex); $branches = 0; foreach($data['branches'] as $branch) { if($branch['sticky'] && count($branch['name'])) { $branches++; $color = get_color($branch['id'], true); $color = imagecolorallocatealpha($image, $color[0], $color[1], $color[2], 0); imagettftext($image, 8, 28, ($branch['id']-1) * $size + 10, $header_height-2, $color, $_SERVER['DOCUMENT_ROOT']."/arial.ttf", $branch['name'][0]); } } if(!$branches) die(); imagecolortransparent($image, $transparentIndex); header('Content-Type: image/png'); imagepng($image); imagedestroy($image); die(); } 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; } } //DEV Breakpoint //print_r($data); //die(); //generate image if($graph_commit == NULL) die("ERROR 0x07"); $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, $text = false) { 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']; } $color_array = $colors[($id - 1) % count($colors)]; if($text && is_array($color_array[0]) && $color_array[1]) return $color_array[1]; return (is_array($color_array[0]) ? $color_array[0] : $color_array); } 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); ?>