diff --git a/public_html/libgit/base.php b/public_html/libgit/base.php index 52f974c..d2bc08b 100644 --- a/public_html/libgit/base.php +++ b/public_html/libgit/base.php @@ -23,11 +23,20 @@ function sha1_from_bin($bin) return bin2hex($bin); } +function number_from_bin($bin) +{ + $c = unpack("N", $bin); + return $c[1]; +} + class GitBranchNotFoundException extends Exception {} class GitTagNotFoundException extends Exception {} class GitInvalidOriginException extends Exception {} class GitInvalidElementException extends Exception {} +class GitInvalidFormatException extends Exception {} +class GitUnsupportedVersionException extends Exception {} class GitPathNotFoundException extends Exception {} +class GitCorruptIndexException extends Exception {} require(dirname(__FILE__) . "/class.repository.php"); require(dirname(__FILE__) . "/class.branch.php"); @@ -38,4 +47,6 @@ require(dirname(__FILE__) . "/class.tree.php"); require(dirname(__FILE__) . "/class.tree.element.php"); require(dirname(__FILE__) . "/class.commit.php"); require(dirname(__FILE__) . "/class.actor.php"); +require(dirname(__FILE__) . "/class.pack.php"); +require(dirname(__FILE__) . "/class.pack.index.php"); ?> diff --git a/public_html/libgit/class.pack.index.php b/public_html/libgit/class.pack.index.php new file mode 100644 index 0000000..c5a0bd1 --- /dev/null +++ b/public_html/libgit/class.pack.index.php @@ -0,0 +1,74 @@ +rawdata = $data; + + if(substr($data, 0, 4) == PACK_IDX_SIGNATURE) + { + $version = number_from_bin(substr($data, 4, 4)); + + if($version == 2) + { + $this->version = $version; + $offset = 8; + + $indexes = unpack("N*", substr($data, $offset, 256*4)); + $highest = 0; + + for($i = 0; $i < 256; $i++) + { + if(!isset($indexes[$i + 1])) + { + continue; + } + + $n = $indexes[$i + 1]; + + if($n < $highest) + { + throw new GitCorruptIndexException("The pack index file is corrupt."); + } + + $highest = $n; + } + + $offset = $offset + (256 * 4); + + $keys = array(); + $values = array(); + + for($i = 0; $i < $highest; $i++) + { + $keys[] = sha1_from_bin(substr($data, $offset, 20)); + $offset += 20; + } + + $offset += ($highest * 4); + + for($i = 0; $i < $highest; $i++) + { + $values[] = number_from_bin(substr($data, $offset, 4)); + $offset += 4; + } + + $this->index = array_combine($keys, $values); + } + else + { + throw new GitUnsupportedVersionException("Version {$version} pack indexes are not supported by this version of the library."); + } + } + else + { + throw new GitInvalidFormatException("The provided data does not look like a pack index file."); + } + } +} diff --git a/public_html/libgit/class.pack.php b/public_html/libgit/class.pack.php new file mode 100644 index 0000000..f66ce52 --- /dev/null +++ b/public_html/libgit/class.pack.php @@ -0,0 +1,16 @@ +repo = $repo; + + $index_filename = "{$repo->path}/objects/pack/{$name}.idx"; + $pack_filename = "{$repo->path}/objects/pack/{$name}.pack"; + + $this->index = new GitPackIndex(file_get_contents($index_filename)); + } +} diff --git a/public_html/test.php b/public_html/test.php index 7def26f..cd324cf 100644 --- a/public_html/test.php +++ b/public_html/test.php @@ -2,4 +2,5 @@ require("libgit/base.php"); $repo = new GitRepository("/home/occupy/testrepo.git"); -pretty_dump($repo->GetObjectForPath($repo->GetBranch("master")->GetTree(), "public_html/css/images/derp")); +pretty_dump(new GitPack($repo, "pack-8503a2b8cf6e60831dd012afd4d486eb1eddfef8")); +//pretty_dump($repo->GetObjectForPath($repo->GetBranch("master")->GetTree(), "public_html/css/images/derp"));