My pretty neat website
git clone git://soophie.de/soso
blob: f20159b9b6823098f259e2d5abe6633606e29171 (3628 bytes)[raw]
1
#include <git2.h>2
#include "git_repo.h"3
#include "git_repo_tree.h"5
#include "../templ/duc_git_repo_tree.h"7
static orb_rc_t init(orb_module_t *self) {8
duc_git_repo_tree_t *data = self->data;9
git_repo_tree_param_list_t *param_list = self->param_list;10
if (param_list) {11
data->repo = param_list->repo;12
}13
return ORB_OK;14
}16
static int _fetch_tree_cb(const char *root, const git_tree_entry *entry_handle, void *data) {17
git_repo_tree_cb_t *handle = data;18
const char *name = git_tree_entry_name(entry_handle);19
git_filemode_t mode_handle = git_tree_entry_filemode(entry_handle);20
if (mode_handle != GIT_FILEMODE_TREE) {21
*handle->entry_list = realloc(*handle->entry_list, sizeof(git_repo_tree_entry_t) * (*handle->entry_list_len + 1));22
git_repo_tree_entry_t *entry = &(*handle->entry_list)[*handle->entry_list_len];23
memset(entry, 0, sizeof(git_repo_tree_entry_t));24
const git_oid *oid = git_tree_entry_id(entry_handle);25
char oid_str[GIT_OID_HEXSZ + 1];26
git_oid_tostr(oid_str, sizeof(oid_str), oid);27
entry->oid = strdup(oid_str);28
size_t filepath_len = strlen(root) + strlen(name);29
char filepath[filepath_len + 1];30
snprintf(filepath, sizeof(filepath), "%s%s", root, name);31
entry->name = strdup(filepath);32
entry->mode = strdup((mode_handle == GIT_FILEMODE_BLOB_EXECUTABLE) ? "-rwx-xr-x" : (mode_handle == GIT_FILEMODE_TREE) ? "d---------" : "-rw-r--r--");33
git_object_t obj_type = git_tree_entry_type(entry_handle);34
if (obj_type == GIT_OBJECT_BLOB) {35
git_object *obj_handle = NULL;36
git_tree_entry_to_object(&obj_handle, handle->repo_handle, entry_handle);37
git_blob *blob_handle = (git_blob *) obj_handle;38
entry->size = (size_t) git_blob_rawsize(blob_handle);39
git_object_free(obj_handle);40
}41
(*handle->entry_list_len)++;42
}43
return 0;44
}46
static orb_rc_t fetch(orb_module_t *self) {47
duc_git_repo_tree_t *data = self->data;48
if (!data->repo) return ORB_ERR(1);49
char *ref_oid = NULL;50
if (data->repo->ref_head) ref_oid = data->repo->ref_head->oid;51
if (data->repo->ref) ref_oid = data->repo->ref->oid;52
if (!ref_oid) return ORB_ERR(2);53
const char *spec_suffix = "^{commit}";54
size_t spec_len = strlen(ref_oid) + strlen(spec_suffix) + 1;55
char spec[spec_len];56
snprintf(spec, spec_len, "%s%s", ref_oid, spec_suffix);57
git_object *obj = NULL;58
if (git_revparse_single(&obj, data->repo->handle, spec) == 0) {59
git_commit *commit_handle = (git_commit *) obj;60
git_tree *tree_handle = NULL;61
if (git_commit_tree(&tree_handle, commit_handle) == 0) {62
git_tree_walk(tree_handle, GIT_TREEWALK_PRE, _fetch_tree_cb, &((git_repo_tree_cb_t) {63
.repo_handle = data->repo->handle,64
.entry_list = &data->entry_list,65
.entry_list_len = &data->entry_list_len,66
}));67
git_tree_free(tree_handle);68
}69
git_object_free(obj);70
}71
return ORB_OK;72
}74
static orb_rc_t render(orb_module_t *self, void *out) {75
return ORB_ERR(duc_git_repo_tree_render(out, (duc_git_repo_tree_t *) self->data));76
}78
static void cleanup(orb_module_t *self) {79
duc_git_repo_tree_t *data = self->data;80
if (data->entry_list && data->entry_list_len > 0) {81
for (size_t i = 0; i < data->entry_list_len; i++) {82
git_repo_tree_entry_t *entry = &data->entry_list[i];83
free(entry->oid);84
free(entry->name);85
free(entry->mode);86
}87
free(data->entry_list);88
data->entry_list = NULL;89
data->entry_list_len = 0;90
}91
}93
const orb_module_type_t GIT_REPO_TREE_TYPE = {94
.size = sizeof(duc_git_repo_tree_t),95
.init = init,96
.fetch = fetch,97
.render = render,98
.cleanup = cleanup,99
};