root/git/ui-commit.c
/*DEFINITIONS
This source file includes following definitions.1 #include <stdio.h> 2 #include <string.h> 3 #include <git2.h> 4 5 #include "html.h" 6 #include "ui-commit.h" 7 #include "git.h" 8 9 static void 10 dump_diffstat(git_diff *diff) 11 { 12 git_diff_stats *stats; 13 14 check_sgerr(git_diff_get_stats(&stats, diff)); 15 16 html("<span class=\"git-diffstat-text\">\n\ 17 %zu files changed, %zu insertions, %zu deletions\n\ 18 </span>\n", 19 git_diff_stats_files_changed(stats), 20 git_diff_stats_insertions(stats), 21 git_diff_stats_deletions(stats)); 22 23 git_diff_stats_free(stats); 24 } 25 26 27 static void 28 my_file_hdr(char *l) 29 { 30 git_commit *oc, *commit; 31 char *cp; 32 33 l = strtok_r(l, "\n", &cp); 34 35 do { 36 if (strchr("+-", *l) && strchr("ab", l[4])) { 37 check_sgerr(git_commit_lookup( 38 &commit, grepo, gbase)); 39 if (l[4] == 'a') { 40 oc = commit, commit = NULL; 41 git_commit_parent(&commit, oc, 0); 42 git_commit_free(oc); 43 } 44 if (commit) { 45 html("<b>%c%c%c %c/%s</b>\n", 46 *l, *l, *l, l[4], 47 html_make_link( 48 make_query_simple( 49 T_TREE, 50 git_commit_id(commit), 51 &l[5]), 52 my_html_encode(&l[6]))); 53 git_commit_free(commit); 54 continue; 55 } else goto fh_bailout; 56 } 57 58 fh_bailout: 59 html("<b>%s</b>\n", my_html_encode(l)); 60 } while ((l = strtok_r(NULL, "\n", &cp)) != NULL); 61 } 62 63 64 static int 65 my_diff_line_cb( 66 const git_diff_delta *delta, 67 const git_diff_hunk *hunk, 68 const git_diff_line *line, 69 void *payload) 70 { 71 char *lc, *l = check_sptr(dup2nul(line->content, line->content_len)); 72 char *class; 73 char c; 74 75 lc = check_sptr(html_conv_tab(l, 8)); 76 my_free(l); 77 l = lc; 78 79 switch (line->origin) { 80 default: 81 html("%s", html_encode(l)); 82 break; 83 case GIT_DIFF_LINE_FILE_HDR: 84 my_file_hdr(l); 85 break; 86 case GIT_DIFF_LINE_HUNK_HDR: 87 html("<span class=\"git-hunk\">%s</span>", html_encode(l)); 88 break; 89 case GIT_DIFF_LINE_CONTEXT: 90 c = ' '; 91 class = "git-context"; 92 goto p_diff_body; 93 case GIT_DIFF_LINE_ADDITION: 94 c = '+'; 95 class = "git-add"; 96 goto p_diff_body; 97 case GIT_DIFF_LINE_DELETION: 98 c = '-'; 99 class = "git-del"; 100 p_diff_body: 101 html("<span class=\"%s\">%c%s</span>", 102 class, c, html_encode(l)); 103 break; 104 } 105 106 my_free(l); 107 108 return 0; 109 } 110 111 112 static void 113 dump_diff(git_diff *diff) 114 { 115 html("<pre class=\"git-diff\">"); 116 check_sgerr(git_diff_print( 117 diff, 118 GIT_DIFF_FORMAT_PATCH, 119 my_diff_line_cb, NULL)); 120 html("</pre>"); 121 } 122 123 124 static void 125 dump_commit_raw(git_commit *commit) 126 { 127 git_email_create_options opts = GIT_EMAIL_CREATE_OPTIONS_INIT; 128 git_buf out; 129 char cidbuf[MINB]; 130 131 check_sgerr(git_email_create_from_commit(&out, commit, &opts)); 132 133 binary_xfer = 1; 134 http_header_attachment(0, 135 git_oid_tostr(cidbuf, MINB, git_commit_id(commit))); 136 http_header_end(query.can_compress); 137 138 fwrite(out.ptr, out.size, 1, stdout); 139 git_buf_free(&out); 140 } 141 142 143 void 144 dump_commit(void) { 145 git_commit *commit, *parent = NULL; 146 git_diff *diff; 147 const git_signature *author; 148 const git_signature *committer; 149 const git_oid *pid = NULL; 150 char cidbuf[MINB], pidbuf[MINB]; 151 152 check_sgerr(git_commit_lookup(&commit, grepo, gbase)); 153 author = git_commit_author(commit); 154 committer = git_commit_committer(commit); 155 git_commit_parent(&parent, commit, 0); 156 if (parent) pid = git_commit_id(parent); 157 158 diff = commit_to_diff(commit, parent); 159 160 if (query.tool == T_PATCH) { 161 dump_commit_raw(commit); 162 goto dump_commit_cleanup; 163 } 164 165 html("<table class=\"git-commit-prop\">\n\ 166 <tr>\n\ 167 <th>author</th>\n\ 168 <td>%s</td><td class=\"git-prop-date\">%s</td>\n\ 169 </tr>\n\ 170 <tr>\n\ 171 <th>committer</th>\n\ 172 <td>%s</td><td class=\"git-prop-date\">%s</td>\n\ 173 </tr>\n\ 174 <th>commit</th>\n\ 175 <td colspan=\"2\">%s (%s) (%s)</td>\n\ 176 </tr>\n\ 177 <th>parent</th>\n\ 178 <td colspan=\"2\" class=\"git-wrap\">%s</td>\n\ 179 </tr>\n\ 180 <th>download</th>\n\ 181 <td colspan=\"2\" class=\"git-snapshots\">\n\ 182 <code>%s</code><br>\n<code>%s</code></td>\n\ 183 </td>\n\ 184 </tr>\n\ 185 </table>\n\ 186 <h2>%s</h2>\n\ 187 <pre class=\"git-message-body\">%s</pre>\n", 188 my_html_encode(author->name), 189 check_sptr(readable_time(author->when.time)), 190 my_html_encode(committer->name), 191 check_sptr(readable_time(committer->when.time)), 192 my_html_make_link( 193 make_query_simple(T_COMMIT, NULL, NULL), 194 git_oid_tostr(cidbuf, MINB, gbase)), 195 my_html_make_link( 196 make_query_simple(T_PATCH, NULL, NULL), 197 "patch"), 198 my_html_make_link( 199 make_query_simple(T_TREE, NULL, NULL), 200 "tree"), 201 !parent ? "..." : html_make_link( 202 make_query_simple(T_COMMIT, pid, NULL), 203 (char *)git_commit_summary(parent)), 204 my_html_make_link( 205 make_query_simple(T_TARGZ, NULL, NULL), 206 my_html_encode(make_snapshot_name("tgz"))), 207 my_html_make_link( 208 make_query_simple(T_ZIP, NULL, NULL), 209 my_html_encode(make_snapshot_name("zip"))), 210 make_tag_summary(commit), 211 my_html_encode(thing_empty((char *)git_commit_body(commit),""))); 212 213 dump_diffstat(diff); 214 dump_diff(diff); 215 216 dump_commit_cleanup: 217 if (parent) git_commit_free(parent); 218 git_commit_free(commit); 219 git_diff_free(diff); 220 }
/*