Skip to content

Commit

Permalink
[status] implement git_status
Browse files Browse the repository at this point in the history
  • Loading branch information
chobie committed Jan 19, 2014
1 parent b79c301 commit 516fe0a
Show file tree
Hide file tree
Showing 6 changed files with 196 additions and 8 deletions.
68 changes: 68 additions & 0 deletions example/status.php
@@ -0,0 +1,68 @@
<?php
$repo = git_repository_open(".");
$list = git_status_list_new($repo, array(
));

$payload = array();
printf("# Changes to be committed:\n");
printf("# (use \"git reset HEAD <file>...\" to unstage)\n");
printf("#\n");

$cnt = git_status_list_entrycount($list);
for ($i = 0; $i < $cnt; $i++) {
$entry = git_status_byindex($list, $i);
$flags = $entry['status'];
$stat = getStat($flags);

if (is_array($entry['head_to_index'])) {
printf("# %15s %s\n", $stat, $entry['head_to_index']['new_file']['path']);
}
}

printf("#\n");
printf("# Changes not staged for commit:\n");
printf("# (use \"git add <file>...\" to update what will be committed)\n");
printf("# (use \"git checkout -- <file>...\" to discard changes in working directory)\n");
printf("#\n");

for ($i = 0; $i < $cnt; $i++) {
$entry = git_status_byindex($list, $i);
$flags = $entry['status'];
$stat = getStat($flags);

if (is_array($entry['index_to_workdir'])) {
printf("# %15s %s\n", $stat, $entry['index_to_workdir']['new_file']['path']);
}
}
printf("#\n");


function getStat($flags)
{
$stat = "";
if ($flags & GIT_STATUS_IGNORED) {
return;
}
if ($flags == GIT_STATUS_CURRENT) {
return;
}
if ($flags & GIT_STATUS_INDEX_NEW){
$stat = "new file:";
}
if ($flags & GIT_STATUS_WT_NEW) {
$stat = "untracked:";
}
if ($flags & GIT_STATUS_INDEX_MODIFIED ||$flags & GIT_STATUS_WT_MODIFIED) {
$stat = "modified:";
}
if ($flags & GIT_STATUS_INDEX_DELETED || $flags & GIT_STATUS_WT_DELETED) {
$stat = "deleted:";
}
if ($flags & GIT_STATUS_INDEX_RENAMED || $flags & GIT_STATUS_WT_RENAMED) {
$stat = "renamed:";
}
if ($flags & GIT_STATUS_INDEX_TYPECHANGE || $flags & GIT_STATUS_WT_TYPECHANGE) {
$stat = "typechange:";
}
return $stat;
}
13 changes: 13 additions & 0 deletions helper.c
Expand Up @@ -43,6 +43,19 @@ zval* php_git2_read_arrval(zval *array, char *name, size_t name_len TSRMLS_DC)
return result;
}

long php_git2_read_arrval_long2(zval *array, char *name, size_t name_len, long value TSRMLS_DC)
{
zval *tmp;
long result = value;

tmp = php_git2_read_arrval(array, name, name_len TSRMLS_CC);
if (tmp) {
result = Z_LVAL_P(tmp);
}

return result;
}

long php_git2_read_arrval_long(zval *array, char *name, size_t name_len TSRMLS_DC)
{
zval *tmp;
Expand Down
2 changes: 2 additions & 0 deletions helper.h
Expand Up @@ -32,6 +32,8 @@ int php_git2_check_error(int error_code, const char *action TSRMLS_DC);

zval* php_git2_read_arrval(zval *array, char *name, size_t name_len TSRMLS_DC);

long php_git2_read_arrval_long2(zval *array, char *name, size_t name_len, long value TSRMLS_DC);

long php_git2_read_arrval_long(zval *array, char *name, size_t name_len TSRMLS_DC);

const char* php_git2_read_arrval_string(zval *array, char *name, size_t name_len TSRMLS_DC);
Expand Down
1 change: 1 addition & 0 deletions php_git2.c
Expand Up @@ -664,6 +664,7 @@ static zend_function_entry php_git2_functions[] = {
PHP_FE(git_status_byindex, arginfo_git_status_byindex)
PHP_FE(git_status_list_free, arginfo_git_status_list_free)
PHP_FE(git_status_should_ignore, arginfo_git_status_should_ignore)
PHP_FE(git_status_options_new, NULL)

/* transport */
PHP_FE(git_transport_new, arginfo_git_transport_new)
Expand Down
118 changes: 110 additions & 8 deletions status.c
Expand Up @@ -2,6 +2,86 @@
#include "php_git2_priv.h"
#include "status.h"

static void php_git2_git_status_options_to_array(git_status_options *options, zval **out TSRMLS_DC)
{
zval *result, *pathspec;

MAKE_STD_ZVAL(result);
array_init(result);

add_assoc_long_ex(result, ZEND_STRS("version"), options->version);
add_assoc_long_ex(result, ZEND_STRS("show"), options->show);
add_assoc_long_ex(result, ZEND_STRS("flags"), options->flags);
php_git2_strarray_to_array(&options->pathspec, &pathspec TSRMLS_CC);
add_assoc_zval_ex(result, ZEND_STRS("pathspec"), pathspec);

*out = result;
}

static void php_git2_array_to_git_status_options(git_status_options *options, zval *array TSRMLS_DC)
{
zval *tmp;
options->version = php_git2_read_arrval_long2(array, ZEND_STRS("version"), 1 TSRMLS_CC);
options->show = php_git2_read_arrval_long2(array, ZEND_STRS("version"), 0 TSRMLS_CC);
options->flags = php_git2_read_arrval_long2(array, ZEND_STRS("version"), 0 TSRMLS_CC);

php_git2_array_to_strarray(&options->pathspec, php_git2_read_arrval(array, ZEND_STRS("pathspec") TSRMLS_CC) TSRMLS_CC);
}

static void php_git2_git_status_entry_to_array(git_status_entry *entry, zval **out TSRMLS_DC)
{
zval *result, *head_to_index, *index_to_workdir;

MAKE_STD_ZVAL(result);
array_init(result);

if (entry->head_to_index) {
php_git2_diff_delta_to_array(entry->head_to_index, &head_to_index TSRMLS_CC);
} else {
MAKE_STD_ZVAL(head_to_index);
ZVAL_NULL(head_to_index);
}

if (entry->index_to_workdir) {
php_git2_diff_delta_to_array(entry->index_to_workdir, &index_to_workdir TSRMLS_CC);
} else {
MAKE_STD_ZVAL(index_to_workdir);
ZVAL_NULL(index_to_workdir);
}

add_assoc_long_ex(result, ZEND_STRS("status"), entry->status);
add_assoc_zval_ex(result, ZEND_STRS("head_to_index"), head_to_index);
add_assoc_zval_ex(result, ZEND_STRS("index_to_workdir"), index_to_workdir);

*out = result;
}

static int php_git2_git_status_cb(
const char *path, unsigned int status_flags, void *payload)
{
php_git2_t *result;
zval *param_path, *param_status_flags, *retval_ptr = NULL;
php_git2_cb_t *p = (php_git2_cb_t*)payload;
int i = 0;
long retval = 0;
GIT2_TSRMLS_SET(p->tsrm_ls)

Z_ADDREF_P(p->payload);
MAKE_STD_ZVAL(param_path);
MAKE_STD_ZVAL(param_status_flags);
ZVAL_STRING(param_path, path, 1);
ZVAL_LONG(param_status_flags, status_flags);

if (php_git2_call_function_v(p->fci, p->fcc TSRMLS_CC, &retval_ptr, 3,
&param_path, &param_status_flags, &p->payload)) {
return GIT_EUSER;
}

retval = Z_LVAL_P(retval_ptr);
zval_ptr_dtor(&retval_ptr);
return retval;
}

/* {{{ proto long git_status_foreach(resource $repo, Callable $callback, $payload)
*/
PHP_FUNCTION(git_status_foreach)
Expand All @@ -12,7 +92,7 @@ PHP_FUNCTION(git_status_foreach)
zend_fcall_info fci = empty_fcall_info;
zend_fcall_info_cache fcc = empty_fcall_info_cache;
php_git2_cb_t *cb = NULL;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
"rfz", &repo, &fci, &fcc, &payload) == FAILURE) {
return;
Expand All @@ -22,7 +102,7 @@ PHP_FUNCTION(git_status_foreach)
if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) {
RETURN_FALSE;
}
//result = git_status_foreach(PHP_GIT2_V(_repo, repository), <CHANGEME>, cb);
result = git_status_foreach(PHP_GIT2_V(_repo, repository), php_git2_git_status_cb, cb);
php_git2_cb_free(cb);
RETURN_LONG(result);
}
Expand All @@ -38,18 +118,23 @@ PHP_FUNCTION(git_status_foreach_ext)
zend_fcall_info fci = empty_fcall_info;
zend_fcall_info_cache fcc = empty_fcall_info_cache;
php_git2_cb_t *cb = NULL;
git_status_options options = GIT_STATUS_OPTIONS_INIT;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
"r<git_status_options>fz", &repo, &opts, &fci, &fcc, &payload) == FAILURE) {
"rafz", &repo, &opts, &fci, &fcc, &payload) == FAILURE) {
return;
}

ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);
php_git2_array_to_git_status_options(&options, opts TSRMLS_CC);
if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) {
RETURN_FALSE;
}
//result = git_status_foreach_ext(PHP_GIT2_V(_repo, repository), opts, <CHANGEME>, cb);
result = git_status_foreach_ext(PHP_GIT2_V(_repo, repository), &options, php_git2_git_status_cb, cb);
php_git2_cb_free(cb);
if (options.pathspec.count > 0) {
php_git2_strarray_free(&options.pathspec);
}
RETURN_LONG(result);
}
/* }}} */
Expand Down Expand Up @@ -82,15 +167,20 @@ PHP_FUNCTION(git_status_list_new)
php_git2_t *result = NULL, *_repo = NULL;
git_status_list *out = NULL;
zval *repo = NULL, *opts = NULL;
git_status_options options = GIT_STATUS_OPTIONS_INIT;
int error = 0;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
"r<git_status_options>", &repo, &opts) == FAILURE) {
"ra", &repo, &opts) == FAILURE) {
return;
}

ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);
error = git_status_list_new(&out, PHP_GIT2_V(_repo, repository), opts);
php_git2_array_to_git_status_options(&options, opts TSRMLS_CC);
error = git_status_list_new(&out, PHP_GIT2_V(_repo, repository), &options);
if (options.pathspec.count > 0) {
php_git2_strarray_free(&options.pathspec);
}
if (php_git2_check_error(error, "git_status_list_new" TSRMLS_CC)) {
RETURN_FALSE;
}
Expand Down Expand Up @@ -125,7 +215,7 @@ PHP_FUNCTION(git_status_list_entrycount)
PHP_FUNCTION(git_status_byindex)
{
const git_status_entry *result = NULL;
zval *statuslist = NULL;
zval *statuslist = NULL, *out;
php_git2_t *_statuslist = NULL;
long idx = 0;

Expand All @@ -136,7 +226,11 @@ PHP_FUNCTION(git_status_byindex)

ZEND_FETCH_RESOURCE(_statuslist, php_git2_t*, &statuslist, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);
result = git_status_byindex(PHP_GIT2_V(_statuslist, status_list), idx);
/* TODO(chobie): implement this */
if (result == NULL) {
RETURN_FALSE;
}
php_git2_git_status_entry_to_array(result, &out TSRMLS_CC);
RETURN_ZVAL(out, 0, 1);
}
/* }}} */

Expand Down Expand Up @@ -182,3 +276,11 @@ PHP_FUNCTION(git_status_should_ignore)
}
/* }}} */

PHP_FUNCTION(git_status_options_new)
{
git_status_options options = GIT_STATUS_OPTIONS_INIT;
zval *result;

php_git2_git_status_options_to_array(&options, &result TSRMLS_CC);
RETURN_ZVAL(result, 0, 1);
}
2 changes: 2 additions & 0 deletions status.h
Expand Up @@ -101,4 +101,6 @@ PHP_FUNCTION(git_status_list_free);
*/
PHP_FUNCTION(git_status_should_ignore);

PHP_FUNCTION(git_status_options_new);

#endif

0 comments on commit 516fe0a

Please sign in to comment.