1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
/*-
* SPDX-License-Identifier: AGPL-3.0-only
* SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu <https://runxiyu.org>
*/
#include "x.h"
int
cmd1(git_repository *repo, struct bare_writer *writer)
{
/* HEAD tree */
git_object *obj = NULL;
int err = git_revparse_single(&obj, repo, "HEAD^{tree}");
if (err != 0) {
bare_put_uint(writer, 4);
return -1;
}
git_tree *tree = (git_tree *) obj;
/* README */
git_tree_entry *entry = NULL;
err = git_tree_entry_bypath(&entry, tree, "README.md");
if (err != 0) {
bare_put_uint(writer, 5);
git_tree_free(tree);
return -1;
}
git_otype objtype = git_tree_entry_type(entry);
if (objtype != GIT_OBJECT_BLOB) {
bare_put_uint(writer, 6);
git_tree_entry_free(entry);
git_tree_free(tree);
return -1;
}
git_object *obj2 = NULL;
err = git_tree_entry_to_object(&obj2, repo, entry);
if (err != 0) {
bare_put_uint(writer, 7);
git_tree_entry_free(entry);
git_tree_free(tree);
return -1;
}
git_blob *blob = (git_blob *) obj2;
const void *content = git_blob_rawcontent(blob);
if (content == NULL) {
bare_put_uint(writer, 8);
git_blob_free(blob);
git_tree_entry_free(entry);
git_tree_free(tree);
return -1;
}
bare_put_uint(writer, 0);
bare_put_data(writer, content, git_blob_rawsize(blob));
/* Commits */
git_revwalk *walker = NULL;
if (git_revwalk_new(&walker, repo) != 0) {
bare_put_uint(writer, 9);
git_blob_free(blob);
git_tree_entry_free(entry);
git_tree_free(tree);
return -1;
}
if (git_revwalk_push_head(walker) != 0) {
bare_put_uint(writer, 9);
git_revwalk_free(walker);
git_blob_free(blob);
git_tree_entry_free(entry);
git_tree_free(tree);
return -1;
}
int count = 0;
git_oid oid;
while (count < 3 && git_revwalk_next(&oid, walker) == 0) {
git_commit *commit = NULL;
if (git_commit_lookup(&commit, repo, &oid) != 0)
break;
const char *msg = git_commit_summary(commit);
const git_signature *author = git_commit_author(commit);
/* ID */
bare_put_data(writer, oid.id, GIT_OID_RAWSZ);
/* Title */
size_t msg_len = msg ? strlen(msg) : 0;
bare_put_data(writer, (const uint8_t *)(msg ? msg : ""), msg_len);
/* Author's name */
const char *author_name = author ? author->name : "";
bare_put_data(writer, (const uint8_t *)author_name, strlen(author_name));
/* Author's email */
const char *author_email = author ? author->email : "";
bare_put_data(writer, (const uint8_t *)author_email, strlen(author_email));
/* Author's date */
/* TODO: Pass the integer instead of a string */
time_t time = git_commit_time(commit);
char timebuf[64];
struct tm *tm = localtime(&time);
if (tm)
strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", tm);
else
strcpy(timebuf, "unknown");
bare_put_data(writer, (const uint8_t *)timebuf, strlen(timebuf));
git_commit_free(commit);
count++;
}
git_revwalk_free(walker);
git_blob_free(blob);
git_tree_entry_free(entry);
git_tree_free(tree);
return 0;
}
|