-rw-r--r-- | cgit.c | 3 | ||||
-rw-r--r-- | cgit.h | 3 | ||||
-rw-r--r-- | ui-diff.c | 14 |
3 files changed, 17 insertions, 3 deletions
@@ -91,65 +91,66 @@ static void cgit_print_repo_page(struct cacheitem *item) if (!strcmp(cgit_query_page, "blob")) { cgit_print_blob(item, cgit_query_sha1, cgit_query_path); return; } } if (cgit_query_page && !strcmp(cgit_query_page, "log")) show_search = 1; cgit_print_docstart(title, item); if (!cgit_query_page) { cgit_print_pageheader("summary", show_search); cgit_print_summary(); cgit_print_docend(); return; } cgit_print_pageheader(cgit_query_page, show_search); if (!strcmp(cgit_query_page, "log")) { cgit_print_log(cgit_query_head, cgit_query_ofs, cgit_max_commit_count, cgit_query_search, cgit_query_path); } else if (!strcmp(cgit_query_page, "tree")) { cgit_print_tree(cgit_query_head, cgit_query_sha1, cgit_query_path); } else if (!strcmp(cgit_query_page, "commit")) { cgit_print_commit(cgit_query_head); } else if (!strcmp(cgit_query_page, "view")) { cgit_print_view(cgit_query_sha1, cgit_query_path); } else if (!strcmp(cgit_query_page, "diff")) { - cgit_print_diff(cgit_query_sha1, cgit_query_sha2, cgit_query_path); + cgit_print_diff(cgit_query_head, cgit_query_sha1, cgit_query_sha2, + cgit_query_path); } else { cgit_print_error("Invalid request"); } cgit_print_docend(); } static void cgit_fill_cache(struct cacheitem *item, int use_cache) { static char buf[PATH_MAX]; int stdout2; getcwd(buf, sizeof(buf)); item->st.st_mtime = time(NULL); if (use_cache) { stdout2 = chk_positive(dup(STDOUT_FILENO), "Preserving STDOUT"); chk_zero(close(STDOUT_FILENO), "Closing STDOUT"); chk_positive(dup2(item->fd, STDOUT_FILENO), "Dup2(cachefile)"); } if (cgit_query_repo) cgit_print_repo_page(item); else cgit_print_repolist(item); if (use_cache) { chk_zero(close(STDOUT_FILENO), "Close redirected STDOUT"); chk_positive(dup2(stdout2, STDOUT_FILENO), "Restoring original STDOUT"); chk_zero(close(stdout2), "Closing temporary STDOUT"); } @@ -147,38 +147,39 @@ extern void html_filemode(unsigned short mode); extern int cgit_read_config(const char *filename, configfn fn); extern int cgit_parse_query(char *txt, configfn fn); extern struct commitinfo *cgit_parse_commit(struct commit *commit); extern struct taginfo *cgit_parse_tag(struct tag *tag); extern char *cache_safe_filename(const char *unsafe); extern int cache_lock(struct cacheitem *item); extern int cache_unlock(struct cacheitem *item); extern int cache_cancel_lock(struct cacheitem *item); extern int cache_exist(struct cacheitem *item); extern int cache_expired(struct cacheitem *item); extern char *cgit_repourl(const char *reponame); extern char *cgit_pageurl(const char *reponame, const char *pagename, const char *query); extern void cgit_print_error(char *msg); extern void cgit_print_date(unsigned long secs); extern void cgit_print_docstart(char *title, struct cacheitem *item); extern void cgit_print_docend(); extern void cgit_print_pageheader(char *title, int show_search); extern void cgit_print_snapshot_start(const char *mimetype, const char *filename, struct cacheitem *item); extern void cgit_print_repolist(struct cacheitem *item); extern void cgit_print_summary(); extern void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *path); extern void cgit_print_view(const char *hex, char *path); extern void cgit_print_blob(struct cacheitem *item, const char *hex, char *path); extern void cgit_print_tree(const char *rev, const char *hex, char *path); extern void cgit_print_commit(const char *hex); -extern void cgit_print_diff(const char *old_hex, const char *new_hex, char *path); +extern void cgit_print_diff(const char *head, const char *old_hex, const char *new_hex, + char *path); extern void cgit_print_snapshot(struct cacheitem *item, const char *hex, const char *format, const char *prefix, const char *filename); #endif /* CGIT_H */ @@ -37,69 +37,81 @@ static void header(unsigned char *sha1, char *path1, char *abbrev1, *abbrev2; if (is_null_sha1(sha1)) path1 = "dev/null"; if (is_null_sha1(sha2)) path2 = "dev/null"; html("<tr><td>"); html("<div class='head'>"); html("diff --git a/"); html_txt(path1); html(" b/"); html_txt(path2); abbrev1 = xstrdup(find_unique_abbrev(sha1, DEFAULT_ABBREV)); abbrev2 = xstrdup(find_unique_abbrev(sha2, DEFAULT_ABBREV)); htmlf("\nindex %s..%s", abbrev1, abbrev2); free(abbrev1); free(abbrev2); html("\n--- a/"); html_txt(path1); html("\n+++ b/"); html_txt(path2); html("</div>"); } static void filepair_cb(struct diff_filepair *pair) { header(pair->one->sha1, pair->one->path, pair->two->sha1, pair->two->path); if (cgit_diff_files(pair->one->sha1, pair->two->sha1, print_line)) cgit_print_error("Error running diff"); html("</tr></td>"); } -void cgit_print_diff(const char *old_hex, const char *new_hex, char *path) +void cgit_print_diff(const char *head, const char *old_hex, const char *new_hex, char *path) { unsigned char sha1[20], sha2[20]; enum object_type type; unsigned long size; + struct commit *commit; + + if (head && !old_hex && !new_hex) { + get_sha1(head, sha1); + commit = lookup_commit_reference(sha1); + if (commit && !parse_commit(commit)) { + html("<table class='diff'>"); + cgit_diff_commit(commit, filepair_cb); + html("</td></tr></table>"); + } + return; + } get_sha1(old_hex, sha1); get_sha1(new_hex, sha2); type = sha1_object_info(sha1, &size); if (type == OBJ_BAD) { type = sha1_object_info(sha2, &size); if (type == OBJ_BAD) { cgit_print_error(fmt("Bad object names: %s, %s", old_hex, new_hex)); return; } } html("<table class='diff'>"); switch(type) { case OBJ_BLOB: html("<tr><td>"); header(sha1, path, sha2, path); if (cgit_diff_files(sha1, sha2, print_line)) cgit_print_error("Error running diff"); html("</tr></td>"); break; case OBJ_TREE: cgit_diff_tree(sha1, sha2, filepair_cb); break; default: cgit_print_error(fmt("Unhandled object type: %s", typename(type))); break; } html("</td></tr></table>"); } |