Don't fail on submodules
Submodules will get listed prefixed with a '@', using a specific CSS class for styling. The href will be set to the url of the submodule. Filesize will appear as 0 and filemode will not be printed to avoid an awkward mode: "?---------". In writefilestree, we don't return anymore if an entry can't be categorized as an object, but rather, fail if we can't retrieve its name.M · stagit.c +40, -29
1@@ -653,6 +653,7 @@ int
2 writefilestree(FILE *fp, git_tree *tree, const char *branch, const char *path)
3 {
4 const git_tree_entry *entry = NULL;
5+ git_submodule *module = NULL;
6 const char *entryname;
7 char filepath[PATH_MAX], entrypath[PATH_MAX];
8 git_object *obj = NULL;
9@@ -663,29 +664,13 @@ writefilestree(FILE *fp, git_tree *tree, const char *branch, const char *path)
10 count = git_tree_entrycount(tree);
11 for (i = 0; i < count; i++) {
12 if (!(entry = git_tree_entry_byindex(tree, i)) ||
13- git_tree_entry_to_object(&obj, repo, entry))
14+ !(entryname = git_tree_entry_name(entry)))
15 return -1;
16- entryname = git_tree_entry_name(entry);
17 r = snprintf(entrypath, sizeof(entrypath), "%s%s%s",
18 path, path[0] ? "/" : "", entryname);
19 if (r == -1 || (size_t)r >= sizeof(entrypath))
20 errx(1, "path truncated: '%s%s%s'",
21 path, path[0] ? "/" : "", entryname);
22- switch (git_object_type(obj)) {
23- case GIT_OBJ_BLOB:
24- break;
25- case GIT_OBJ_TREE:
26- /* NOTE: recurses */
27- ret = writefilestree(fp, (git_tree *)obj, branch,
28- entrypath);
29- git_object_free(obj);
30- if (ret)
31- return ret;
32- continue;
33- default:
34- git_object_free(obj);
35- continue;
36- }
37
38 r = snprintf(filepath, sizeof(filepath), "file/%s%s%s.html",
39 path, path[0] ? "/" : "", entryname);
40@@ -693,20 +678,46 @@ writefilestree(FILE *fp, git_tree *tree, const char *branch, const char *path)
41 errx(1, "path truncated: 'file/%s%s%s.html'",
42 path, path[0] ? "/" : "", entryname);
43
44- filesize = git_blob_rawsize((git_blob *)obj);
45+ if (!git_tree_entry_to_object(&obj, repo, entry)) {
46+ switch (git_object_type(obj)) {
47+ case GIT_OBJ_BLOB:
48+ break;
49+ case GIT_OBJ_TREE:
50+ /* NOTE: recurses */
51+ ret = writefilestree(fp, (git_tree *)obj, branch,
52+ entrypath);
53+ git_object_free(obj);
54+ if (ret)
55+ return ret;
56+ continue;
57+ default:
58+ git_object_free(obj);
59+ continue;
60+ }
61
62- lc = writeblob(obj, filepath, entryname, filesize);
63+ filesize = git_blob_rawsize((git_blob *)obj);
64+ lc = writeblob(obj, filepath, entryname, filesize);
65
66- fputs("<tr><td>", fp);
67- fputs(filemode(git_tree_entry_filemode(entry)), fp);
68- fprintf(fp, "</td><td><a href=\"%s%s\">", relpath, filepath);
69- xmlencode(fp, entrypath, strlen(entrypath));
70- fputs("</a></td><td class=\"num\">", fp);
71- if (showlinecount && lc > 0)
72- fprintf(fp, "%dL", lc);
73- else
74- fprintf(fp, "%juB", (uintmax_t)filesize);
75- fputs("</td></tr>\n", fp);
76+ fputs("<tr><td>", fp);
77+ fputs(filemode(git_tree_entry_filemode(entry)), fp);
78+ fprintf(fp, "</td><td><a href=\"%s%s\">", relpath, filepath);
79+ xmlencode(fp, entrypath, strlen(entrypath));
80+ fputs("</a></td><td class=\"num\">", fp);
81+ if (showlinecount && lc > 0)
82+ fprintf(fp, "%dL", lc);
83+ else
84+ fprintf(fp, "%juB", (uintmax_t)filesize);
85+ fputs("</td></tr>\n", fp);
86+ } else if (git_submodule_lookup(&module, repo, entryname) == 0) {
87+
88+ fprintf(fp, "<tr><td></td><td><a class=\"module\" href=\"%s\">@",
89+ git_submodule_url(module));
90+ xmlencode(fp, entrypath, strlen(entrypath));
91+ fprintf(fp, "</a></td><td class=\"num\">0%c",
92+ showlinecount ? 'L' : 'B');
93+ git_submodule_free(module);
94+ fputs("</td></tr>\n", fp);
95+ }
96 }
97
98 return 0;
M · style.css
+4, -0 1@@ -58,6 +58,10 @@ table td {
2 white-space: normal;
3 }
4
5+a.module {
6+ color: #777;
7+}
8+
9 td.num {
10 text-align: right;
11 }