stagit

git site generator
Contents

sort branches and tags by time (descending)

In general version tags are done in chronological order, so this will have a
better sorting for tagged (versioned) releases.

Request from Caltlgin Stsodaat and others, thanks!

Hiltjo Posthuma hiltjo@codemadness.org

commit: e654152 parent: d01987f
1 files changed, 92 insertions(+), 72 deletions(-)
Mstagit.c+92-72
M · stagit.c +92, -72
 1@@ -48,6 +48,12 @@ struct commitinfo {
 2 size_t ndeltas;
 3 };
 4
 5+/* reference and associated data for sorting */
 6+struct referenceinfo {
 7+ struct git_reference
*ref;
 8+ struct commitinfo
*ci;
 9+};
 10+
 11 static git_repository *repo;
 12
 13 static const
char *relpath = "";
 14@@ -938,113 +944,127 @@ writefiles(FILE *fp, const git_oid *id)
 15 int
 16 refs_cmp(const
void *v1, const void *v2)
 17 {
 18- git_reference *r1 = (*(git_reference **)v1);
 19- git_reference *r2 =
(*(git_reference **)v2);
 20+ struct referenceinfo
*r1 = (struct referenceinfo *)v1;
 21+ struct referenceinfo
*r2 = (struct referenceinfo *)v2;
 22+ time_t t1, t2;
 23 int r;
 24
 25- if ((r = git_reference_is_branch(r1) - git_reference_is_branch(r2)))
 26+ if ((r =
git_reference_is_tag(r1->ref) - git_reference_is_tag(r2->ref)))
 27+ return r;
 28+
 29+ t1 =
r1->ci->author ? r1->ci->author->when.time : 0;
 30+ t2 =
r2->ci->author ? r2->ci->author->when.time : 0;
 31+ if ((r = t1 >
t2 ? -1 : (t1 == t2 ? 0 : 1)))
 32 return r;
 33
 34- return strcmp(git_reference_shorthand(r1),
 35-
git_reference_shorthand(r2));
 36+ return
strcmp(git_reference_shorthand(r1->ref),
 37+
git_reference_shorthand(r2->ref));
 38 }
 39
 40 int
 41 writerefs(FILE
*fp)
 42 {
 43+ struct referenceinfo *ris = NULL;
 44 struct commitinfo *ci;
 45 const git_oid
*id = NULL;
 46 git_object *obj
= NULL;
 47 git_reference
*dref = NULL, *r, *ref = NULL;
 48
git_reference_iterator *it = NULL;
 49- git_reference **refs = NULL;
 50 size_t count, i, j, refcount;
 51 const char
*titles[] = { "Branches", "Tags" };
 52 const char
*ids[] = { "branches", "tags" };
 53- const char *name;
 54+ const char *s;
 55
 56 if
(git_reference_iterator_new(&it, repo))
 57 return -1;
 58
 59- for (refcount = 0; !git_reference_next(&ref, it); refcount++) {
 60- if (!(refs =
reallocarray(refs, refcount + 1, sizeof(git_reference *))))
 61- err(1,
"realloc");
 62- refs[refcount] = ref;
 63- }
 64-
git_reference_iterator_free(it);
 65-
 66- /* sort by type then
shorthand name */
 67- qsort(refs, refcount,
sizeof(git_reference *), refs_cmp);
 68-
 69- for (j = 0; j
< 2; j++) {
 70- for (i = 0, count =
0; i < refcount; i++) {
 71- if
(!(git_reference_is_branch(refs[i]) && j == 0) &&
 72-
!(git_reference_is_tag(refs[i]) && j == 1))
 73- continue;
 74+ for (refcount = 0;
!git_reference_next(&ref, it); ) {
 75+ if
(!git_reference_is_branch(ref) && !git_reference_is_tag(ref)) {
 76+
git_reference_free(ref);
 77+ ref = NULL;
 78+ continue;
 79+ }
 80
 81- switch (git_reference_type(refs[i])) {
 82- case
GIT_REF_SYMBOLIC:
 83- if
(git_reference_resolve(&dref, refs[i]))
 84- goto err;
 85- r = dref;
 86- break;
 87- case GIT_REF_OID:
 88- r = refs[i];
 89- break;
 90- default:
 91- continue;
 92- }
 93- if
(!git_reference_target(r) ||
 94-
git_reference_peel(&obj, r, GIT_OBJ_ANY))
 95+ switch
(git_reference_type(ref)) {
 96+ case
GIT_REF_SYMBOLIC:
 97+ if
(git_reference_resolve(&dref, ref))
 98 goto err;
 99- if (!(id = git_object_id(obj)))
100- goto err;
101- if (!(ci =
commitinfo_getbyoid(id)))
102- break;
103+ r = dref;
104+ break;
105+ case GIT_REF_OID:
106+ r = ref;
107+ break;
108+ default:
109+ continue;
110+ }
111+ if
(!git_reference_target(r) ||
112+
git_reference_peel(&obj, r, GIT_OBJ_ANY))
113+ goto err;
114+ if (!(id =
git_object_id(obj)))
115+ goto err;
116+ if (!(ci =
commitinfo_getbyoid(id)))
117+ break;
118
119- /* print header if it has an entry (first). */
120- if (++count == 1) {
121- fprintf(fp,
"<h2>%s</h2><table id=\"%s\">"
122-
"<thead>\n<tr><td><b>Name</b></td>"
123-
"<td><b>Last commit date</b></td>"
124-
"<td><b>Author</b></td>\n</tr>\n"
125-
"</thead><tbody>\n",
126- titles[j], ids[j]);
127- }
128+ if (!(ris =
reallocarray(ris, refcount + 1, sizeof(*ris))))
129+ err(1,
"realloc");
130+ ris[refcount].ci =
ci;
131+ ris[refcount].ref =
r;
132+ refcount++;
133
134- relpath = "";
135- name =
git_reference_shorthand(r);
136+ git_object_free(obj);
137+ obj = NULL;
138+
git_reference_free(dref);
139+ dref = NULL;
140+ }
141+
git_reference_iterator_free(it);
142
143- fputs("<tr><td>", fp);
144- xmlencode(fp, name,
strlen(name));
145-
fputs("</td><td>", fp);
146- if
(ci->author)
147- printtimeshort(fp,
&(ci->author->when));
148-
fputs("</td><td>", fp);
149- if
(ci->author)
150- xmlencode(fp,
ci->author->name, strlen(ci->author->name));
151-
fputs("</td></tr>\n", fp);
152+ /* sort by type, date
then shorthand name */
153+ qsort(ris, refcount,
sizeof(*ris), refs_cmp);
154
155- relpath = "../";
156+ for (i = 0, j = 0,
count = 0; i < refcount; i++) {
157+ if (j == 0
&& git_reference_is_tag(ris[i].ref)) {
158+ if (count)
159+
fputs("</tbody></table><br/>\n", fp);
160+ count = 0;
161+ j = 1;
162+ }
163
164- commitinfo_free(ci);
165- git_object_free(obj);
166- obj = NULL;
167-
git_reference_free(dref);
168- dref = NULL;
169+ /* print header if it
has an entry (first). */
170+ if (++count == 1) {
171+ fprintf(fp,
"<h2>%s</h2><table id=\"%s\">"
172+
"<thead>\n<tr><td><b>Name</b></td>"
173+
"<td><b>Last commit date</b></td>"
174+
"<td><b>Author</b></td>\n</tr>\n"
175+
"</thead><tbody>\n",
176+ titles[j], ids[j]);
177 }
178- /* table footer */
179- if (count)
180-
fputs("</tbody></table><br/>", fp);
181+
182+ ci = ris[i].ci;
183+ s =
git_reference_shorthand(ris[i].ref);
184+
185+
fputs("<tr><td>", fp);
186+ xmlencode(fp, s,
strlen(s));
187+
fputs("</td><td>", fp);
188+ if
(ci->author)
189+ printtimeshort(fp,
&(ci->author->when));
190+
fputs("</td><td>", fp);
191+ if
(ci->author)
192+ xmlencode(fp,
ci->author->name, strlen(ci->author->name));
193+
fputs("</td></tr>\n", fp);
194 }
195+ /* table footer */
196+ if (count)
197+
fputs("</tbody></table><br/>\n", fp);
198
199 err:
200
git_object_free(obj);
201
git_reference_free(dref);
202
203- for (i = 0; i < refcount; i++)
204-
git_reference_free(refs[i]);
205- free(refs);
206+ for (i = 0; i
< refcount; i++) {
207+
commitinfo_free(ris[i].ci);
208+
git_reference_free(ris[i].ref);
209+ }
210+ free(ris);
211
212 return 0;
213 }