+ if (!is_null_oid(old_rev_oid)) {
+ commit2 = lookup_commit_reference(the_repository, old_rev_oid);
+ if (!commit2 || repo_parse_commit(the_repository, commit2)) {
+ cgit_print_error_page(404, "Not found",
+ "Bad commit: %s", oid_to_hex(old_rev_oid));
+ return;
+ }
+ old_tree_oid = get_commit_tree_oid(commit2);
+ } else {
+ old_tree_oid = NULL;
+ }
+
+ if (raw) {
+ struct diff_options diffopt;
+
+ repo_diff_setup(the_repository, &diffopt);
+ diffopt.output_format = DIFF_FORMAT_PATCH;
+ diffopt.flags.recursive = 1;
+ diff_setup_done(&diffopt);
+
+ ctx.page.mimetype = "text/plain";
+ cgit_print_http_headers();
+ if (old_tree_oid) {
+ diff_tree_oid(old_tree_oid, new_tree_oid, "",
+ &diffopt);
+ } else {
+ diff_root_tree_oid(new_tree_oid, "", &diffopt);
+ }
+ diffcore_std(&diffopt);
+ diff_flush(&diffopt);
+
+ return;
+ }
+
+ difftype = ctx.qry.has_difftype ? ctx.qry.difftype : ctx.cfg.difftype;
+ use_ssdiff = difftype == DIFF_SSDIFF;
+
+ if (show_ctrls) {
+ cgit_print_layout_start();
+ cgit_print_diff_ctrls();
+ }
+
+ /*
+ * Clicking on a link to a file in the diff stat should show a diff
+ * of the file, showing the diff stat limited to a single file is
+ * pretty useless. All links from this point on will be to
+ * individual files, so we simply reset the difftype in the query
+ * here to avoid propagating DIFF_STATONLY to the individual files.
+ */
+ if (difftype == DIFF_STATONLY)
+ ctx.qry.difftype = ctx.cfg.difftype;
+
+ cgit_print_diffstat(old_rev_oid, new_rev_oid, prefix);
+
+ if (difftype == DIFF_STATONLY)
+ return;
+
+ if (use_ssdiff) {
+ html("<table summary='ssdiff' class='ssdiff'>");
+ } else {
+ html("<table summary='diff' class='diff'>");
+ html("<tr><td>");
+ }
+ cgit_diff_tree(old_rev_oid, new_rev_oid, filepair_cb, prefix,
+ ctx.qry.ignorews);
+ if (!use_ssdiff)
+ html("</td></tr>");