\n", fp); relpath = "../"; - printshowfile(commit); + printshowfile(ci); -errdiff: - /* TODO: print error ? */ - git_diff_stats_free(stats); - git_diff_free(diff); - git_commit_free(commit); + commitinfo_free(ci); } fprintf(fp, "
trework code, "cache" commit data in struct commitinfo - stagit - static git page generator
git clone git://src.adamsgaard.dk/stagit
Log
Files
Refs
README
LICENSE
---
commit 9c1862ccdacddee9b8a324a8d4a67d18c5ab7d93
parent 1b4f30ba2e66133139f225cb536ba2c6ed62ff36
Author: Hiltjo Posthuma 
Date:   Mon,  7 Dec 2015 23:00:07 +0100

rework code, "cache" commit data in struct commitinfo

Diffstat:
  M urmoms.c                            |     353 +++++++++++++++----------------

1 file changed, 175 insertions(+), 178 deletions(-)
---
diff --git a/urmoms.c b/urmoms.c
t@@ -11,6 +11,28 @@
 
 #include "git2.h"
 
+struct commitinfo {
+        const git_oid *id;
+
+        char oid[GIT_OID_HEXSZ + 1];
+        char parentoid[GIT_OID_HEXSZ + 1];
+
+        const git_signature *author;
+        const char *summary;
+        const char *msg;
+
+        git_diff_stats *stats;
+        git_diff       *diff;
+        git_commit     *commit;
+        git_commit     *parent;
+        git_tree       *commit_tree;
+        git_tree       *parent_tree;
+
+        size_t addcount;
+        size_t delcount;
+        size_t filecount;
+};
+
 static git_repository *repo;
 
 static const char *relpath = "";
t@@ -20,6 +42,69 @@ static char name[255];
 static char description[255];
 static int hasreadme, haslicense;
 
+void
+commitinfo_free(struct commitinfo *ci)
+{
+        if (!ci)
+                return;
+
+        /* TODO: print error ? */
+        git_diff_stats_free(ci->stats);
+        git_diff_free(ci->diff);
+        git_commit_free(ci->commit);
+}
+
+struct commitinfo *
+commitinfo_getbyoid(const git_oid *id)
+{
+        struct commitinfo *ci;
+        int error;
+
+        if (!(ci = calloc(1, sizeof(struct commitinfo))))
+                err(1, "calloc");
+
+        ci->id = id;
+        if (git_commit_lookup(&(ci->commit), repo, id))
+                goto err;
+
+        /* TODO: show tags when commit has it */
+        git_oid_tostr(ci->oid, sizeof(ci->oid), git_commit_id(ci->commit));
+        git_oid_tostr(ci->parentoid, sizeof(ci->parentoid), git_commit_parent_id(ci->commit, 0));
+
+        ci->author = git_commit_author(ci->commit);
+        ci->summary = git_commit_summary(ci->commit);
+        ci->msg = git_commit_message(ci->commit);
+
+        if ((error = git_commit_tree(&(ci->commit_tree), ci->commit)))
+                goto err; /* TODO: handle error */
+        if (!(error = git_commit_parent(&(ci->parent), ci->commit, 0))) {
+                if ((error = git_commit_tree(&(ci->parent_tree), ci->parent)))
+                        goto err;
+        } else {
+                ci->parent = NULL;
+                ci->parent_tree = NULL;
+        }
+
+        if ((error = git_diff_tree_to_tree(&(ci->diff), repo, ci->parent_tree, ci->commit_tree, NULL)))
+                goto err;
+        if (git_diff_get_stats(&(ci->stats), ci->diff))
+                goto err;
+
+        ci->addcount = git_diff_stats_insertions(ci->stats);
+        ci->delcount = git_diff_stats_deletions(ci->stats);
+        ci->filecount = git_diff_stats_files_changed(ci->stats);
+
+        /* TODO: show tag when commit has it */
+
+        return ci;
+
+err:
+        commitinfo_free(ci);
+        free(ci);
+
+        return NULL;
+}
+
 int
 writeheader(FILE *fp)
 {
t@@ -156,22 +241,23 @@ printtime(FILE *fp, const git_time *intime)
 }
 
 void
-printcommit(FILE *fp, git_commit *commit)
+writeblobhtml(FILE *fp, const git_blob *blob)
 {
-        const git_signature *sig;
-        char buf[GIT_OID_HEXSZ + 1];
-        int i, count;
-        const char *msg;
+        xmlencode(fp, git_blob_rawcontent(blob), (size_t)git_blob_rawsize(blob));
+}
 
+void
+printcommit(FILE *fp, struct commitinfo *ci)
+{
         /* TODO: show tag when commit has it */
-        git_oid_tostr(buf, sizeof(buf), git_commit_id(commit));
         fprintf(fp, "commit %s\n",
-                relpath, buf, buf);
+                relpath, ci->oid, ci->oid);
 
-        if (git_oid_tostr(buf, sizeof(buf), git_commit_parent_id(commit, 0)) && buf[0])
+        if (ci->parentoid[0])
                 fprintf(fp, "parent %s\n",
-                        relpath, buf, buf);
+                        relpath, ci->parentoid, ci->parentoid);
 
+#if 0
         if ((count = (int)git_commit_parentcount(commit)) > 1) {
                 fprintf(fp, "Merge:");
                 for (i = 0; i < count; i++) {
t@@ -181,81 +267,66 @@ printcommit(FILE *fp, git_commit *commit)
                 }
                 fputc('\n', fp);
         }
-        if ((sig = git_commit_author(commit)) != NULL) {
+#endif
+        if (ci->author) {
                 fprintf(fp, "Author: ");
-                xmlencode(fp, sig->name, strlen(sig->name));
+                xmlencode(fp, ci->author->name, strlen(ci->author->name));
                 fprintf(fp, " <email, strlen(sig->email));
+                xmlencode(fp, ci->author->email, strlen(ci->author->email));
                 fputs("\">", fp);
-                xmlencode(fp, sig->email, strlen(sig->email));
+                xmlencode(fp, ci->author->email, strlen(ci->author->email));
                 fputs(">\nDate:   ", fp);
-                printtime(fp, &sig->when);
+                printtime(fp, &(ci->author->when));
                 fputc('\n', fp);
         }
         fputc('\n', fp);
 
-        if ((msg = git_commit_message(commit)))
-                xmlencode(fp, msg, strlen(msg));
+        if (ci->msg)
+                xmlencode(fp, ci->msg, strlen(ci->msg));
+
         fputc('\n', fp);
 }
 
 void
-printshowfile(git_commit *commit)
+printshowfile(struct commitinfo *ci)
 {
-        const git_diff_delta *delta = NULL;
-        const git_diff_hunk *hunk = NULL;
-        const git_diff_line *line = NULL;
-        git_commit *parent = NULL;
-        git_tree *commit_tree = NULL, *parent_tree = NULL;
-        git_patch *patch = NULL;
-        git_diff *diff = NULL;
-        git_diff_stats *diffstats = NULL;
-        git_buf diffstatsbuf;
+        const git_diff_delta *delta;
+        const git_diff_hunk *hunk;
+        const git_diff_line *line;
+        git_patch *patch;
+        git_buf statsbuf;
+        size_t ndeltas, nhunks, nhunklines;
         FILE *fp;
-        size_t i, j, k, ndeltas, nhunks = 0, nhunklines = 0;
-        char buf[GIT_OID_HEXSZ + 1], path[PATH_MAX];
-        int error;
+        size_t i, j, k;
+        char path[PATH_MAX];
 
-        git_oid_tostr(buf, sizeof(buf), git_commit_id(commit));
-        if (!buf[0])
-                return;
-        snprintf(path, sizeof(path), "commit/%s.html", buf);
+        snprintf(path, sizeof(path), "commit/%s.html", ci->oid);
         /* check if file exists if so skip it */
         if (!access(path, F_OK))
                 return;
 
-        memset(&diffstatsbuf, 0, sizeof(diffstatsbuf));
-
         fp = efopen(path, "w+b");
         writeheader(fp);
-        printcommit(fp, commit);
+        printcommit(fp, ci);
 
-        if ((error = git_commit_tree(&commit_tree, commit)))
-                goto err;
-        if (!(error = git_commit_parent(&parent, commit, 0))) {
-                if ((error = git_commit_tree(&parent_tree, parent)))
-                        goto err; /* TODO: handle error */
-        } else {
-                parent = NULL;
-                parent_tree = NULL;
-        }
-        if ((error = git_diff_tree_to_tree(&diff, repo, parent_tree, commit_tree, NULL)))
-                goto err;
+        memset(&statsbuf, 0, sizeof(statsbuf));
 
         /* diff stat */
-        if (!git_diff_get_stats(&diffstats, diff)) {
-                if (!git_diff_stats_to_buf(&diffstatsbuf, diffstats,
+        if (ci->stats) {
+                if (!git_diff_stats_to_buf(&statsbuf, ci->stats,
                     GIT_DIFF_STATS_FULL | GIT_DIFF_STATS_SHORT, 80)) {
-                        fprintf(fp, "Diffstat:\n");
-                        fputs(diffstatsbuf.ptr, fp);
+                        if (statsbuf.ptr && statsbuf.ptr[0]) {
+                                fprintf(fp, "Diffstat:\n");
+                                fputs(statsbuf.ptr, fp);
+                        }
                 }
-                git_diff_stats_free(diffstats);
         }
+
         fputs("
", fp); - ndeltas = git_diff_num_deltas(diff); + ndeltas = git_diff_num_deltas(ci->diff); for (i = 0; i < ndeltas; i++) { - if (git_patch_from_diff(&patch, diff, i)) { + if (git_patch_from_diff(&patch, ci->diff, i)) { git_patch_free(patch); break; /* TODO: handle error */ } t@@ -265,26 +336,6 @@ printshowfile(git_commit *commit) relpath, delta->old_file.path, delta->old_file.path, relpath, delta->new_file.path, delta->new_file.path); - /* TODO: "new file mode ". */ - /* TODO: add indexfrom...indexto + flags */ - -#if 0 - fputs("--- ", fp); - if (delta->status & GIT_DELTA_ADDED) - fputs("/dev/null", fp); - else - fprintf(fp, "a/%s", - relpath, delta->old_file.path, delta->old_file.path); - - fputs("\n+++ ", fp); - if (delta->status & GIT_DELTA_DELETED) - fputs("/dev/null", fp); - else - fprintf(fp, "b/%s", - relpath, delta->new_file.path, delta->new_file.path); - fputs("\n", fp); -#endif - /* check binary data */ if (delta->flags & GIT_DIFF_FLAG_BINARY) { fputs("Binary files differ\n", fp); t@@ -317,32 +368,20 @@ printshowfile(git_commit *commit) } git_patch_free(patch); } - git_diff_free(diff); + git_buf_free(&statsbuf); writefooter(fp); fclose(fp); return; - -err: - git_buf_free(&diffstatsbuf); - fclose(fp); } int writelog(FILE *fp) { + struct commitinfo *ci; git_revwalk *w = NULL; git_oid id; - git_commit *commit = NULL; - const git_signature *author; - git_diff_stats *stats = NULL; - git_tree *commit_tree = NULL, *parent_tree = NULL; - git_commit *parent = NULL; - git_diff *diff = NULL; - size_t nfiles, ndel, nadd; - const char *summary; - char buf[GIT_OID_HEXSZ + 1]; - int error, ret = 0; + int ret = 0; mkdir("commit", 0755); t@@ -355,67 +394,37 @@ writelog(FILE *fp) while (!git_revwalk_next(&id, w)) { relpath = ""; - if (git_commit_lookup(&commit, repo, &id)) { - ret = 1; - goto err; - } - if ((error = git_commit_tree(&commit_tree, commit))) - goto errdiff; /* TODO: handle error */ - if (!(error = git_commit_parent(&parent, commit, 0))) { - if ((error = git_commit_tree(&parent_tree, parent))) - goto errdiff; - } else { - parent = NULL; - parent_tree = NULL; - } - - if ((error = git_diff_tree_to_tree(&diff, repo, parent_tree, commit_tree, NULL))) - goto errdiff; - if (git_diff_get_stats(&stats, diff)) - goto errdiff; - - git_oid_tostr(buf, sizeof(buf), git_commit_id(commit)); - - ndel = git_diff_stats_deletions(stats); - nadd = git_diff_stats_insertions(stats); - nfiles = git_diff_stats_files_changed(stats); - - /* TODO: show tag when commit has it */ - - /* TODO: collect stats per author and make stats.html page */ - author = git_commit_author(commit); - summary = git_commit_summary(commit); + if (!(ci = commitinfo_getbyoid(&id))) + break; fputs("
", fp); - if (summary) { - fprintf(fp, "", relpath, buf); - xmlencode(fp, summary, strlen(summary)); + if (ci->summary) { + fprintf(fp, "", relpath, ci->oid); + xmlencode(fp, ci->summary, strlen(ci->summary)); fputs("", fp); } fputs("", fp); - if (author) - xmlencode(fp, author->name, strlen(author->name)); + if (ci->author) + xmlencode(fp, ci->author->name, strlen(ci->author->name)); + fputs("", fp); - printtime(fp, &author->when); + if (ci->author) + printtime(fp, &(ci->author->when)); fputs("", fp); - fprintf(fp, "%zu", nfiles); + fprintf(fp, "%zu", ci->filecount); fputs("", fp); - fprintf(fp, "+%zu", nadd); + fprintf(fp, "+%zu", ci->addcount); fputs("", fp); - fprintf(fp, "-%zu", ndel); + fprintf(fp, "-%zu", ci->delcount); fputs("
"); -err: + git_revwalk_free(w); relpath = ""; t@@ -423,38 +432,28 @@ err: } void -printcommitatom(FILE *fp, git_commit *commit) +printcommitatom(FILE *fp, struct commitinfo *ci) { - const git_signature *sig; - char buf[GIT_OID_HEXSZ + 1]; - int i, count; - const char *msg, *summary; - fputs("\n", fp); - /* TODO: show tag when commit has it */ - git_oid_tostr(buf, sizeof(buf), git_commit_id(commit)); - fprintf(fp, "%s\n", buf); - - sig = git_commit_author(commit); - - if (sig) { + fprintf(fp, "%s\n", ci->oid); + if (ci->author) { fputs("", fp); - printtimez(fp, &sig->when); + printtimez(fp, &(ci->author->when)); fputs("\n", fp); } - - if ((summary = git_commit_summary(commit))) { + if (ci->summary) { fputs("", fp); - xmlencode(fp, summary, strlen(summary)); + xmlencode(fp, ci->summary, strlen(ci->summary)); fputs("\n", fp); } fputs("", fp); - fprintf(fp, "commit %s\n", buf); - if (git_oid_tostr(buf, sizeof(buf), git_commit_parent_id(commit, 0)) && buf[0]) - fprintf(fp, "parent %s\n", buf); + fprintf(fp, "commit %s\n", ci->oid); + if (ci->parentoid[0]) + fprintf(fp, "parent %s\n", ci->parentoid); +#if 0 if ((count = (int)git_commit_parentcount(commit)) > 1) { fprintf(fp, "Merge:"); for (i = 0; i < count; i++) { t@@ -463,25 +462,26 @@ printcommitatom(FILE *fp, git_commit *commit) } fputc('\n', fp); } +#endif - if (sig) { + if (ci->author) { fprintf(fp, "Author: "); - xmlencode(fp, sig->name, strlen(sig->name)); + xmlencode(fp, ci->author->name, strlen(ci->author->name)); fprintf(fp, " <"); - xmlencode(fp, sig->email, strlen(sig->email)); + xmlencode(fp, ci->author->email, strlen(ci->author->email)); fprintf(fp, ">\nDate: "); - printtime(fp, &sig->when); + printtime(fp, &(ci->author->when)); } fputc('\n', fp); - if ((msg = git_commit_message(commit))) - xmlencode(fp, msg, strlen(msg)); + if (ci->msg) + xmlencode(fp, ci->msg, strlen(ci->msg)); fputs("\n\n", fp); - if (sig) { + if (ci->author) { fputs("", fp); - xmlencode(fp, sig->name, strlen(sig->name)); + xmlencode(fp, ci->author->name, strlen(ci->author->name)); fputs("\n", fp); - xmlencode(fp, sig->email, strlen(sig->email)); + xmlencode(fp, ci->author->email, strlen(ci->author->email)); fputs("\n\n", fp); } fputs("\n", fp); t@@ -490,9 +490,9 @@ printcommitatom(FILE *fp, git_commit *commit) int writeatom(FILE *fp) { + struct commitinfo *ci; git_revwalk *w = NULL; git_oid id; - git_commit *c = NULL; size_t i, m = 100; /* max */ fputs("\n", fp); t@@ -507,10 +507,10 @@ writeatom(FILE *fp) git_revwalk_push_head(w); for (i = 0; i < m && !git_revwalk_next(&id, w); i++) { - if (git_commit_lookup(&c, repo, &id)) - return 1; /* TODO: error */ - printcommitatom(fp, c); - git_commit_free(c); + if (!(ci = commitinfo_getbyoid(&id))) + break; + printcommitatom(fp, ci); + commitinfo_free(ci); } git_revwalk_free(w); t@@ -522,14 +522,16 @@ writeatom(FILE *fp) int writefiles(FILE *fp) { - git_index *index; const git_index_entry *entry; + git_index *index; size_t count, i; - git_repository_index(&index, repo); + fputs("\n" + "\n" + "\n", fp); + git_repository_index(&index, repo); count = git_index_entrycount(index); - fputs("
ModeNameSize
\n\n\n", fp); for (i = 0; i < count; i++) { entry = git_index_get_byindex(index, i); t@@ -543,17 +545,12 @@ writefiles(FILE *fp) fprintf(fp, "%" PRIu64, entry->file_size); fputs("\n", fp); } + fputs("
ModeNameSize
", fp); return 0; } -void -writeblobhtml(FILE *fp, const git_blob *blob) -{ - xmlencode(fp, git_blob_rawcontent(blob), (size_t)git_blob_rawsize(blob)); -} - int main(int argc, char *argv[]) {