public function _unserialize($data) { $lines = explode("\n", $data); unset($data); $meta = array(); while (($line = array_shift($lines)) != '') { $parts = explode(' ', $line, 2); if (!isset($meta[$parts[0]])) { $meta[$parts[0]] = array($parts[1]); } else { $meta[$parts[0]][] = $parts[1]; } } if (isset($meta['object'][0])) { $this->object = sha1_bin($meta['object'][0]); $this->objtype = Git::getTypeID($meta['type'][0]); } if (isset($meta['tag'][0])) { $this->tag = $meta['tag'][0]; } if (isset($meta['tagger'][0])) { $this->tagger = new GitCommitStamp(); $this->tagger->unserialize($meta['tagger'][0]); } $this->summary = array_shift($lines); $this->detail = implode("\n", $lines); }
function git_commitdiff($projectroot, $project, $hash, $hash_parent) { global $tpl; $cachekey = sha1($project) . "|" . $hash . "|" . $hash_parent; $git = new Git($projectroot . $project); $hash = sha1_bin($hash); if (isset($hash_parent)) { $hash_parent = sha1_bin($hash_parent); } if (!$tpl->is_cached('commitdiff.tpl', $cachekey)) { $co = git_read_commit($git, $hash); $ad = date_str($co['author_epoch']); $tpl->assign('committer', $co['committer']); $tpl->assign('rfc2822', $ad['rfc2822']); if (!isset($hash_parent) && isset($co['parent'])) { $hash_parent = sha1_bin($co['parent']); } $a_tree = isset($hash_parent) ? $git->getObject($hash_parent)->getTree() : array(); $b_tree = $git->getObject(sha1_bin($co['tree'])); $difftree = GitTree::diffTree($a_tree, $b_tree); $tpl->assign("hash", sha1_hex($hash)); $tpl->assign("tree", $co['tree']); $tpl->assign("hashparent", sha1_hex($hash_parent)); $tpl->assign("title", $co['title']); $refs = read_info_ref($git); if (isset($refs[$hash])) { $tpl->assign("commitref", $refs[$hash]); } $tpl->assign("comment", $co['comment']); $difftreelines = array(); $status_map = array(GitTree::TREEDIFF_ADDED => "A", GitTree::TREEDIFF_REMOVED => "D", GitTree::TREEDIFF_CHANGED => "M"); foreach ($difftree as $file => $diff) { $difftreeline = array(); $difftreeline["from_mode"] = decoct($diff->old_mode); $difftreeline["to_mode"] = decoct($diff->new_mode); $difftreeline["from_id"] = sha1_hex($diff->old_obj); $difftreeline["to_id"] = sha1_hex($diff->new_obj); $difftreeline["status"] = $status_map[$diff->status]; $difftreeline["file"] = $file; $difftreeline["md5"] = md5($file); $difftreeline["from_type"] = file_type($difftreeline["from_mode"]); $difftreeline["to_type"] = file_type($difftreeline["to_mode"]); if ($diff->status == GitTree::TREEDIFF_ADDED) { $difftreeline['diffout'] = explode("\n", git_diff($git, null, "/dev/null", $diff->new_obj, "b/" . $file)); } else { if ($diff->status == GitTree::TREEDIFF_REMOVED) { $difftreeline['diffout'] = explode("\n", git_diff($git, $diff->old_obj, "a/" . $file, null, "/dev/null")); } else { if ($diff->status == GitTree::TREEDIFF_CHANGED && $diff->old_obj != $diff->new_obj) { $difftreeline['diffout'] = explode("\n", git_diff($git, $diff->old_obj, "a/" . $file, $diff->new_obj, "b/" . $file)); } } } $difftreelines[] = $difftreeline; } $tpl->assign("difftreelines", $difftreelines); } $tpl->display('commitdiff.tpl', $cachekey); }
public function action_view($hash = NULL) { $commit = $this->repo->getObject(sha1_bin($hash)); require Kohana::find_file('vendor', 'htmlpurifier/library/htmlpurifier.auto'); require Kohana::find_file('vendor', 'markdown/markdown'); $this->template->title = html::chars($commit->summary); $this->template->content = View::factory('changelog/view')->set('commit', $commit)->set('htmlpurifier', new HTMLPurifier()); }
function git_commitdiff_plain($projectroot, $project, $hash, $hash_parent) { global $tpl; $cachekey = sha1($project) . "|" . $hash . "|" . $hash_parent; header("Content-type: text/plain; charset=UTF-8"); header("Content-disposition: inline; filename=\"git-" . $hash . ".patch\""); $git = new Git($projectroot . $project); $hash = sha1_bin($hash); if (isset($hash_parent)) { $hash_parent = sha1_bin($hash_parent); } if (!$tpl->is_cached('diff_plaintext.tpl', $cachekey)) { $co = git_read_commit($git, $hash); if (!isset($hash_parent) && isset($co['parent'])) { $hash_parent = sha1_bin($co['parent']); } $a_tree = isset($hash_parent) ? $git->getObject($hash_parent)->getTree() : array(); $b_tree = $git->getObject(sha1_bin($co['tree'])); $difftree = GitTree::diffTree($a_tree, $b_tree); // FIXME: simplified tagname search is not implemented yet /*$refs = read_info_ref($git,"tags"); $listout = git_read_revlist($git, "HEAD"); foreach ($listout as $i => $rev) { if (isset($refs[$rev])) $tagname = $refs[$rev]; if ($rev == $hash) break; }*/ $ad = date_str($co['author_epoch'], $co['author_tz']); $tpl->assign("from", $co['author']); $tpl->assign("date", $ad['rfc2822']); $tpl->assign("subject", $co['title']); if (isset($tagname)) { $tpl->assign("tagname", $tagname); } $tpl->assign("url", script_url() . "?p=" . $project . "&a=commitdiff&h=" . sha1_hex($hash)); $tpl->assign("comment", $co['comment']); $diffs = array(); foreach ($difftree as $file => $diff) { if ($diff->status == GitTree::TREEDIFF_ADDED) { $diffs[] = git_diff($git, null, "/dev/null", $diff->new_obj, "b/" . $file); } else { if ($diff->status == GitTree::TREEDIFF_REMOVED) { $diffs[] = git_diff($git, $diff->old_obj, "a/" . $file, null, "/dev/null"); } else { if ($diff->status == GitTree::TREEDIFF_CHANGED) { $diffs[] = git_diff($git, $diff->old_obj, "a/" . $file, $diff->new_obj, "b/" . $file); } } } } $tpl->assign("diffs", $diffs); } $tpl->display('diff_plaintext.tpl', $cachekey); }
function git_blobdiff_plain($projectroot, $project, $hash, $hashparent, $file) { global $tpl; header("Content-type: text/plain; charset=UTF-8"); $cachekey = sha1($project) . "|" . $hash . "|" . $hashparent . "|" . sha1($file); $git = new Git($projectroot . $project); if (!$tpl->is_cached('blobdiffplain.tpl', $cachekey)) { $ret = prep_tmpdir(); if ($ret !== TRUE) { echo $ret; return; } $tpl->assign("blobdiff", git_diff($git, sha1_bin($hashparent), $file ? "a/" . $file : $hashparent, sha1_bin($hash), $file ? "b/" . $file : $hash)); } $tpl->display('blobdiffplain.tpl', $cachekey); }
function git_read_ref($project, $ref_id, $ref_file) { $hash = $project->revParse(trim($ref_id)); $type = git_get_type($project, $hash); if (!$type) { return null; } $ref_item = array(); $ref_item['type'] = $type; $ref_item['id'] = $ref_id; $ref_item['epoch'] = 0; $ref_item['age_string'] = "unknown"; if ($type == "tag") { $tag = git_read_tag($project, $hash); $ref_item['comment'] = $tag['comment']; if ($tag['type'] == "commit") { $co = git_read_commit($project, sha1_bin($tag['object'])); $ref_item['epoch'] = $co['committer_epoch']; $ref_item['age_string'] = $co['age_string']; $ref_item['age'] = $co['age']; } else { if (isset($tag['epoch'])) { $age = time() - $tag['epoch']; $ref_item['epoch'] = $tag['epoch']; $ref_item['age_string'] = age_string($age); $ref_item['age'] = $age; } } $ref_item['reftype'] = $tag['type']; $ref_item['name'] = $tag['name']; $ref_item['refid'] = $tag['object']; } else { if ($type == "commit") { $co = git_read_commit($project, $hash); $ref_item['reftype'] = "commit"; $ref_item['name'] = $ref_file; $ref_item['title'] = $co['title']; $ref_item['refid'] = $ref_id; $ref_item['epoch'] = $co['committer_epoch']; $ref_item['age_string'] = $co['age_string']; $ref_item['age'] = $co['age']; } } return $ref_item; }
public function _unserialize($data) { $lines = explode("\n", $data); unset($data); $meta = array('parent' => array()); while (($line = array_shift($lines)) != '') { $parts = explode(' ', $line, 2); if (!isset($meta[$parts[0]])) { $meta[$parts[0]] = array($parts[1]); } else { $meta[$parts[0]][] = $parts[1]; } } $this->tree = sha1_bin($meta['tree'][0]); $this->parents = array_map('sha1_bin', $meta['parent']); $this->author = new GitCommitStamp(); $this->author->unserialize($meta['author'][0]); $this->committer = new GitCommitStamp(); $this->committer->unserialize($meta['committer'][0]); $this->summary = array_shift($lines); $this->detail = implode("\n", $lines); $this->history = NULL; }
function git_blobdiff($projectroot, $project, $hash, $hashbase, $hashparent, $file) { global $tpl; $cachekey = sha1($project) . "|" . $hashbase . "|" . $hash . "|" . $hashparent . "|" . sha1($file); $git = new Git($projectroot . $project); if (!$tpl->is_cached('blobdiff.tpl', $cachekey)) { $ret = prep_tmpdir(); if ($ret !== TRUE) { echo $ret; return; } $tpl->assign("hash", $hash); $tpl->assign("hashparent", $hashparent); $tpl->assign("hashbase", $hashbase); if (isset($file)) { $tpl->assign("file", $file); } $hash = sha1_bin($hash); $hashbase = sha1_bin($hashbase); $hashparent = sha1_bin($hashparent); if ($co = git_read_commit($git, $hashbase)) { $tpl->assign("fullnav", TRUE); $tpl->assign("tree", sha1_hex($co['tree'])); $tpl->assign("title", $co['title']); $refs = read_info_ref($git); if (isset($refs[$hashbase])) { $tpl->assign("hashbaseref", $refs[$hashbase]); } } $paths = git_path_trees($git, $git->getObject($hashbase), $file); $tpl->assign("paths", $paths); $diffout = explode("\n", git_diff($git, $hashparent, $file ? $file : $hashparent, $hash, $file ? $file : $hash)); $tpl->assign("diff", $diffout); } $tpl->display('blobdiff.tpl', $cachekey); }
function git_commit($projectroot, $project, $hash) { global $tpl; $cachekey = sha1($project) . "|" . $hash; $git = new Git($projectroot . $project); $hash = $git->revParse($hash); if (!$tpl->is_cached('commit.tpl', $cachekey)) { $co = git_read_commit($git, $hash); $ad = date_str($co['author_epoch'], $co['author_tz']); $cd = date_str($co['committer_epoch'], $co['committer_tz']); if (isset($co['parent'])) { $a_tree = $git->getObject(sha1_bin($co['parent']))->getTree(); } else { $a_tree = false; } $b_tree = $git->getObject(sha1_bin($co['tree'])); $difftree = GitTree::diffTree($a_tree, $b_tree); ksort($difftree); $tpl->assign("hash", sha1_hex($hash)); $tpl->assign("tree", $co['tree']); if (isset($co['parent'])) { $tpl->assign("parent", $co['parent']); } $tpl->assign("title", $co['title']); $refs = read_info_ref($git); if (isset($refs[$hash])) { $tpl->assign("commitref", $refs[$hash]); } $tpl->assign("author", $co['author']); $tpl->assign("adrfc2822", $ad['rfc2822']); $tpl->assign("adhourlocal", $ad['hour_local']); $tpl->assign("adminutelocal", $ad['minute_local']); $tpl->assign("adtzlocal", $ad['tz_local']); $tpl->assign("committer", $co['committer']); $tpl->assign("cdrfc2822", $cd['rfc2822']); $tpl->assign("cdhourlocal", $cd['hour_local']); $tpl->assign("cdminutelocal", $cd['minute_local']); $tpl->assign("cdtzlocal", $cd['tz_local']); $tpl->assign("id", $co['id']); $tpl->assign("parents", $co['parents']); $tpl->assign("comment", $co['comment']); $tpl->assign("difftreesize", count($difftree) + 1); $status_map = array(GitTree::TREEDIFF_ADDED => "A", GitTree::TREEDIFF_REMOVED => "D", GitTree::TREEDIFF_CHANGED => "M"); $difftreelines = array(); foreach ($difftree as $file => $diff) { $difftreeline = array(); $difftreeline["from_mode"] = decoct($diff->old_mode); $difftreeline["to_mode"] = decoct($diff->new_mode); $difftreeline["from_mode_cut"] = substr(decoct($diff->old_mode), -4); $difftreeline["to_mode_cut"] = substr(decoct($diff->new_mode), -4); $difftreeline["from_id"] = sha1_hex($diff->old_obj); $difftreeline["to_id"] = sha1_hex($diff->new_obj); $difftreeline["status"] = $status_map[$diff->status]; $difftreeline["similarity"] = ""; $difftreeline["file"] = $file; $difftreeline["from_file"] = ""; $difftreeline["from_filetype"] = ""; $difftreeline["to_file"] = ""; $difftreeline["to_filetype"] = ""; $difftreeline["isreg"] = TRUE; $modestr = ""; /*if ((octdec($regs[1]) & 0x17000) != (octdec($regs[2]) & 0x17000)) $modestr .= " from " . file_type($regs[1]) . " to " . file_type($regs[2]); if ((octdec($regs[1]) & 0777) != (octdec($regs[2]) & 0777)) { if ((octdec($regs[1]) & 0x8000) && (octdec($regs[2]) & 0x8000)) $modestr .= " mode: " . (octdec($regs[1]) & 0777) . "->" . (octdec($regs[2]) & 0777); else if (octdec($regs[2]) & 0x8000) $modestr .= " mode: " . (octdec($regs[2]) & 0777);*/ $difftreeline["modechange"] = $modestr; $simmodechg = ""; /*if ($regs[1] != $regs[2]) $simmodechg .= ", mode: " . (octdec($regs[2]) & 0777);*/ $difftreeline["simmodechg"] = $simmodechg; $difftreelines[] = $difftreeline; } $tpl->assign("difftreelines", $difftreelines); } $tpl->display('commit.tpl', $cachekey); }
function git_tree($projectroot, $project, $hash, $file, $hashbase) { global $tpl; $cachekey = sha1($project) . "|" . $hashbase . "|" . $hash . "|" . sha1($file); $git = new Git($projectroot . $project); if (isset($hash)) { $hash = sha1_bin($hash); } if (isset($hashbase)) { $hashbase = sha1_bin($hashbase); } if (!$tpl->is_cached('tree.tpl', $cachekey)) { if (!isset($hash)) { $hash = git_read_head($git); if (!isset($hashbase)) { $hashbase = $hash; } if (isset($file)) { $hash = git_get_hash_by_path($git, $git->getObject($hashbase ? $hashbase : $hash), $file, "tree"); } } $refs = read_info_ref($git); $tpl->assign("hash", sha1_hex($hash)); if (isset($hashbase)) { $tpl->assign("hashbase", sha1_hex($hashbase)); } if (isset($hashbase) && ($co = git_read_commit($git, $hashbase))) { $basekey = $hashbase; $tpl->assign("fullnav", TRUE); $tpl->assign("title", $co['title']); if (isset($refs[$hashbase])) { $tpl->assign("hashbaseref", $refs[$hashbase]); } } if (isset($hashbase)) { $objbase = $git->getObject($hashbase); if ($objbase->getType() == Git::OBJ_COMMIT) { $objbase = $objbase->getTree(); } $paths = git_path_trees($git, $objbase, $file); $tpl->assign("paths", $paths); } if (isset($file)) { $tpl->assign("base", $file . "/"); } $obj = $git->getObject($hash); if ($obj->getType() == Git::OBJ_COMMIT) { $obj = $obj->getTree(); } $treelines = array(); foreach ($obj->nodes as $node) { $treeline = array(); $treeline["filemode"] = mode_str(decoct($node->mode)); $treeline["type"] = $node->is_dir ? "tree" : "blob"; $treeline["hash"] = sha1_hex($node->object); $treeline["name"] = $node->name; $treelines[] = $treeline; $tok = strtok(""); } $tpl->assign("treelines", $treelines); } $tpl->display('tree.tpl', $cachekey); }
/** * @brief Look up a branch. * * @param $branch (string) The branch to look up, defaulting to @em master. * @returns (string) The tip of the branch (binary sha1). */ public function getTip($branch = 'master') { $subpath = sprintf('refs/heads/%s', $branch); $path = sprintf('%s/%s', $this->dir, $subpath); if (file_exists($path)) { return sha1_bin(file_get_contents($path)); } $path = sprintf('%s/packed-refs', $this->dir); if (file_exists($path)) { $head = NULL; $f = fopen($path, 'rb'); flock($f, LOCK_SH); while ($head === NULL && ($line = fgets($f)) !== FALSE) { if ($line[0] == '#') { continue; } $parts = explode(' ', trim($line)); if (count($parts) == 2 && $parts[1] == $subpath) { $head = sha1_bin($parts[0]); } } fclose($f); if ($head !== NULL) { return $head; } } throw new Exception(sprintf('no such branch: %s', $branch)); }
$pending = array(); $blob = new GitBlob($repo); $pending[] = $blob; $blob->data = $content; $blob->rehash(); $f = fopen(sprintf('%s/refs/heads/%s', $repo->dir, Config::GIT_BRANCH), 'a+b'); flock($f, LOCK_EX); $ref = stream_get_contents($f); $fast_forward = FALSE; $fast_merge = FALSE; $commit_base = $commit; if (strlen($ref) == 0) { /* create branch from scratch */ $fast_forward = TRUE; } else { $ref = sha1_bin($ref); if ($ref == $commit->getName()) { /* no new commits */ $fast_forward = TRUE; } else { $tip = $repo->getObject($ref); try { if ($tip->find($page->path) == $commit->find($page->path)) { /* * New commits have been made, but the concerned file * has the same contents as when we started editing. We * directly perform the trivial merge. */ $fast_merge = TRUE; } } catch (GitTreeError $e) {
/** * @brief reads a single ref from a file * @param $ref (string) reference to be loaded * @returns (integer) * 0 if reference is bad * 1 if reference sha1 is loaded * 2 if reference is need to be resolved */ protected function read_ref($ref) { // safety: refuse to resolve reference that points to parent directory if (substr($ref, 3) == '../' || strpos($ref, '/../')) { $this->brefs[$ref] = true; return 0; } $data = trim(@file_get_contents(sprintf("%s/%s", $this->dir, $ref))); if (substr($data, 0, 4) == "ref:") { $this->srefs[$ref] = trim(substr($data, 4)); return 2; } if (is_valid_sha1($data)) { $this->refs[$ref] = sha1_bin($data); return 1; } $this->brefs[$ref] = true; //mark reference as bad return 0; }