Skip to content

Commit 6953b00

Browse files
committedJan 15, 2014
[remote] WIP: push
1 parent 8d9977d commit 6953b00

File tree

6 files changed

+140
-17
lines changed

6 files changed

+140
-17
lines changed
 

‎example/push.php

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
$payload = array();
4+
$repo = git_repository_open(".");
5+
$remote = git_remote_load($repo, "origin");
6+
$remote_callbacks = [
7+
"credentials" => function($url, $username_from_url, $allowed_types, &$payload) {
8+
// NOTE(chobie): you need to build with LibSSH2 when communicating with ssh protocol. */
9+
if ($allowed_types & GIT_CREDTYPE_USERPASS_PLAINTEXT) {
10+
return git_cred_userpass_plaintext_new("chobie", getenv("GITHUB_TOKEN"));
11+
} else {
12+
error_log("not supported allowed types");
13+
}
14+
}];
15+
16+
git_remote_set_callbacks($remote, $remote_callbacks);
17+
if (git_remote_connect($remote, GIT_DIRECTION_PUSH)) {
18+
$push = git_push_new($remote);
19+
20+
git_push_add_refspec($push, "refs/heads/master:refs/heads/master");
21+
git_push_finish($push);
22+
git_push_unpack_ok($push);
23+
24+
git_push_status_foreach($push, function($ref, $name, &$payload){
25+
var_dump($ref, $name, $payload);
26+
}, $payload);
27+
28+
git_push_update_tips($push);
29+
git_remote_disconnect($remote);
30+
}

‎example/reflog.php

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
$repo = git_repository_open("../");
3+
$reflog = git_reflog_read($repo, "HEAD");
4+
5+
$count = git_reflog_entrycount($reflog);
6+
for ($i = 0; $i < $count; $i++) {
7+
$entry = git_reflog_entry_byindex($reflog, $i);
8+
var_dump(git_reflog_entry_committer($entry));
9+
}

‎php_git2.c

+7
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,12 @@ PHP_FUNCTION(git_checkout_opts_new)
310310
RETURN_ZVAL(tmp, 0, 1);
311311
}
312312

313+
PHP_FUNCTION(git_libgit2_capabilities)
314+
{
315+
RETURN_LONG(git_libgit2_capabilities());
316+
}
317+
318+
313319
static zend_function_entry php_git2_functions[] = {
314320
/* repository */
315321
PHP_FE(git_repository_new, arginfo_git_repository_new)
@@ -914,6 +920,7 @@ static zend_function_entry php_git2_functions[] = {
914920

915921
/* misc */
916922
PHP_FE(git_resource_type, arginfo_git_resource_type)
923+
PHP_FE(git_libgit2_capabilities, NULL)
917924
PHP_FE_END
918925
};
919926

‎push.c

+28-3
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,34 @@
44

55
static int php_git2_push_status_foreach_cb(const char *ref, const char *msg, void *data)
66
{
7-
fprintf(stderr, "ref: %s\n", ref);
8-
fprintf(stderr, "msg: %s\n", msg);
9-
return 0;
7+
php_git2_t *result;
8+
zval *param_ref, *param_msg, *retval_ptr = NULL;
9+
php_git2_cb_t *p = (php_git2_cb_t*)data;
10+
int i = 0;
11+
int retval = 0;
12+
GIT2_TSRMLS_SET(p->tsrm_ls)
13+
14+
Z_ADDREF_P(p->payload);
15+
MAKE_STD_ZVAL(param_ref);
16+
MAKE_STD_ZVAL(param_msg);
17+
ZVAL_NULL(param_ref);
18+
ZVAL_NULL(param_msg);
19+
20+
if (ref != NULL) {
21+
ZVAL_STRING(param_ref, ref, 1);
22+
}
23+
if (msg != NULL) {
24+
ZVAL_STRING(param_msg, msg, 1);
25+
}
26+
27+
if (php_git2_call_function_v(p->fci, p->fcc TSRMLS_CC, &retval_ptr, 3, &param_ref, &param_msg, &p->payload)) {
28+
zend_list_delete(result->resource_id);
29+
return GIT_EUSER;
30+
}
31+
32+
retval = Z_LVAL_P(retval_ptr);
33+
zval_ptr_dtor(&retval_ptr);
34+
return retval;
1035
}
1136

1237
/* {{{ proto resource git_push_new(resource $remote)

‎push.h

+3-5
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_git_push_unpack_ok, 0, 0, 1)
6060
ZEND_ARG_INFO(0, push)
6161
ZEND_END_ARG_INFO()
6262

63-
ZEND_BEGIN_ARG_INFO_EX(arginfo_git_push_status_foreach, 0, 0, 5)
63+
ZEND_BEGIN_ARG_INFO_EX(arginfo_git_push_status_foreach, 0, 0, 3)
6464
ZEND_ARG_INFO(0, push)
65-
ZEND_ARG_INFO(0, ref)
66-
ZEND_ARG_INFO(0, msg)
67-
ZEND_ARG_INFO(0, data)
68-
ZEND_ARG_INFO(0, data)
65+
ZEND_ARG_INFO(0, callback)
66+
ZEND_ARG_INFO(1, data)
6967
ZEND_END_ARG_INFO()
7068

7169
ZEND_BEGIN_ARG_INFO_EX(arginfo_git_push_free, 0, 0, 1)

‎remote.c

+63-9
Original file line numberDiff line numberDiff line change
@@ -753,40 +753,94 @@ PHP_FUNCTION(git_remote_set_transport)
753753
}
754754
/* }}} */
755755

756-
static int cred_cb(git_cred **cred, const char *url, const char *username_from_url, unsigned int allowed_types, void *data)
757-
{
758-
fprintf(stderr, "url: %s\n", url);
759-
fprintf(stderr, "name: %s\n", username_from_url);
760-
fprintf(stderr, "types: %d\n", allowed_types);
761-
762-
return 0;
763-
}
764756

765757
typedef struct php_git2_fcall_t {
766758
zend_fcall_info fci;
767759
zend_fcall_info_cache fcc;
760+
zval *value;
768761
} php_git2_fcall_t;
762+
769763
typedef struct php_git2_remote_cb_t {
770764
php_git2_fcall_t callbacks[4];
771765
zval *payload;
766+
GIT2_TSRMLS_DECL
772767
} php_git2_remote_cb_t;
773768

769+
static int cred_cb(git_cred **cred, const char *url, const char *username_from_url, unsigned int allowed_types, void *data)
770+
{
771+
php_git2_t *result;
772+
zval *param_url = NULL, *param_username_from_url = NULL, *param_allowed_types = NULL, *retval_ptr;
773+
php_git2_remote_cb_t *cb = (php_git2_remote_cb_t*)data;
774+
GIT2_TSRMLS_SET(cb->tsrm_ls);
775+
int retval = 1;
776+
777+
if (cb != NULL) {
778+
MAKE_STD_ZVAL(param_url);
779+
MAKE_STD_ZVAL(param_username_from_url);
780+
MAKE_STD_ZVAL(param_allowed_types);
781+
ZVAL_NULL(param_url);
782+
ZVAL_NULL(param_username_from_url);
783+
784+
if (url != NULL) {
785+
ZVAL_STRING(param_url, url, 1);
786+
}
787+
if (username_from_url != NULL) {
788+
ZVAL_STRING(param_username_from_url, username_from_url, 1);
789+
}
790+
ZVAL_LONG(param_allowed_types, allowed_types);
791+
Z_ADDREF_P(cb->payload);
792+
SEPARATE_ZVAL_TO_MAKE_IS_REF(&cb->payload);
793+
794+
if (php_git2_call_function_v(&cb->callbacks[0].fci, &cb->callbacks[0].fcc TSRMLS_CC, &retval_ptr, 4,
795+
&param_url, &param_username_from_url, &param_allowed_types, &cb->payload)) {
796+
fprintf(stderr, "CALL FUNCTION ERROR");
797+
}
798+
}
799+
800+
if (retval_ptr && Z_TYPE_P(retval_ptr) == IS_RESOURCE) {
801+
ZEND_FETCH_RESOURCE_NO_RETURN(result, php_git2_t*, &retval_ptr, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);
802+
*cred = PHP_GIT2_V(result, cred);
803+
zval_ptr_dtor(&retval_ptr);
804+
}
805+
return retval;
806+
}
807+
774808
/* {{{ proto long git_remote_set_callbacks(remote, callbacks)
775809
*/
776810
PHP_FUNCTION(git_remote_set_callbacks)
777811
{
778812
zval *remote;
779813
php_git2_t *_remote;
780-
zval *callbacks;
814+
zval *callbacks, *credentials_cb = NULL;
781815
php_git2_t *_callbacks;
782816
struct git_remote_callbacks cb = GIT_REMOTE_CALLBACKS_INIT;
817+
php_git2_remote_cb_t *_payload = NULL, payload = {0};
783818

784819
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
785820
"ra", &remote, &callbacks) == FAILURE) {
786821
return;
787822
}
788823

824+
/* TODO(chobie): support other callbacks */
789825
cb.credentials = cred_cb;
826+
credentials_cb = php_git2_read_arrval(callbacks, ZEND_STRS("credentials") TSRMLS_CC);
827+
828+
/* TODO(chobie): can we free payload? */
829+
_payload = emalloc(sizeof(php_git2_remote_cb_t));
830+
MAKE_STD_ZVAL(_payload->payload);
831+
GIT2_TSRMLS_SET2(_payload, TSRMLS_C);
832+
833+
if (credentials_cb != NULL) {
834+
char *is_callable_error;
835+
836+
if(zend_fcall_info_init(credentials_cb, 0, &(_payload->callbacks[0].fci), &(_payload->callbacks[0].fci), NULL, &is_callable_error TSRMLS_CC) == SUCCESS) {
837+
if (is_callable_error) {
838+
efree(is_callable_error);
839+
}
840+
}
841+
Z_ADDREF_P(credentials_cb);
842+
}
843+
cb.payload = _payload;
790844

791845
ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);
792846
git_remote_set_callbacks(PHP_GIT2_V(_remote, remote), &cb);

0 commit comments

Comments
 (0)
Please sign in to comment.