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);
}
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);
}
Esempio n. 3
0
function git_rss($projectroot, $project)
{
    global $tpl;
    header("Content-type: text/xml; charset=UTF-8");
    $cachekey = sha1($project);
    $git = new Git($projectroot . $project);
    if (!$tpl->is_cached('rss.tpl', $cachekey)) {
        $head = git_read_head($git);
        $revlist = git_read_revlist($git, $head, GITPHP_RSS_ITEMS);
        $tpl->assign("self", script_url());
        $commitlines = array();
        $revlistcount = count($revlist);
        for ($i = 0; $i < $revlistcount; ++$i) {
            $commit = $revlist[$i];
            $co = git_read_commit($git, $commit->getName());
            if ($i >= 20 && time() - $co['committer_epoch'] > 48 * 60 * 60) {
                break;
            }
            $cd = date_str($co['committer_epoch']);
            $difftree = array();
            $diffout = GitTree::diffTree(isset($commit->parent[0]) ? $commit->parent[0]->getTree() : null, $commit->getTree());
            foreach ($diffout as $file => $diff) {
                $difftree[] = $file;
            }
            $commitline = array();
            $commitline["cdmday"] = $cd['mday'];
            $commitline["cdmonth"] = $cd['month'];
            $commitline["cdhour"] = $cd['hour'];
            $commitline["cdminute"] = $cd['minute'];
            $commitline["title"] = $co['title'];
            $commitline["author"] = $co['author'];
            $commitline["cdrfc2822"] = $cd['rfc2822'];
            $commitline["commit"] = $commit;
            $commitline["comment"] = $co['comment'];
            $commitline["difftree"] = $difftree;
            $commitlines[] = $commitline;
        }
        $tpl->assign("commitlines", $commitlines);
    }
    $tpl->display('rss.tpl', $cachekey);
}
Esempio n. 4
0
 /**
  * Sets the path to object (implements the ArrayAccess interface).
  *
  * @param string $path
  * @param string $object
  *
  */
 public function offsetSet($path, $object)
 {
     $path = new GitPath($path);
     if (!$object instanceof GitBlob) {
         throw new Exception('Object should be a GitBlob');
     }
     if ($this->isReadOnly()) {
         throw new Exception('Can not write to locked object');
     }
     if ($path->isRoot()) {
         throw new Exception('Can not set self to another object');
     }
     if ($path->isSingle()) {
         $beSureDataIsLoaded = $this->nodes;
         $this->data['nodes'][$path[0]] = $object;
     } else {
         if (isset($this->nodes[$path[0]])) {
             $sub = $this->nodes[$path[0]];
             if ($sub->isReadOnly()) {
                 // clone the loaded object, to make it a new one
                 $sub = clone $sub;
             }
         } else {
             $sub = new GitTree($this->git);
         }
         if (!$sub instanceof GitTree) {
             throw new Exception('Invalid path to set');
         }
         $this->data['nodes'][$path[0]] = $sub;
         $sub->offsetSet($path->getShifted(), $object);
     }
 }
Esempio n. 5
0
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);
}
Esempio n. 6
0
 /**
  * @brief Updates a node in this tree.
  *
  * Missing directories in the path will be created automatically.
  *
  * @param $path (string) Path to the node, relative to this tree.
  * @param $mode Git mode to set the node to. 0 if the node shall be
  * cleared, i.e. the tree or blob shall be removed from this path.
  * @param $object (string) Binary SHA-1 hash of the object that shall be
  * placed at the given path.
  *
  * @returns (array of GitObject) An array of GitObject%s that were newly
  * created while updating the specified node. Those need to be written to
  * the repository together with the modified tree.
  */
 public function updateNode($path, $mode, $object)
 {
     if (!is_array($path)) {
         $path = explode('/', $path);
     }
     $name = array_shift($path);
     if (count($path) == 0) {
         /* create leaf node */
         if ($mode) {
             $node = new stdClass();
             $node->mode = $mode;
             $node->name = $name;
             $node->object = $object;
             $node->is_dir = !!($mode & 040000);
             $this->nodes[$node->name] = $node;
         } else {
             unset($this->nodes[$name]);
         }
         return array();
     } else {
         /* descend one level */
         if (isset($this->nodes[$name])) {
             $node = $this->nodes[$name];
             if (!$node->is_dir) {
                 throw new GitTreeInvalidPathError();
             }
             $subtree = clone $this->repo->getObject($node->object);
         } else {
             /* create new tree */
             $subtree = new GitTree($this->repo);
             $node = new stdClass();
             $node->mode = 040000;
             $node->name = $name;
             $node->is_dir = TRUE;
             $this->nodes[$node->name] = $node;
         }
         $pending = $subtree->updateNode($path, $mode, $object);
         $subtree->rehash();
         $node->object = $subtree->getName();
         $pending[] = $subtree;
         return $pending;
     }
 }
Esempio n. 7
0
 public static function treeDiff($a, $b)
 {
     return GitTree::treeDiff($a ? $a->getTree() : NULL, $b ? $b->getTree() : NULL);
 }
Esempio n. 8
0
 /**
  * Returns the node associated with the supplied path (implements the ArrayAccess interface).
  *
  * @param  string $index  The path of the object to get
  *
  * @return GitBlob, GitTree
  */
 public function offsetGet($path)
 {
     $path = new GitPath($path);
     $object = array_key_exists((string) $path, $this->stash) ? new GitBlob($this->git, null, null, $this->stash[(string) $path]) : $this->getTip()->offsetGet($path);
     if (is_null($object) || $object instanceof GitTree) {
         //make sure it's a cleaned reference, and that it's referencing a path
         $path = new GitPath($path . '/');
         foreach (array_keys($this->stash) as $key) {
             $file = new GitPath($key);
             if ($file->hasAncestor($path)) {
                 //remove $path part of the stash item
                 $file->splice(0, count($path));
                 if (is_null($object)) {
                     $object = new GitTree($this->git);
                 } elseif ($object->isReadOnly()) {
                     $object = clone $object;
                 }
                 if (is_null($this->stash[$key])) {
                     unset($object[$file]);
                 } else {
                     $object[$file] = new GitBlob($this->git, null, null, $this->stash[$key]);
                 }
             }
         }
     }
     return $object;
 }