stagit

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 67d0cff9152866b00ff4bddd9cbf5b65baaff0f1
parent 67e5e6c5e74117b478c150480c282a03543fe887
Author: JP <JP@JP.com>
Date:   Sun, 21 Nov 2021 20:14:14 +0000

Updated stagit and stagit-index to work with this server setup

added .gitignore

Diffstat:
A.gitignore | 3+++
Mstagit-index.c | 30++++--------------------------
Mstagit.c | 177+++++++++++++++++++++++++++-----------------------------------------------------
3 files changed, 66 insertions(+), 144 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1,3 @@ +stagit +stagit-index +*.o diff --git a/stagit-index.c b/stagit-index.c @@ -28,28 +28,6 @@ joinpath(char *buf, size_t bufsiz, const char *path, const char *path2) path, path[0] && path[strlen(path) - 1] != '/' ? "/" : "", path2); } -/* Percent-encode, see RFC3986 section 2.1. */ -void -percentencode(FILE *fp, const char *s, size_t len) -{ - static char tab[] = "0123456789ABCDEF"; - unsigned char uc; - size_t i; - - for (i = 0; *s && i < len; s++, i++) { - uc = *s; - /* NOTE: do not encode '/' for paths */ - if (uc < '/' || uc >= 127 || (uc >= ':' && uc <= '@') || - uc == '[' || uc == ']') { - putc('%', fp); - putc(tab[(uc >> 4) & 0x0f], fp); - putc(tab[uc & 0x0f], fp); - } else { - putc(uc, fp); - } - } -} - /* Escape characters below as HTML 2.0 / XML 1.0. */ void xmlencode(FILE *fp, const char *s, size_t len) @@ -63,7 +41,7 @@ xmlencode(FILE *fp, const char *s, size_t len) case '\'': fputs("&#39;" , fp); break; case '&': fputs("&amp;", fp); break; case '"': fputs("&quot;", fp); break; - default: putc(*s, fp); + default: fputc(*s, fp); } } } @@ -88,13 +66,12 @@ writeheader(FILE *fp) fputs("<!DOCTYPE html>\n" "<html>\n<head>\n" "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n" - "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n" "<title>", fp); xmlencode(fp, description, strlen(description)); fprintf(fp, "</title>\n<link rel=\"icon\" type=\"image/png\" href=\"%sfavicon.png\" />\n", relpath); fprintf(fp, "<link rel=\"stylesheet\" type=\"text/css\" href=\"%sstyle.css\" />\n", relpath); fputs("</head>\n<body>\n", fp); - fprintf(fp, "<table>\n<tr><td><img src=\"%slogo.png\" alt=\"\" width=\"32\" height=\"32\" /></td>\n" + fprintf(fp, "<table>\n<tr><td><img src=\"%srepo.jpg\" alt=\"\" width=\"32\" height=\"32\" /></td>\n" "<td><span class=\"desc\">", relpath); xmlencode(fp, description, strlen(description)); fputs("</span></td></tr><tr><td></td><td>\n" @@ -123,6 +100,7 @@ writelog(FILE *fp) git_revwalk_new(&w, repo); git_revwalk_push_head(w); + git_revwalk_simplify_first_parent(w); if (git_revwalk_next(&id, w) || git_commit_lookup(&commit, repo, &id)) { @@ -140,7 +118,7 @@ writelog(FILE *fp) *p = '\0'; fputs("<tr><td><a href=\"", fp); - percentencode(fp, stripped_name, strlen(stripped_name)); + xmlencode(fp, stripped_name, strlen(stripped_name)); fputs("/log.html\">", fp); xmlencode(fp, stripped_name, strlen(stripped_name)); fputs("</a></td><td>", fp); diff --git a/stagit.c b/stagit.c @@ -16,8 +16,6 @@ #include "compat.h" -#define LEN(s) (sizeof(s)/sizeof(*s)) - struct deltainfo { git_patch *patch; @@ -58,7 +56,6 @@ struct referenceinfo { static git_repository *repo; -static const char *baseurl = ""; /* base URL to make absolute RSS/Atom URI */ static const char *relpath = ""; static const char *repodir; @@ -71,7 +68,7 @@ static char *licensefiles[] = { "HEAD:LICENSE", "HEAD:LICENSE.md", "HEAD:COPYING static char *license; static char *readmefiles[] = { "HEAD:README", "HEAD:README.md" }; static char *readme; -static long long nlogcommits = -1; /* -1 indicates not used */ +static long long nlogcommits = -1; /* < 0 indicates not used */ /* cache */ static git_oid lastoid; @@ -254,7 +251,8 @@ err: int refs_cmp(const void *v1, const void *v2) { - const struct referenceinfo *r1 = v1, *r2 = v2; + struct referenceinfo *r1 = (struct referenceinfo *)v1; + struct referenceinfo *r2 = (struct referenceinfo *)v2; time_t t1, t2; int r; @@ -349,38 +347,16 @@ err: } FILE * -efopen(const char *filename, const char *flags) +efopen(const char *name, const char *flags) { FILE *fp; - if (!(fp = fopen(filename, flags))) - err(1, "fopen: '%s'", filename); + if (!(fp = fopen(name, flags))) + err(1, "fopen: '%s'", name); return fp; } -/* Percent-encode, see RFC3986 section 2.1. */ -void -percentencode(FILE *fp, const char *s, size_t len) -{ - static char tab[] = "0123456789ABCDEF"; - unsigned char uc; - size_t i; - - for (i = 0; *s && i < len; s++, i++) { - uc = *s; - /* NOTE: do not encode '/' for paths */ - if (uc < '/' || uc >= 127 || (uc >= ':' && uc <= '@') || - uc == '[' || uc == ']') { - putc('%', fp); - putc(tab[(uc >> 4) & 0x0f], fp); - putc(tab[uc & 0x0f], fp); - } else { - putc(uc, fp); - } - } -} - /* Escape characters below as HTML 2.0 / XML 1.0. */ void xmlencode(FILE *fp, const char *s, size_t len) @@ -394,27 +370,7 @@ xmlencode(FILE *fp, const char *s, size_t len) case '\'': fputs("&#39;", fp); break; case '&': fputs("&amp;", fp); break; case '"': fputs("&quot;", fp); break; - default: putc(*s, fp); - } - } -} - -/* Escape characters below as HTML 2.0 / XML 1.0, ignore printing '\r', '\n' */ -void -xmlencodeline(FILE *fp, const char *s, size_t len) -{ - size_t i; - - for (i = 0; *s && i < len; s++, i++) { - switch(*s) { - case '<': fputs("&lt;", fp); break; - case '>': fputs("&gt;", fp); break; - case '\'': fputs("&#39;", fp); break; - case '&': fputs("&amp;", fp); break; - case '"': fputs("&quot;", fp); break; - case '\r': break; /* ignore CR */ - case '\n': break; /* ignore LF */ - default: putc(*s, fp); + default: fputc(*s, fp); } } } @@ -492,7 +448,6 @@ writeheader(FILE *fp, const char *title) fputs("<!DOCTYPE html>\n" "<html>\n<head>\n" "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n" - "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n" "<title>", fp); xmlencode(fp, title, strlen(title)); if (title[0] && strippedname[0]) @@ -502,15 +457,13 @@ writeheader(FILE *fp, const char *title) fputs(" - ", fp); xmlencode(fp, description, strlen(description)); fprintf(fp, "</title>\n<link rel=\"icon\" type=\"image/png\" href=\"%sfavicon.png\" />\n", relpath); - fputs("<link rel=\"alternate\" type=\"application/atom+xml\" title=\"", fp); - xmlencode(fp, name, strlen(name)); - fprintf(fp, " Atom Feed\" href=\"%satom.xml\" />\n", relpath); - fputs("<link rel=\"alternate\" type=\"application/atom+xml\" title=\"", fp); - xmlencode(fp, name, strlen(name)); - fprintf(fp, " Atom Feed (tags)\" href=\"%stags.xml\" />\n", relpath); + fprintf(fp, "<link rel=\"alternate\" type=\"application/atom+xml\" title=\"%s Atom Feed\" href=\"%satom.xml\" />\n", + name, relpath); + fprintf(fp, "<link rel=\"alternate\" type=\"application/atom+xml\" title=\"%s Atom Feed (tags)\" href=\"%stags.xml\" />\n", + name, relpath); fprintf(fp, "<link rel=\"stylesheet\" type=\"text/css\" href=\"%sstyle.css\" />\n", relpath); fputs("</head>\n<body>\n<table><tr><td>", fp); - fprintf(fp, "<a href=\"../%s\"><img src=\"%slogo.png\" alt=\"\" width=\"32\" height=\"32\" /></a>", + fprintf(fp, "<a href=\"../%s\"><img src=\"%srepo.jpg\" alt=\"\" width=\"32\" height=\"32\" /></a>", relpath, relpath); fputs("</td><td><h1>", fp); xmlencode(fp, strippedname, strlen(strippedname)); @@ -519,7 +472,7 @@ writeheader(FILE *fp, const char *title) fputs("</span></td></tr>", fp); if (cloneurl[0]) { fputs("<tr class=\"url\"><td></td><td>git clone <a href=\"", fp); - xmlencode(fp, cloneurl, strlen(cloneurl)); /* not percent-encoded */ + xmlencode(fp, cloneurl, strlen(cloneurl)); fputs("\">", fp); xmlencode(fp, cloneurl, strlen(cloneurl)); fputs("</a></td></tr>", fp); @@ -546,31 +499,30 @@ writefooter(FILE *fp) fputs("</div>\n</body>\n</html>\n", fp); } -size_t +int writeblobhtml(FILE *fp, const git_blob *blob) { - size_t n = 0, i, len, prev; - const char *nfmt = "<a href=\"#l%zu\" class=\"line\" id=\"l%zu\">%7zu</a> "; + size_t n = 0, i, prev; + const char *nfmt = "<a href=\"#l%d\" class=\"line\" id=\"l%d\">%7d</a> "; const char *s = git_blob_rawcontent(blob); + git_off_t len = git_blob_rawsize(blob); - len = git_blob_rawsize(blob); fputs("<pre id=\"blob\">\n", fp); if (len > 0) { - for (i = 0, prev = 0; i < len; i++) { + for (i = 0, prev = 0; i < (size_t)len; i++) { if (s[i] != '\n') continue; n++; fprintf(fp, nfmt, n, n, n); - xmlencodeline(fp, &s[prev], i - prev + 1); - putc('\n', fp); + xmlencode(fp, &s[prev], i - prev + 1); prev = i + 1; } /* trailing data */ if ((len - prev) > 0) { n++; fprintf(fp, nfmt, n, n, n); - xmlencodeline(fp, &s[prev], len - prev); + xmlencode(fp, &s[prev], len - prev); } } @@ -593,17 +545,17 @@ printcommit(FILE *fp, struct commitinfo *ci) fputs("<b>Author:</b> ", fp); xmlencode(fp, ci->author->name, strlen(ci->author->name)); fputs(" &lt;<a href=\"mailto:", fp); - xmlencode(fp, ci->author->email, strlen(ci->author->email)); /* not percent-encoded */ + xmlencode(fp, ci->author->email, strlen(ci->author->email)); fputs("\">", fp); xmlencode(fp, ci->author->email, strlen(ci->author->email)); fputs("</a>&gt;\n<b>Date:</b> ", fp); printtime(fp, &(ci->author->when)); - putc('\n', fp); + fputc('\n', fp); } if (ci->msg) { - putc('\n', fp); + fputc('\n', fp); xmlencode(fp, ci->msg, strlen(ci->msg)); - putc('\n', fp); + fputc('\n', fp); } } @@ -688,11 +640,11 @@ printshowfile(FILE *fp, struct commitinfo *ci) patch = ci->deltas[i]->patch; delta = git_patch_get_delta(patch); fprintf(fp, "<b>diff --git a/<a id=\"h%zu\" href=\"%sfile/", i, relpath); - percentencode(fp, delta->old_file.path, strlen(delta->old_file.path)); + xmlencode(fp, delta->old_file.path, strlen(delta->old_file.path)); fputs(".html\">", fp); xmlencode(fp, delta->old_file.path, strlen(delta->old_file.path)); fprintf(fp, "</a> b/<a href=\"%sfile/", relpath); - percentencode(fp, delta->new_file.path, strlen(delta->new_file.path)); + xmlencode(fp, delta->new_file.path, strlen(delta->new_file.path)); fprintf(fp, ".html\">"); xmlencode(fp, delta->new_file.path, strlen(delta->new_file.path)); fprintf(fp, "</a></b>\n"); @@ -722,9 +674,8 @@ printshowfile(FILE *fp, struct commitinfo *ci) fprintf(fp, "<a href=\"#h%zu-%zu-%zu\" id=\"h%zu-%zu-%zu\" class=\"d\">-", i, j, k, i, j, k); else - putc(' ', fp); - xmlencodeline(fp, line->content, line->content_len); - putc('\n', fp); + fputc(' ', fp); + xmlencode(fp, line->content, line->content_len); if (line->old_lineno == -1 || line->new_lineno == -1) fputs("</a>", fp); } @@ -764,11 +715,11 @@ writelog(FILE *fp, const git_oid *oid) git_oid id; char path[PATH_MAX], oidstr[GIT_OID_HEXSZ + 1]; FILE *fpfile; - size_t remcommits = 0; int r; git_revwalk_new(&w, repo); git_revwalk_push(w, oid); + git_revwalk_simplify_first_parent(w); while (!git_revwalk_next(&id, w)) { relpath = ""; @@ -784,11 +735,8 @@ writelog(FILE *fp, const git_oid *oid) /* optimization: if there are no log lines to write and the commit file already exists: skip the diffstat */ - if (!nlogcommits) { - remcommits++; - if (!r) - continue; - } + if (!nlogcommits && !r) + continue; if (!(ci = commitinfo_getbyoid(&id))) break; @@ -796,10 +744,15 @@ writelog(FILE *fp, const git_oid *oid) if (commitinfo_getstats(ci) == -1) goto err; - if (nlogcommits != 0) { + if (nlogcommits < 0) { + writelogline(fp, ci); + } else if (nlogcommits > 0) { writelogline(fp, ci); - if (nlogcommits > 0) - nlogcommits--; + nlogcommits--; + if (!nlogcommits && ci->parentoid[0]) + fputs("<tr><td></td><td colspan=\"5\">" + "More commits remaining [...]</td>" + "</tr>\n", fp); } if (cachefile) @@ -821,12 +774,6 @@ err: } git_revwalk_free(w); - if (nlogcommits == 0 && remcommits != 0) { - fprintf(fp, "<tr><td></td><td colspan=\"5\">" - "%zu more commits remaining, fetch the repository" - "</td></tr>\n", remcommits); - } - relpath = ""; return 0; @@ -858,8 +805,8 @@ printcommitatom(FILE *fp, struct commitinfo *ci, const char *tag) xmlencode(fp, ci->summary, strlen(ci->summary)); fputs("</title>\n", fp); } - fprintf(fp, "<link rel=\"alternate\" type=\"text/html\" href=\"%scommit/%s.html\" />\n", - baseurl, ci->oid); + fprintf(fp, "<link rel=\"alternate\" type=\"text/html\" href=\"commit/%s.html\" />\n", + ci->oid); if (ci->author) { fputs("<author>\n<name>", fp); @@ -880,10 +827,10 @@ printcommitatom(FILE *fp, struct commitinfo *ci, const char *tag) xmlencode(fp, ci->author->email, strlen(ci->author->email)); fputs("&gt;\nDate: ", fp); printtime(fp, &(ci->author->when)); - putc('\n', fp); + fputc('\n', fp); } if (ci->msg) { - putc('\n', fp); + fputc('\n', fp); xmlencode(fp, ci->msg, strlen(ci->msg)); } fputs("\n</content>\n</entry>\n", fp); @@ -910,6 +857,7 @@ writeatom(FILE *fp, int all) if (all) { git_revwalk_new(&w, repo); git_revwalk_push_head(w); + git_revwalk_simplify_first_parent(w); for (i = 0; i < m && !git_revwalk_next(&id, w); i++) { if (!(ci = commitinfo_getbyoid(&id))) break; @@ -935,12 +883,12 @@ writeatom(FILE *fp, int all) return 0; } -size_t -writeblob(git_object *obj, const char *fpath, const char *filename, size_t filesize) +int +writeblob(git_object *obj, const char *fpath, const char *filename, git_off_t filesize) { char tmp[PATH_MAX] = "", *d; const char *p; - size_t lc = 0; + int lc = 0; FILE *fp; if (strlcpy(tmp, fpath, sizeof(tmp)) >= sizeof(tmp)) @@ -960,7 +908,7 @@ writeblob(git_object *obj, const char *fpath, const char *filename, size_t files writeheader(fp, filename); fputs("<p> ", fp); xmlencode(fp, filename, strlen(filename)); - fprintf(fp, " (%zuB)", filesize); + fprintf(fp, " (%juB)", (uintmax_t)filesize); fputs("</p><hr/>", fp); if (git_blob_is_binary((git_blob *)obj)) { @@ -1025,10 +973,11 @@ writefilestree(FILE *fp, git_tree *tree, const char *path) { const git_tree_entry *entry = NULL; git_object *obj = NULL; + git_off_t filesize; const char *entryname; - char filepath[PATH_MAX], entrypath[PATH_MAX], oid[8]; - size_t count, i, lc, filesize; - int r, ret; + char filepath[PATH_MAX], entrypath[PATH_MAX]; + size_t count, i; + int lc, r, ret; count = git_tree_entrycount(tree); for (i = 0; i < count; i++) { @@ -1065,14 +1014,14 @@ writefilestree(FILE *fp, git_tree *tree, const char *path) fputs("<tr><td>", fp); fputs(filemode(git_tree_entry_filemode(entry)), fp); fprintf(fp, "</td><td><a href=\"%s", relpath); - percentencode(fp, filepath, strlen(filepath)); + xmlencode(fp, filepath, strlen(filepath)); fputs("\">", fp); xmlencode(fp, entrypath, strlen(entrypath)); fputs("</a></td><td class=\"num\" align=\"right\">", fp); if (lc > 0) - fprintf(fp, "%zuL", lc); + fprintf(fp, "%dL", lc); else - fprintf(fp, "%zuB", filesize); + fprintf(fp, "%juB", (uintmax_t)filesize); fputs("</td></tr>\n", fp); git_object_free(obj); } else if (git_tree_entry_type(entry) == GIT_OBJ_COMMIT) { @@ -1080,10 +1029,7 @@ writefilestree(FILE *fp, git_tree *tree, const char *path) fprintf(fp, "<tr><td>m---------</td><td><a href=\"%sfile/.gitmodules.html\">", relpath); xmlencode(fp, entrypath, strlen(entrypath)); - fputs("</a> @ ", fp); - git_oid_tostr(oid, sizeof(oid), git_tree_entry_id(entry)); - xmlencode(fp, oid, strlen(oid)); - fputs("</td><td class=\"num\" align=\"right\"></td></tr>\n", fp); + fputs("</a></td><td class=\"num\" align=\"right\"></td></tr>\n", fp); } } @@ -1174,8 +1120,7 @@ writerefs(FILE *fp) void usage(char *argv0) { - fprintf(stderr, "%s [-c cachefile | -l commits] " - "[-u baseurl] repodir\n", argv0); + fprintf(stderr, "%s [-c cachefile | -l commits] repodir\n", argv0); exit(1); } @@ -1208,10 +1153,6 @@ main(int argc, char *argv[]) if (argv[i][0] == '\0' || *p != '\0' || nlogcommits <= 0 || errno) usage(argv[0]); - } else if (argv[i][1] == 'u') { - if (i + 1 >= argc) - usage(argv[0]); - baseurl = argv[++i]; } } if (!repodir) @@ -1289,7 +1230,7 @@ main(int argc, char *argv[]) } /* check LICENSE */ - for (i = 0; i < LEN(licensefiles) && !license; i++) { + for (i = 0; i < sizeof(licensefiles) / sizeof(*licensefiles) && !license; i++) { if (!git_revparse_single(&obj, repo, licensefiles[i]) && git_object_type(obj) == GIT_OBJ_BLOB) license = licensefiles[i] + strlen("HEAD:"); @@ -1297,7 +1238,7 @@ main(int argc, char *argv[]) } /* check README */ - for (i = 0; i < LEN(readmefiles) && !readme; i++) { + for (i = 0; i < sizeof(readmefiles) / sizeof(*readmefiles) && !readme; i++) { if (!git_revparse_single(&obj, repo, readmefiles[i]) && git_object_type(obj) == GIT_OBJ_BLOB) readme = readmefiles[i] + strlen("HEAD:");