Subversion Repositories oidplus

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1192 daniel-mar 1
<?php
2
 
3
/*
4
 * Copyright (C) 2008 Patrik Fimml
5
 * Copyright (c) 2023 Daniel Marschall
6
 *
7
 * This file is part of glip.
8
 *
9
 * glip is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU General Public License as published by
11
 * the Free Software Foundation, either version 2 of the License, or
12
 * (at your option) any later version.
13
 
14
 * glip is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with glip.  If not, see <http://www.gnu.org/licenses/>.
21
 */
22
 
23
namespace ViaThinkSoft\Glip;
24
 
25
class GitObject
26
{
27
        /**
28
         * @brief (Git) The repository this object belongs to.
29
         */
30
        public $repo;
31
        protected $type;
32
        protected $name = null;
33
 
34
        /**
35
         * @brief Get the object's cached SHA-1 hash value.
36
         *
37
         * @returns (string) The hash value (binary sha1).
38
         */
39
        public function getName() {
40
                return $this->name;
41
        }
42
 
43
        /**
44
         * @brief Get the object's type.
45
         *
46
         * @returns (integer) One of Git::OBJ_COMMIT, Git::OBJ_TREE or
47
         * GIT::OBJ_BLOB.
48
         */
49
        public function getType() {
50
                return $this->type;
51
        }
52
 
53
        /**
54
         * @brief Create a GitObject of the specified type.
55
         *
56
         * @param $repo (Git) The repository the object belongs to.
57
         * @param $type (integer) Object type (one of Git::OBJ_COMMIT,
58
         * Git::OBJ_TREE, Git::OBJ_BLOB).
59
         * @returns GitCommit|GitTree|GitBlob  A new GitCommit, GitTree or GitBlob object respectively.
60
         */
61
        static public function create($repo, $type) {
62
                if ($type == Git::OBJ_COMMIT)
63
                        return new GitCommit($repo);
64
                if ($type == Git::OBJ_TREE)
65
                        return new GitTree($repo);
66
                if ($type == Git::OBJ_BLOB)
67
                        return new GitBlob($repo);
68
                throw new \Exception(sprintf('unhandled object type %d', $type));
69
        }
70
 
71
        /**
72
         * @brief Internal function to calculate the hash value of a git object of the
73
         * current type with content $data.
74
         *
75
         * @param $data (string) The data to hash.
76
         * @returns (string) The hash value (binary sha1).
77
         */
78
        protected function hash($data) {
79
                $hash = hash_init('sha1');
80
                hash_update($hash, Git::getTypeName($this->type));
81
                hash_update($hash, ' ');
82
                hash_update($hash, "".strlen($data));
83
                hash_update($hash, "\0");
84
                hash_update($hash, $data);
85
                return hash_final($hash, true);
86
        }
87
 
88
        /**
89
         * @brief Internal constructor for use from derived classes.
90
         *
91
         * Never use this function except from a derived class. Use the
92
         * constructor of a derived class, create() or Git::getObject() instead.
93
         */
94
        public function __construct($repo, $type) {
95
                $this->repo = $repo;
96
                $this->type = $type;
97
        }
98
 
99
        /**
100
         * @brief Populate this object with values from its string representation.
101
         *
102
         * Note that the types of $this and the serialized object in $data have to
103
         * match.
104
         *
105
         * @param $data (string) The serialized representation of an object, as
106
         * it would be stored by git.
107
         */
108
        public function unserialize($data) {
109
                $this->name = $this->hash($data);
110
                $this->_unserialize($data);
111
        }
112
 
113
        /**
114
         * @brief Get the string representation of an object.
115
         *
116
         * @returns string The serialized representation of the object, as it would be
117
         * stored by git.
118
         */
119
        public function serialize() {
120
                return $this->_serialize();
121
        }
122
 
123
        /**
124
         * @brief Update the SHA-1 name of an object.
125
         *
126
         * You need to call this function after making changes to attributes in
127
         * order to have getName() return the correct hash.
128
         */
129
        public function rehash() {
130
                $this->name = $this->hash($this->serialize());
131
        }
132
 
133
        /**
134
         * @brief Write this object in its serialized form to the git repository
135
         * given at creation time.
136
         */
137
        public function write() {
138
                $sha1 = bin2hex($this->name);
139
                $path = sprintf('%s/objects/%s/%s', $this->repo->dir, substr($sha1, 0, 2), substr($sha1, 2));
140
                if (file_exists($path))
141
                        return false;
142
                $dir = dirname($path);
143
                if (!is_dir($dir))
144
                        mkdir(dirname($path), 0770);
145
                $f = fopen($path, 'ab');
146
                flock($f, LOCK_EX);
147
                ftruncate($f, 0);
148
                $data = $this->serialize();
149
                $data = Git::getTypeName($this->type) . ' ' . strlen($data) . "\0" . $data;
150
                fwrite($f, gzcompress($data));
151
                fclose($f);
152
                return true;
153
        }
154
}