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 | +++ |
M | stagit-index.c | | | 30 | ++++-------------------------- |
M | stagit.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("'" , fp); break;
case '&': fputs("&", fp); break;
case '"': fputs(""", 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("'", fp); break;
case '&': fputs("&", fp); break;
case '"': fputs(""", 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("<", fp); break;
- case '>': fputs(">", fp); break;
- case '\'': fputs("'", fp); break;
- case '&': fputs("&", fp); break;
- case '"': fputs(""", 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(" <<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>>\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(">\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:");