Exemple #1
0
 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);
}
Exemple #3
0
 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;
}
Exemple #7
0
 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);
}
Exemple #11
0
 /**
  * @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));
 }
Exemple #12
0
 $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) {
Exemple #13
0
 /**
  * @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;
 }