summaryrefslogtreecommitdiffstats
path: root/3rdparty/granite/git/object/raw.php
blob: 56f363c37b29b98747413a4999428e7a4568627b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
<?php
/**
 * Raw - provides a raw Git object
 *
 * PHP version 5.3
 *
 * @category Git
 * @package  Granite
 * @author   Craig Roberts <craig0990@googlemail.com>
 * @license  http://www.opensource.org/licenses/mit-license.php MIT Expat License
 * @link     http://craig0990.github.com/Granite/
 */

namespace Granite\Git\Object;
use \InvalidArgumentException as InvalidArgumentException;

/**
 * Raw represents a raw Git object, using Index to locate
 * packed objects.
 *
 * @category Git
 * @package  Granite
 * @author   Craig Roberts <craig0990@googlemail.com>
 * @license  http://www.opensource.org/licenses/mit-license.php MIT Expat License
 * @link     http://craig0990.github.com/Granite/
 */
class Raw
{
    /**
     * Integer values for Git objects
     * @see http://book.git-scm.com/7_the_packfile.html
     */
    const OBJ_COMMIT = 1;
    const OBJ_TREE = 2;
    const OBJ_BLOB = 3;
    const OBJ_TAG = 4;
    const OBJ_OFS_DELTA = 6;
    const OBJ_REF_DELTA = 7;

    /**
     * The SHA-1 id of the requested object
     */
    protected $sha;
    /**
     * The type of the requested object (see class constants)
     */
    protected $type;
    /**
     * The binary string content of the requested object
     */
    protected $content;

    /**
     * Returns an instance of a raw Git object
     *
     * @param string $path The path to the repository root
     * @param string $sha  The SHA-1 id of the requested object
     *
     * @return Packed|Loose
     */
    public static function factory($path, $sha)
    {
        $loose_path = $path
                      . 'objects/'
                      . substr($sha, 0, 2)
                      . '/'
                      . substr($sha, 2);
        if (file_exists($loose_path)) {
            return new Loose($path, $sha);
        } else {
            return self::_findPackedObject($path, $sha);
        }
    }

    /**
     * Returns the raw content of the Git object requested
     *
     * @return string Raw object content
     */
    public function content()
    {
        return $this->content;
    }

    /**
     * Returns the size of the Git object
     *
     * @return int The size of the object in bytes
     */
    public function size()
    {
        return strlen($this->content);
    }

    /**
     * Returns the type of the object as either commit, tag, blob or tree
     *
     * @return string The object type
     */
    public function type()
    {
        return $this->type;
    }

    /**
     * Searches a packfile for the SHA id and reads the object from the packfile
     *
     * @param string $path The path to the repository
     * @param string $sha  The SHA-1 id of the object being requested
     *
     * @throws \InvalidArgumentException
     * @return array An array containing the type, size and object data
     */
    private static function _findPackedObject($path, $sha)
    {
        $packfiles = glob(
            $path
            . 'objects'
            . DIRECTORY_SEPARATOR
            . 'pack'
            . DIRECTORY_SEPARATOR
            . 'pack-*.pack'
        );

        $offset = false;
        foreach ($packfiles as $packfile) {
            $packname = substr(basename($packfile, '.pack'), 5);
            $idx = new Index($path, $packname);
            $offset = $idx->find($sha);

            if ($offset !== false) {
                break; // Found it
            }
        }

        if ($offset == false) {
            throw new InvalidArgumentException("Could not find packed object $sha");
        }

        $packname = $path
            . 'objects'
            . DIRECTORY_SEPARATOR
            . 'pack'
            . DIRECTORY_SEPARATOR
            . 'pack-' . $packname . '.pack';
        $object = new Packed($packname, $offset);

        return $object;
    }

}

?>