so://phie

soso

My pretty neat website
git clone git://soophie.de/soso

blob: 08298702af31c668a9ca50173a18b63503963534 (3998 bytes)[raw]

1#include <buf.h>

2#include <git2/diff.h>

3#include "git_repo.h"

4#include "git_repo_commit.h"

5

6#include "../templ/duc_git_repo_commit.h"

7

8static orb_rc_t fetch(orb_module_t *self) {

9 duc_git_repo_commit_t *data = self->data;

10 git_repo_commit_param_list_t *param_list = self->param_list;

11 if (!param_list) return ORB_FATAL(1);

12 if (!param_list->repo) return ORB_FATAL(2);

13 if (!param_list->repo->flag_oid) return ORB_FATAL(3);

14 data->repo = param_list->repo;

15 git_oid commit_oid;

16 if (git_oid_fromstr(&commit_oid, data->repo->flag_oid) != 0) return ORB_FATAL(4);

17 git_commit *commit_handle = NULL;

18 git_commit *parent_commit_handle = NULL;

19 git_commit_lookup(&commit_handle, data->repo->handle, &commit_oid);

20 data->commit = calloc(1, sizeof(git_repo_commit_t));

21 git_repo_commit_t *commit = data->commit;

22 commit->oid = strdup(data->repo->flag_oid);

23 commit->message = strdup(git_commit_message(commit_handle));

24 commit->summary = strdup(git_commit_summary(commit_handle));

25 const char *body = git_commit_body(commit_handle);

26 if (body) commit->body = strdup(body);

27 commit->author_name = strdup(git_commit_author(commit_handle)->name);

28 commit->author_email = strdup(git_commit_author(commit_handle)->email);

29 commit->time = (time_t) git_commit_time(commit_handle);

30 if (git_commit_parentcount(commit_handle) > 0) {

31 git_commit_parent(&parent_commit_handle, commit_handle, 0);

32 const git_oid *parent_oid = git_commit_id(parent_commit_handle);

33 data->parent_commit_oid = malloc(sizeof(char) * (GIT_OID_HEXSZ + 1));

34 git_oid_tostr(data->parent_commit_oid, GIT_OID_HEXSZ + 1, parent_oid);

35 }

36 git_tree *tree_handle = NULL;

37 git_tree *parent_tree_handle = NULL;

38 git_commit_tree(&tree_handle, commit_handle);

39 if (parent_commit_handle != NULL) {

40 git_commit_tree(&parent_tree_handle, parent_commit_handle);

41 }

42 git_diff *diff_handle = NULL;

43 git_diff_tree_to_tree(&diff_handle, data->repo->handle, parent_tree_handle, tree_handle, NULL);

44 size_t num_deltas = git_diff_num_deltas(diff_handle);

45 buf_t out = BUF_NULL;

46 for (size_t i = 0; i < num_deltas; i++) {

47 git_patch *patch_handle = NULL;

48 git_patch_from_diff(&patch_handle, diff_handle, i);

49 git_buf buf_handle = GIT_BUF_INIT_CONST(NULL, 0);

50 git_patch_to_buf(&buf_handle, patch_handle);

51 buf_write_len(&out, buf_handle.ptr, buf_handle.size);

52 buf_write(&out, "\n\n");

53 git_buf_dispose(&buf_handle);

54 git_patch_free(patch_handle);

55 }

56 buf_write_len(&out, "\0", 1);

57 // git_diff_stats *stats_handle = NULL;

58 // if (git_diff_get_stats(&stats_handle, diff_handle)) {

59 // size_t files_changed = git_diff_stats_files_changed(stats_handle);

60 // size_t insertions = git_diff_stats_insertions(stats_handle);

61 // size_t deletions = git_diff_stats_deletions(stats_handle);

62 // git_diff_stats_free(stats_handle);

63 // }

64 git_diff_free(diff_handle);

65 git_tree_free(tree_handle);

66 if (parent_tree_handle) {

67 git_tree_free(parent_tree_handle);

68 }

69 git_commit_free(commit_handle);

70 if (parent_commit_handle) {

71 git_commit_free(parent_commit_handle);

72 }

73 data->diff = (char *) out.bytes;

74 return ORB_OK;

75}

76

77static orb_rc_t render(orb_module_t *self, void *out) {

78 return ORB_ERR(duc_git_repo_commit_render(out, (duc_git_repo_commit_t *) self->data));

79}

80

81static void cleanup(orb_module_t *self) {

82 duc_git_repo_commit_t *data = self->data;

83 if (data->commit) {

84 git_repo_commit_t *commit = data->commit;

85 free(commit->oid);

86 free(commit->message);

87 free(commit->summary);

88 if (commit->body) free(commit->body);

89 free(commit->author_name);

90 free(commit->author_email);

91 free(commit);

92 commit = NULL;

93 }

94 if (data->parent_commit_oid) {

95 free(data->parent_commit_oid);

96 data->parent_commit_oid = NULL;

97 }

98 if (data->diff) {

99 free(data->diff);

100 data->diff = NULL;

101 }

102}

103

104const orb_module_type_t GIT_REPO_COMMIT_TYPE = {

105 .size = sizeof(duc_git_repo_commit_t),

106 .fetch = fetch,

107 .render = render,

108.cleanup = cleanup,

109};