Exemplo n.º 1
0
 /**
  * Gets the data for a blob
  *
  * @param GitPHP_Blob $blob blob
  * @return string blob data
  */
 public function Load($blob)
 {
     if (!$blob) {
         return;
     }
     return $this->objectLoader->GetObject($blob->GetHash());
 }
Exemplo n.º 2
0
 /**
  * Gets the data for a tree
  *
  * @param GitPHP_Tree $tree tree
  * @return array array of tree contents
  */
 public function Load($tree)
 {
     if (!$tree) {
         return;
     }
     $contents = array();
     $treePath = $tree->GetPath();
     $treeData = $this->objectLoader->GetObject($tree->GetHash());
     $start = 0;
     $len = strlen($treeData);
     while ($start < $len) {
         $pos = strpos($treeData, "", $start);
         list($mode, $path) = explode(' ', substr($treeData, $start, $pos - $start), 2);
         $mode = str_pad($mode, 6, '0', STR_PAD_LEFT);
         $hash = bin2hex(substr($treeData, $pos + 1, 20));
         $start = $pos + 21;
         $octmode = octdec($mode);
         if ($octmode == 57344) {
             // submodules not currently supported
             continue;
         }
         if (!empty($treePath)) {
             $path = $treePath . '/' . $path;
         }
         $data = array();
         $data['hash'] = $hash;
         if ($octmode & 0x4000) {
             // tree
             $data['type'] = 'tree';
         } else {
             // blob
             $data['type'] = 'blob';
         }
         $data['mode'] = $mode;
         $data['path'] = $path;
         $contents[] = $data;
     }
     return $contents;
 }
Exemplo n.º 3
0
 /**
  * Abbreviate a hash
  *
  * @param GitPHP_Project $project project
  * @param string $hash hash to abbreviate
  * @return string abbreviated hash
  */
 public function AbbreviateHash($project, $hash)
 {
     if (!$project) {
         return $hash;
     }
     if (!preg_match('/[0-9A-Fa-f]{40}/', $hash)) {
         return $hash;
     }
     $abbrevLen = GitPHP_ProjectLoad_Raw::HashAbbreviateLength;
     $projAbbrevLen = $project->GetAbbreviateLength();
     if ($projAbbrevLen > 0) {
         $abbrevLen = max(4, min($projAbbrevLen, 40));
     }
     $prefix = substr($hash, 0, $abbrevLen);
     if (!$project->GetUniqueAbbreviation()) {
         return $prefix;
     }
     return $this->objectLoader->EnsureUniqueHash($hash, $prefix);
 }
Exemplo n.º 4
0
 /**
  * Gets the data for a commit
  *
  * @param GitPHP_Commit $commit commit
  * @return array commit data
  */
 public function Load($commit)
 {
     if (!$commit) {
         return;
     }
     $abbreviatedHash = null;
     $tree = null;
     $parents = array();
     $author = null;
     $authorEpoch = null;
     $authorTimezone = null;
     $committer = null;
     $committerEpoch = null;
     $committerTimezone = null;
     $title = null;
     $comment = array();
     $data = $this->objectLoader->GetObject($commit->GetHash());
     if (empty($data)) {
         return;
     }
     $lines = explode("\n", $data);
     $linecount = count($lines);
     $i = 0;
     $encoding = null;
     /* Commit header */
     for ($i = 0; $i < $linecount; $i++) {
         $line = $lines[$i];
         if (preg_match('/^tree ([0-9a-fA-F]{40})$/', $line, $regs)) {
             /* Tree */
             $tree = $regs[1];
         } else {
             if (preg_match('/^parent ([0-9a-fA-F]{40})$/', $line, $regs)) {
                 /* Parent */
                 $parents[] = $regs[1];
             } else {
                 if (preg_match('/^author (.*) ([0-9]+) (.*)$/', $line, $regs)) {
                     /* author data */
                     $author = $regs[1];
                     $authorEpoch = $regs[2];
                     $authorTimezone = $regs[3];
                 } else {
                     if (preg_match('/^committer (.*) ([0-9]+) (.*)$/', $line, $regs)) {
                         /* committer data */
                         $committer = $regs[1];
                         $committerEpoch = $regs[2];
                         $committerTimezone = $regs[3];
                     } else {
                         if (preg_match('/^encoding (.+)$/', $line, $regs)) {
                             $gitEncoding = trim($regs[1]);
                             if (strlen($gitEncoding) > 0 && function_exists('mb_list_encodings')) {
                                 $supportedEncodings = mb_list_encodings();
                                 $encIdx = array_search(strtolower($gitEncoding), array_map('strtolower', $supportedEncodings));
                                 if ($encIdx !== false) {
                                     $encoding = $supportedEncodings[$encIdx];
                                 }
                             }
                             $encoding = trim($regs[1]);
                         } else {
                             if (strlen($line) == 0) {
                                 break;
                             }
                         }
                     }
                 }
             }
         }
     }
     /* Commit body */
     for ($i += 1; $i < $linecount; $i++) {
         $trimmed = trim($lines[$i]);
         if (strlen($trimmed) > 0 && strlen($encoding) > 0 && function_exists('mb_convert_encoding')) {
             $trimmed = mb_convert_encoding($trimmed, 'UTF-8', $encoding);
         }
         if (empty($title) && strlen($trimmed) > 0) {
             $title = $trimmed;
         }
         if (!empty($title)) {
             if (strlen($trimmed) > 0 || $i < $linecount - 1) {
                 $comment[] = $trimmed;
             }
         }
     }
     return array($abbreviatedHash, $tree, $parents, $author, $authorEpoch, $authorTimezone, $committer, $committerEpoch, $committerTimezone, $title, $comment);
 }
Exemplo n.º 5
0
 /**
  * Gets the data for a tag
  *
  * @param GitPHP_Tag $tag tag
  * @return array array of tag data
  */
 public function Load($tag)
 {
     if (!$tag) {
         return;
     }
     $type = null;
     $object = null;
     $commitHash = null;
     $tagger = null;
     $taggerEpoch = null;
     $taggerTimezone = null;
     $comment = array();
     $data = $this->objectLoader->GetObject($tag->GetHash(), $packedType);
     if ($packedType == GitPHP_Pack::OBJ_COMMIT) {
         /* light tag */
         $object = $tag->GetHash();
         $commitHash = $tag->GetHash();
         $type = 'commit';
         return array($type, $object, $commitHash, $tagger, $taggerEpoch, $taggerTimezone, $comment);
     }
     $lines = explode("\n", $data);
     if (!isset($lines[0])) {
         return;
     }
     $objectHash = null;
     $readInitialData = false;
     foreach ($lines as $line) {
         if (!$readInitialData) {
             if (preg_match('/^object ([0-9a-fA-F]{40})$/', $line, $regs)) {
                 $objectHash = $regs[1];
                 continue;
             } else {
                 if (preg_match('/^type (.+)$/', $line, $regs)) {
                     $type = $regs[1];
                     continue;
                 } else {
                     if (preg_match('/^tag (.+)$/', $line, $regs)) {
                         continue;
                     } else {
                         if (preg_match('/^tagger (.*) ([0-9]+) (.*)$/', $line, $regs)) {
                             $tagger = $regs[1];
                             $taggerEpoch = $regs[2];
                             $taggerTimezone = $regs[3];
                             continue;
                         }
                     }
                 }
             }
         }
         $trimmed = trim($line);
         if (strlen($trimmed) > 0 || $readInitialData === true) {
             $comment[] = $line;
         }
         $readInitialData = true;
     }
     switch ($type) {
         case 'commit':
             $object = $objectHash;
             $commitHash = $objectHash;
             break;
         case 'tag':
             $object = $tag->GetProject()->GetTagList()->GetTagNameFromHash($objectHash);
             break;
         case 'blob':
             $object = $objectHash;
             break;
     }
     return array($type, $object, $commitHash, $tagger, $taggerEpoch, $taggerTimezone, $comment);
 }
Exemplo n.º 6
0
 /**
  * Unpacks an object at an offset
  *
  * @param resource $pack pack file pointer
  * @param int $offset object offset
  * @return array object type and data
  */
 private function UnpackObject($pack, $offset)
 {
     fseek($pack, $offset);
     /*
      * object header:
      * first byte is the type (high 3 bits) and low byte of size (lower 4 bits)
      * subsequent bytes each have 7 next higher bits of the size (little endian)
      * most significant bit is either 1 or 0 to indicate whether the next byte
      * should be read as part of the size.  1 means continue reading the size,
      * 0 means the data is starting
      */
     $c = ord(fgetc($pack));
     $type = $c >> 4 & 0x7;
     $size = $c & 0xf;
     for ($i = 4; $c & 0x80; $i += 7) {
         $c = ord(fgetc($pack));
         $size |= ($c & 0x7f) << $i;
     }
     if ($type == GitPHP_Pack::OBJ_COMMIT || $type == GitPHP_Pack::OBJ_TREE || $type == GitPHP_Pack::OBJ_BLOB || $type == GitPHP_Pack::OBJ_TAG) {
         /*
          * regular gzipped object data
          */
         return array($type, gzuncompress(fread($pack, $size + 512), $size));
     } else {
         if ($type == GitPHP_Pack::OBJ_OFS_DELTA) {
             /*
              * delta of an object at offset
              */
             $buf = fread($pack, $size + 512 + 20);
             /*
              * read the base object offset
              * each subsequent byte's 7 least significant bits
              * are part of the offset in decreasing significance per byte
              * (opposite of other places)
              * most significant bit is a flag indicating whether to read the
              * next byte as part of the offset
              */
             $pos = 0;
             $off = -1;
             do {
                 $off++;
                 $c = ord($buf[$pos++]);
                 $off = ($off << 7) + ($c & 0x7f);
             } while ($c & 0x80);
             /*
              * next read the compressed delta data
              */
             $delta = gzuncompress(mb_orig_substr($buf, $pos), $size);
             $baseOffset = $offset - $off;
             if ($baseOffset > 0) {
                 /*
                  * read base object at offset and apply delta to it
                  */
                 list($type, $base) = $this->UnpackObject($pack, $baseOffset);
                 $data = GitPHP_PackData::ApplyDelta($delta, $base);
                 return array($type, $data);
             }
         } else {
             if ($type == GitPHP_Pack::OBJ_REF_DELTA) {
                 /*
                  * delta of object with hash
                  */
                 /*
                  * first the base object's hash
                  * load that object
                  */
                 $hash = fread($pack, 20);
                 $hash = bin2hex($hash);
                 $base = $this->objectLoader->GetObject($hash, $type);
                 /*
                  * then the gzipped delta data
                  */
                 $delta = gzuncompress(fread($pack, $size + 512), $size);
                 $data = GitPHP_PackData::ApplyDelta($delta, $base);
                 return array($type, $data);
             }
         }
     }
     return false;
 }