Skip to content

Commit b5b5ce7

Browse files
committed
add Git\Reference\Manager class.
[added] - Git\Reference\Manager::getList() - Git\Reference\Manager::create(string $name, string $oid) - Git\Reference\Manager::lookupRef(string $name) - Git\Reference\Manager::pack() - Git\Reference\Manager::__construct(Git\Repository $repository) [obsoleted] - Git\Repository::getReferences() should use Git\Reference\Manager::getList(). e.g) $repository = new Git\Repository("/path/to/git/.git"); $manager = new Git\Reference\Manager($repository); $manager->getList(); $manager->lookupRef("refs/heads/master") $manager->create("refs/heads/oid-fix",hash); $manager->pack(); // be carefull to use this method.
1 parent 2416274 commit b5b5ce7

File tree

4 files changed

+303
-1
lines changed

4 files changed

+303
-1
lines changed

src/config.m4

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ if test $PHP_GIT != "no"; then
2929
PHP_ADD_LIBRARY_WITH_PATH(git2, $LIBGIT2_LIBDIR, GIT_SHARED_LIBADD)
3030

3131
PHP_SUBST(GIT_SHARED_LIBADD)
32-
PHP_NEW_EXTENSION(git,php_git.c reference.c repository.c signature.c commit.c index_entry.c index.c tree.c blob.c tree_entry.c walker.c object.c rawobject.c tag.c odb.c backend.c, $ext_shared)
32+
PHP_NEW_EXTENSION(git,php_git.c reference.c reference_manager.c repository.c signature.c commit.c index_entry.c index.c tree.c blob.c tree_entry.c walker.c object.c rawobject.c tag.c odb.c backend.c, $ext_shared)
3333

3434
ifdef([PHP_ADD_EXTENSION_DEP],
3535
[

src/php_git.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ PHP_MINIT_FUNCTION(git) {
145145
git_init_blob(TSRMLS_C);
146146
git_init_odb(TSRMLS_C);
147147
git_init_backend(TSRMLS_C);
148+
git_init_reference_manager(TSRMLS_C);
148149

149150
REGISTER_NS_LONG_CONSTANT(ZEND_NS_NAME(PHP_GIT_NS,"Revwalk"), "SORT_NONE", 0, CONST_CS | CONST_PERSISTENT);
150151
REGISTER_NS_LONG_CONSTANT(ZEND_NS_NAME(PHP_GIT_NS,"Revwalk"), "SORT_TOPO", 1, CONST_CS | CONST_PERSISTENT);

src/php_git.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ extern zend_module_entry git_module_entry;
4747

4848
extern PHPAPI zend_class_entry *git_class_entry;
4949
extern PHPAPI zend_class_entry *git_reference_class_entry;
50+
extern PHPAPI zend_class_entry *git_reference_manager_class_entry;
5051
extern PHPAPI zend_class_entry *git_repository_class_entry;
5152
extern PHPAPI zend_class_entry *git_object_class_entry;
5253
extern PHPAPI zend_class_entry *git_index_class_entry;
@@ -148,5 +149,10 @@ typedef struct{
148149
git_reference *object;
149150
} php_git_reference_t;
150151

152+
typedef struct{
153+
zend_object zo;
154+
git_repository *repository;
155+
} php_git_reference_manager_t;
156+
151157

152158
#endif /* PHP_GIT_H */

src/reference_manager.c

Lines changed: 295 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
1+
/*
2+
* The MIT License
3+
*
4+
* Copyright (c) 2010 - 2011 Shuhei Tanuma
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
25+
#include "php_git.h"
26+
#include <spl/spl_array.h>
27+
#include <zend_interfaces.h>
28+
#include <string.h>
29+
#include <time.h>
30+
31+
PHPAPI zend_class_entry *git_reference_manager_class_entry;
32+
33+
ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_manager__construct, 0, 0, 1)
34+
ZEND_ARG_INFO(0, repository)
35+
ZEND_END_ARG_INFO()
36+
37+
ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_manager_lookup, 0, 0, 1)
38+
ZEND_ARG_INFO(0, name)
39+
ZEND_END_ARG_INFO()
40+
41+
ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_manager_create, 0, 0, 2)
42+
ZEND_ARG_INFO(0, name)
43+
ZEND_ARG_INFO(0, oid)
44+
ZEND_END_ARG_INFO()
45+
46+
static void php_git_reference_manager_free_storage(php_git_reference_manager_t *obj TSRMLS_DC)
47+
{
48+
zend_object_std_dtor(&obj->zo TSRMLS_CC);
49+
obj->repository = NULL;
50+
efree(obj);
51+
}
52+
53+
zend_object_value php_git_reference_manager_new(zend_class_entry *ce TSRMLS_DC)
54+
{
55+
zend_object_value retval;
56+
php_git_tree_entry_t *obj;
57+
zval *tmp;
58+
59+
obj = ecalloc(1, sizeof(*obj));
60+
zend_object_std_init( &obj->zo, ce TSRMLS_CC );
61+
zend_hash_copy(obj->zo.properties, &ce->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
62+
63+
retval.handle = zend_objects_store_put(obj,
64+
(zend_objects_store_dtor_t)zend_objects_destroy_object,
65+
(zend_objects_free_object_storage_t)php_git_reference_manager_free_storage,
66+
NULL TSRMLS_CC);
67+
retval.handlers = zend_get_std_object_handlers();
68+
return retval;
69+
}
70+
71+
PHP_METHOD(git_reference_manager, __construct)
72+
{
73+
php_git_reference_manager_t *this= (php_git_reference_manager_t *) zend_object_store_get_object(getThis() TSRMLS_CC);
74+
zval *repository;
75+
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
76+
"z", &repository) == FAILURE){
77+
return;
78+
}
79+
if(!instanceof_function(Z_OBJCE_P(repository), git_repository_class_entry TSRMLS_CC)){
80+
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC,
81+
"argument does not Git\\Repository");
82+
RETURN_FALSE;
83+
}
84+
php_git_repository_t *repo = (php_git_repository_t *) zend_object_store_get_object(repository TSRMLS_CC);
85+
if(repo->repository == NULL){
86+
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC,
87+
"repository didn't ready");
88+
RETURN_FALSE;
89+
}
90+
this->repository = repo->repository;
91+
}
92+
93+
PHP_METHOD(git_reference_manager, getList)
94+
{
95+
php_git_reference_manager_t *this= (php_git_reference_manager_t *) zend_object_store_get_object(getThis() TSRMLS_CC);
96+
git_strarray *list = malloc(sizeof(git_strarray));
97+
int result;
98+
int i = 0;
99+
git_reference *reference;
100+
zval *references;
101+
git_rtype type;
102+
char out[GIT_OID_HEXSZ+1] = {0};
103+
104+
git_reference_listall(list,this->repository,GIT_REF_LISTALL);
105+
106+
MAKE_STD_ZVAL(references);
107+
array_init(references);
108+
for(i = 0; i < list->count; i++){
109+
zval *ref;
110+
111+
// FIXME
112+
result = git_reference_lookup(&reference, this->repository, list->strings[i]);
113+
if(result != GIT_SUCCESS) {
114+
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC,
115+
"Can't find specified reference.");
116+
RETURN_FALSE;
117+
}
118+
119+
MAKE_STD_ZVAL(ref);
120+
object_init_ex(ref, git_reference_class_entry);
121+
php_git_reference_t *refobj = (php_git_reference_t *) zend_object_store_get_object(ref TSRMLS_CC);
122+
refobj->object = reference;
123+
124+
add_property_string_ex(ref,"name", sizeof("name"), (char *)git_reference_name(reference), 1 TSRMLS_CC);
125+
126+
type = git_reference_type(reference);
127+
if(type == GIT_REF_SYMBOLIC) {
128+
const char *target = git_reference_target(reference);
129+
if(target != NULL) {
130+
add_property_string_ex(ref,"target",sizeof("target"),(char *)target, 1 TSRMLS_CC);
131+
}
132+
int rr = git_reference_resolve(&refobj->object,reference);
133+
if(rr != GIT_SUCCESS){
134+
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC,
135+
"something wrong");
136+
RETURN_FALSE;
137+
}
138+
}
139+
140+
git_oid_to_string(out,GIT_OID_HEXSZ+1,git_reference_oid(refobj->object));
141+
add_property_string_ex(ref,"oid",sizeof("oid"),out, 1 TSRMLS_CC);
142+
memset(out,'\0',GIT_OID_HEXSZ+1);
143+
//
144+
145+
add_next_index_zval(references, ref);
146+
}
147+
148+
git_strarray_free(list);
149+
RETURN_ZVAL(references,0,0);
150+
}
151+
152+
PHP_METHOD(git_reference_manager, pack)
153+
{
154+
php_git_reference_manager_t *this= (php_git_reference_manager_t *) zend_object_store_get_object(getThis() TSRMLS_CC);
155+
int ret = git_reference_packall(this->repository);
156+
if(ret != GIT_SUCCESS){
157+
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC,
158+
"an error occured while packing references. error_code: %d\n",ret);
159+
RETURN_FALSE;
160+
}
161+
RETURN_TRUE;
162+
}
163+
164+
PHP_METHOD(git_reference_manager, lookupRef)
165+
{
166+
php_git_reference_manager_t *this = (php_git_reference_manager_t *) zend_object_store_get_object(getThis() TSRMLS_CC);
167+
char *name;
168+
int name_len = 0;
169+
int result;
170+
zval *ref;
171+
char out[GIT_OID_HEXSZ+1] = {0};
172+
git_oid *oid;
173+
git_rtype type;
174+
git_reference *reference;
175+
176+
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
177+
"s", &name, &name_len) == FAILURE){
178+
return;
179+
}
180+
181+
result = git_reference_lookup(&reference, this->repository, name);
182+
if(result != GIT_SUCCESS) {
183+
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC,
184+
"Can't find specified reference.");
185+
RETURN_FALSE;
186+
}
187+
188+
MAKE_STD_ZVAL(ref);
189+
object_init_ex(ref, git_reference_class_entry);
190+
php_git_reference_t *refobj = (php_git_reference_t *) zend_object_store_get_object(ref TSRMLS_CC);
191+
refobj->object = reference;
192+
193+
add_property_string_ex(ref,"name", sizeof("name"), (char *)git_reference_name(reference), 1 TSRMLS_CC);
194+
195+
type = git_reference_type(reference);
196+
if(type == GIT_REF_SYMBOLIC) {
197+
const char *target = git_reference_target(reference);
198+
if(target != NULL) {
199+
add_property_string_ex(ref,"target",sizeof("target"),(char *)target, 1 TSRMLS_CC);
200+
}
201+
int rr = git_reference_resolve(&refobj->object,reference);
202+
if(rr != GIT_SUCCESS){
203+
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC,
204+
"something wrong");
205+
RETURN_FALSE;
206+
}
207+
}
208+
209+
git_oid_to_string(out,GIT_OID_HEXSZ+1,git_reference_oid(refobj->object));
210+
add_property_string_ex(ref,"oid",sizeof("oid"),out, 1 TSRMLS_CC);
211+
212+
RETURN_ZVAL(ref,0,0);
213+
}
214+
215+
PHP_METHOD(git_reference_manager, create)
216+
{
217+
php_git_reference_manager_t *this = (php_git_reference_manager_t *) zend_object_store_get_object(getThis() TSRMLS_CC);
218+
char *name;
219+
int name_len = 0;
220+
char *oid;
221+
int oid_len = 0;
222+
git_oid id;
223+
224+
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
225+
"ss", &name, &name_len, &oid, &oid_len) == FAILURE){
226+
return;
227+
}
228+
if(oid_len != GIT_OID_HEXSZ){
229+
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC,
230+
"oid length seems illegal");
231+
RETURN_FALSE;
232+
}
233+
234+
git_oid_mkstr(&id, oid);
235+
git_odb *odb;
236+
odb = git_repository_database(this->repository);
237+
238+
if(!git_odb_exists(odb,&id)){
239+
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC,
240+
"specified oid not found");
241+
RETURN_FALSE;
242+
}
243+
244+
git_reference *reference;
245+
int ret = git_reference_create_oid(&reference, this->repository, name, &id);
246+
if(ret != GIT_SUCCESS){
247+
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC,
248+
"can't add reference");
249+
RETURN_FALSE;
250+
}
251+
252+
char out[GIT_OID_HEXSZ+1] = {0};
253+
git_rtype type;
254+
zval *ref;
255+
MAKE_STD_ZVAL(ref);
256+
object_init_ex(ref, git_reference_class_entry);
257+
php_git_reference_t *refobj = (php_git_reference_t *) zend_object_store_get_object(ref TSRMLS_CC);
258+
refobj->object = reference;
259+
260+
add_property_string_ex(ref,"name", sizeof("name"), name, 1 TSRMLS_CC);
261+
type = git_reference_type(reference);
262+
if(type == GIT_REF_SYMBOLIC) {
263+
const char *target = git_reference_target(reference);
264+
if(target != NULL) {
265+
add_property_string_ex(ref,"target",sizeof("target"),(char *)target, 1 TSRMLS_CC);
266+
}
267+
int rr = git_reference_resolve(&refobj->object,reference);
268+
if(rr != GIT_SUCCESS){
269+
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC,
270+
"something wrong");
271+
RETURN_FALSE;
272+
}
273+
}
274+
git_oid_to_string(out,GIT_OID_HEXSZ+1,git_reference_oid(refobj->object));
275+
add_property_string_ex(ref,"oid",sizeof("oid"),out, 1 TSRMLS_CC);
276+
RETURN_ZVAL(ref,0,0);
277+
}
278+
279+
PHPAPI function_entry php_git_reference_manager_methods[] = {
280+
PHP_ME(git_reference_manager, __construct, arginfo_git_reference_manager__construct, ZEND_ACC_PUBLIC)
281+
PHP_ME(git_reference_manager, getList, NULL, ZEND_ACC_PUBLIC)
282+
PHP_ME(git_reference_manager, lookupRef, arginfo_git_reference_manager_lookup, ZEND_ACC_PUBLIC)
283+
PHP_ME(git_reference_manager, pack, NULL, ZEND_ACC_PUBLIC)
284+
PHP_ME(git_reference_manager, create, arginfo_git_reference_manager_create, ZEND_ACC_PUBLIC)
285+
{NULL, NULL, NULL}
286+
};
287+
288+
void git_init_reference_manager(TSRMLS_D)
289+
{
290+
zend_class_entry ce;
291+
INIT_NS_CLASS_ENTRY(ce, ZEND_NS_NAME(PHP_GIT_NS,"Reference"),"Manager", php_git_reference_manager_methods);
292+
git_reference_manager_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
293+
git_reference_manager_class_entry->create_object = php_git_reference_manager_new;
294+
295+
}

0 commit comments

Comments
 (0)