示例#1
0
文件: ui-refs.c 项目: Distrotech/cgit
static int print_branch(struct refinfo *ref)
{
	struct commitinfo *info = ref->commit;
	char *name = (char *)ref->refname;

	if (!info)
		return 1;
	html("<tr><td>");
	cgit_log_link(name, NULL, NULL, name, NULL, NULL, 0, NULL, NULL,
		      ctx.qry.showmsg);
	html("</td><td>");

	if (ref->object->type == OBJ_COMMIT) {
		cgit_commit_link(info->subject, NULL, NULL, name, NULL, NULL, 0);
		html("</td><td>");
		cgit_open_filter(ctx.repo->email_filter, info->author_email, "refs");
		html_txt(info->author);
		cgit_close_filter(ctx.repo->email_filter);
		html("</td><td colspan='2'>");
		cgit_print_age(info->commit->date, -1, NULL);
	} else {
		html("</td><td></td><td>");
		cgit_object_link(ref->object);
	}
	html("</td></tr>\n");
	return 0;
}
示例#2
0
void cgit_print_repo_readme(char *path)
{
	char *filename, *ref;
	int free_filename = 0;

	if (ctx.repo->readme.nr == 0)
		return;

	filename = ctx.repo->readme.items[0].string;
	ref = ctx.repo->readme.items[0].util;

	if (path) {
		free_filename = 1;
		filename = append_readme_path(filename, ref, path);
		if (!filename)
			return;
	}

	/* Print the calculated readme, either from the git repo or from the
	 * filesystem, while applying the about-filter.
	 */
	html("<div id='summary'>");
	cgit_open_filter(ctx.repo->about_filter, filename);
	if (ref)
		cgit_print_file(filename, ref, 1);
	else
		html_include(filename);
	cgit_close_filter(ctx.repo->about_filter);

	html("</div>");
	if (free_filename)
		free(filename);
}
示例#3
0
void cgit_print_site_readme(void)
{
	if (!ctx.cfg.root_readme)
		return;
	cgit_open_filter(ctx.cfg.about_filter, ctx.cfg.root_readme);
	html_include(ctx.cfg.root_readme);
	cgit_close_filter(ctx.cfg.about_filter);
}
示例#4
0
文件: ui-refs.c 项目: Distrotech/cgit
static int print_tag(struct refinfo *ref)
{
	struct tag *tag = NULL;
	struct taginfo *info = NULL;
	char *name = (char *)ref->refname;
	struct object *obj = ref->object;

	if (obj->type == OBJ_TAG) {
		tag = (struct tag *)obj;
		obj = tag->tagged;
		info = ref->tag;
		if (!tag || !info)
			return 1;
	}

	html("<tr><td>");
	cgit_tag_link(name, NULL, NULL, ctx.qry.head, name);
	html("</td><td>");
	if (ctx.repo->snapshots && (obj->type == OBJ_COMMIT))
		print_tag_downloads(ctx.repo, name);
	else
		cgit_object_link(obj);
	html("</td><td>");
	if (info) {
		if (info->tagger) {
			cgit_open_filter(ctx.repo->email_filter, info->tagger_email, "refs");
			html_txt(info->tagger);
			cgit_close_filter(ctx.repo->email_filter);
		}
	} else if (ref->object->type == OBJ_COMMIT) {
		cgit_open_filter(ctx.repo->email_filter, ref->commit->author_email, "refs");
		html_txt(ref->commit->author);
		cgit_close_filter(ctx.repo->email_filter);
	}
	html("</td><td colspan='2'>");
	if (info) {
		if (info->tagger_date > 0)
			cgit_print_age(info->tagger_date, -1, NULL);
	} else if (ref->object->type == OBJ_COMMIT) {
		cgit_print_age(ref->commit->commit->date, -1, NULL);
	}
	html("</td></tr>\n");

	return 0;
}
示例#5
0
void cgit_print_site_readme(void)
{
	cgit_print_layout_start();
	if (!ctx.cfg.root_readme)
		goto done;
	cgit_open_filter(ctx.cfg.about_filter, ctx.cfg.root_readme);
	html_include(ctx.cfg.root_readme);
	cgit_close_filter(ctx.cfg.about_filter);
done:
	cgit_print_layout_end();
}
示例#6
0
void cgit_print_repo_readme(char *path)
{
	char *slash, *tmp, *colon, *ref;

	if (!ctx.repo->readme || !(*ctx.repo->readme))
		return;

	ref = NULL;

	/* Check if the readme is tracked in the git repo. */
	colon = strchr(ctx.repo->readme, ':');
	if (colon && strlen(colon) > 1) {
		*colon = '\0';
		ref = ctx.repo->readme;
		ctx.repo->readme = colon + 1;
		if (!(*ctx.repo->readme))
			return;
	}

	/* Prepend repo path to relative readme path unless tracked. */
	if (!ref && *ctx.repo->readme != '/')
		ctx.repo->readme = xstrdup(fmt("%s/%s", ctx.repo->path,
					       ctx.repo->readme));

	/* If a subpath is specified for the about page, make it relative
	 * to the directory containing the configured readme.
	 */
	if (path) {
		slash = strrchr(ctx.repo->readme, '/');
		if (!slash) {
			if (!colon)
				return;
			slash = colon;
		}
		tmp = xmalloc(slash - ctx.repo->readme + 1 + strlen(path) + 1);
		strncpy(tmp, ctx.repo->readme, slash - ctx.repo->readme + 1);
		strcpy(tmp + (slash - ctx.repo->readme + 1), path);
	} else
		tmp = ctx.repo->readme;

	/* Print the calculated readme, either from the git repo or from the
	 * filesystem, while applying the about-filter.
	 */
	html("<div id='summary'>");
	if (ctx.repo->about_filter)
		cgit_open_filter(ctx.repo->about_filter);
	if (ref)
		cgit_print_file(tmp, ref);
	else
		html_include(tmp);
	if (ctx.repo->about_filter)
		cgit_close_filter(ctx.repo->about_filter);
	html("</div>");
}
示例#7
0
void cgit_print_repo_readme(char *path)
{
	char *slash, *tmp;

	if (!ctx.repo->readme)
		return;

	if (path) {
		slash = strrchr(ctx.repo->readme, '/');
		if (!slash)
			return;
		tmp = xmalloc(slash - ctx.repo->readme + 1 + strlen(path) + 1);
		strncpy(tmp, ctx.repo->readme, slash - ctx.repo->readme + 1);
		strcpy(tmp + (slash - ctx.repo->readme + 1), path);
	} else
		tmp = ctx.repo->readme;
	html("<div id='summary'>");
	if (ctx.repo->about_filter)
		cgit_open_filter(ctx.repo->about_filter);
	html_include(tmp);
	if (ctx.repo->about_filter)
		cgit_close_filter(ctx.repo->about_filter);
	html("</div>");
}
示例#8
0
void cgit_print_repolist(void)
{
	int i, columns = 3, hits = 0, header = 0;
	char *last_section = NULL;
	char *section;
	int sorted = 0;

	if (!any_repos_visible()) {
		cgit_print_error_page(404, "Not found", "No repositories found");
		return;
	}

	if (ctx.cfg.enable_index_links)
		++columns;
	if (ctx.cfg.enable_index_owner)
		++columns;

	ctx.page.title = ctx.cfg.root_title;
	cgit_print_http_headers();
	cgit_print_docstart();
	cgit_print_pageheader();

	if (ctx.cfg.index_header)
		html_include(ctx.cfg.index_header);

	if (ctx.qry.sort)
		sorted = sort_repolist(ctx.qry.sort);
	else if (ctx.cfg.section_sort)
		sort_repolist("section");

	html("<table summary='repository list' class='list nowrap'>");
	for (i = 0; i < cgit_repolist.count; i++) {
		ctx.repo = &cgit_repolist.repos[i];
		if (!is_visible(ctx.repo))
			continue;
		hits++;
		if (hits <= ctx.qry.ofs)
			continue;
		if (hits > ctx.qry.ofs + ctx.cfg.max_repo_count)
			continue;
		if (!header++)
			print_header();
		section = ctx.repo->section;
		if (section && !strcmp(section, ""))
			section = NULL;
		if (!sorted &&
		    ((last_section == NULL && section != NULL) ||
		    (last_section != NULL && section == NULL) ||
		    (last_section != NULL && section != NULL &&
		     strcmp(section, last_section)))) {
			htmlf("<tr class='nohover'><td colspan='%d' class='reposection'>",
			      columns);
			html_txt(section);
			html("</td></tr>");
			last_section = section;
		}
		htmlf("<tr><td class='%s'>",
		      !sorted && section ? "sublevel-repo" : "toplevel-repo");
		cgit_summary_link(ctx.repo->name, ctx.repo->name, NULL, NULL);
		html("</td><td>");
		html_link_open(cgit_repourl(ctx.repo->url), NULL, NULL);
		html_ntxt(ctx.cfg.max_repodesc_len, ctx.repo->desc);
		html_link_close();
		html("</td><td>");
		if (ctx.cfg.enable_index_owner) {
			if (ctx.repo->owner_filter) {
				cgit_open_filter(ctx.repo->owner_filter);
				html_txt(ctx.repo->owner);
				cgit_close_filter(ctx.repo->owner_filter);
			} else {
				html("<a href='");
				html_attr(cgit_currenturl());
				html("?q=");
				html_url_arg(ctx.repo->owner);
				html("'>");
				html_txt(ctx.repo->owner);
				html("</a>");
			}
			html("</td><td>");
		}
		print_modtime(ctx.repo);
		html("</td>");
		if (ctx.cfg.enable_index_links) {
			html("<td>");
			cgit_summary_link("summary", NULL, "button", NULL);
			cgit_log_link("log", NULL, "button", NULL, NULL, NULL,
				      0, NULL, NULL, ctx.qry.showmsg, 0);
			cgit_tree_link("tree", NULL, "button", NULL, NULL, NULL);
			html("</td>");
		}
		html("</tr>\n");
	}
	html("</table>");
	if (hits > ctx.cfg.max_repo_count)
		print_pager(hits, ctx.cfg.max_repo_count, ctx.qry.search, ctx.qry.sort);
	cgit_print_docend();
}
示例#9
0
void cgit_print_commit(char *hex, const char *prefix)
{
	struct commit *commit, *parent;
	struct commitinfo *info, *parent_info;
	struct commit_list *p;
	struct strbuf notes = STRBUF_INIT;
	unsigned char sha1[20];
	char *tmp, *tmp2;
	int parents = 0;

	if (!hex)
		hex = ctx.qry.head;

	if (get_sha1(hex, sha1)) {
		cgit_print_error("Bad object id: %s", hex);
		return;
	}
	commit = lookup_commit_reference(sha1);
	if (!commit) {
		cgit_print_error("Bad commit reference: %s", hex);
		return;
	}
	info = cgit_parse_commit(commit);

	format_display_notes(sha1, &notes, PAGE_ENCODING, 0);

	load_ref_decorations(DECORATE_FULL_REFS);

	cgit_print_diff_ctrls();
	html("<table summary='commit info' class='commit-info'>\n");
	html("<tr><th>author</th><td>");
	html_txt(info->author);
	if (!ctx.cfg.noplainemail) {
		html(" ");
		html_txt(info->author_email);
	}
	html("</td><td class='right'>");
	cgit_print_date(info->author_date, FMT_LONGDATE, ctx.cfg.local_time);
	html("</td></tr>\n");
	html("<tr><th>committer</th><td>");
	html_txt(info->committer);
	if (!ctx.cfg.noplainemail) {
		html(" ");
		html_txt(info->committer_email);
	}
	html("</td><td class='right'>");
	cgit_print_date(info->committer_date, FMT_LONGDATE, ctx.cfg.local_time);
	html("</td></tr>\n");
	html("<tr><th>commit</th><td colspan='2' class='sha1'>");
	tmp = sha1_to_hex(commit->object.sha1);
	cgit_commit_link(tmp, NULL, NULL, ctx.qry.head, tmp, prefix, 0);
	html(" (");
	cgit_patch_link("patch", NULL, NULL, NULL, tmp, prefix);
	html(")</td></tr>\n");
	html("<tr><th>tree</th><td colspan='2' class='sha1'>");
	tmp = xstrdup(hex);
	cgit_tree_link(sha1_to_hex(commit->tree->object.sha1), NULL, NULL,
		       ctx.qry.head, tmp, NULL);
	if (prefix) {
		html(" /");
		cgit_tree_link(prefix, NULL, NULL, ctx.qry.head, tmp, prefix);
	}
	free(tmp);
	html("</td></tr>\n");
	for (p = commit->parents; p; p = p->next) {
		parent = lookup_commit_reference(p->item->object.sha1);
		if (!parent) {
			html("<tr><td colspan='3'>");
			cgit_print_error("Error reading parent commit");
			html("</td></tr>");
			continue;
		}
		html("<tr><th>parent</th>"
		     "<td colspan='2' class='sha1'>");
		tmp = tmp2 = sha1_to_hex(p->item->object.sha1);
		if (ctx.repo->enable_subject_links) {
			parent_info = cgit_parse_commit(parent);
			tmp2 = parent_info->subject;
		}
		cgit_commit_link(tmp2, NULL, NULL, ctx.qry.head, tmp, prefix, 0);
		html(" (");
		cgit_diff_link("diff", NULL, NULL, ctx.qry.head, hex,
			       sha1_to_hex(p->item->object.sha1), prefix, 0);
		html(")</td></tr>");
		parents++;
	}
	if (ctx.repo->snapshots) {
		html("<tr><th>download</th><td colspan='2' class='sha1'>");
		cgit_print_snapshot_links(ctx.qry.repo, ctx.qry.head,
					  hex, ctx.repo->snapshots);
		html("</td></tr>");
	}
	html("</table>\n");
	html("<div class='commit-subject'>");
	if (ctx.repo->commit_filter)
		cgit_open_filter(ctx.repo->commit_filter);
	html_txt(info->subject);
	if (ctx.repo->commit_filter)
		cgit_close_filter(ctx.repo->commit_filter);
	show_commit_decorations(commit);
	html("</div>");
	html("<div class='commit-msg'>");
	if (ctx.repo->commit_filter)
		cgit_open_filter(ctx.repo->commit_filter);
	html_txt(info->msg);
	if (ctx.repo->commit_filter)
		cgit_close_filter(ctx.repo->commit_filter);
	html("</div>");
	if (notes.len != 0) {
		html("<div class='notes-header'>Notes</div>");
		html("<div class='notes'>");
		if (ctx.repo->commit_filter)
			cgit_open_filter(ctx.repo->commit_filter);
		html_txt(notes.buf);
		if (ctx.repo->commit_filter)
			cgit_close_filter(ctx.repo->commit_filter);
		html("</div>");
		html("<div class='notes-footer'></div>");
	}
	if (parents < 3) {
		if (parents)
			tmp = sha1_to_hex(commit->parents->item->object.sha1);
		else
			tmp = NULL;
		cgit_print_diff(ctx.qry.sha1, tmp, prefix, 0);
	}
	strbuf_release(&notes);
	cgit_free_commitinfo(info);
}
示例#10
0
void cgit_print_tag(char *revname)
{
	struct strbuf fullref = STRBUF_INIT;
	unsigned char sha1[20];
	struct object *obj;
	struct tag *tag;
	struct taginfo *info;

	if (!revname)
		revname = ctx.qry.head;

	strbuf_addf(&fullref, "refs/tags/%s", revname);
	if (get_sha1(fullref.buf, sha1)) {
		cgit_print_error_page(404, "Not found",
			"Bad tag reference: %s", revname);
		goto cleanup;
	}
	obj = parse_object(sha1);
	if (!obj) {
		cgit_print_error_page(500, "Internal server error",
			"Bad object id: %s", sha1_to_hex(sha1));
		goto cleanup;
	}
	if (obj->type == OBJ_TAG) {
		tag = lookup_tag(sha1);
		if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag))) {
			cgit_print_error_page(500, "Internal server error",
				"Bad tag object: %s", revname);
			goto cleanup;
		}
		cgit_print_layout_start();
		html("<table class='commit-info'>\n");
		htmlf("<tr><td>tag name</td><td>");
		html_txt(revname);
		htmlf(" (%s)</td></tr>\n", sha1_to_hex(sha1));
		if (info->tagger_date > 0) {
			html("<tr><td>tag date</td><td>");
			cgit_print_date(info->tagger_date, FMT_LONGDATE, ctx.cfg.local_time);
			html("</td></tr>\n");
		}
		if (info->tagger) {
			html("<tr><td>tagged by</td><td>");
			cgit_open_filter(ctx.repo->email_filter, info->tagger_email, "tag");
			html_txt(info->tagger);
			if (info->tagger_email && !ctx.cfg.noplainemail) {
				html(" ");
				html_txt(info->tagger_email);
			}
			cgit_close_filter(ctx.repo->email_filter);
			html("</td></tr>\n");
		}
		html("<tr><td>tagged object</td><td class='sha1'>");
		cgit_object_link(tag->tagged);
		html("</td></tr>\n");
		if (ctx.repo->snapshots)
			print_download_links(revname);
		html("</table>\n");
		print_tag_content(info->msg);
		cgit_print_layout_end();
	} else {
		cgit_print_layout_start();
		html("<table class='commit-info'>\n");
		htmlf("<tr><td>tag name</td><td>");
		html_txt(revname);
		html("</td></tr>\n");
		html("<tr><td>Tagged object</td><td class='sha1'>");
		cgit_object_link(obj);
		html("</td></tr>\n");
		if (ctx.repo->snapshots)
			print_download_links(revname);
		html("</table>\n");
		cgit_print_layout_end();
	}

cleanup:
	strbuf_release(&fullref);
}
示例#11
0
static void print_object(const unsigned char *sha1, const char *path,
			 const char *basename, const char *rev)
{
	enum object_type type;
	char *buf;
	unsigned long size;
	struct argv_array rev_argv = ARGV_ARRAY_INIT;
	struct rev_info revs;
	struct blame_scoreboard sb;
	struct blame_origin *o;
	struct blame_entry *ent = NULL;

	type = sha1_object_info(sha1, &size);
	if (type == OBJ_BAD) {
		cgit_print_error_page(404, "Not found", "Bad object name: %s",
				      sha1_to_hex(sha1));
		return;
	}

	buf = read_sha1_file(sha1, &type, &size);
	if (!buf) {
		cgit_print_error_page(500, "Internal server error",
			"Error reading object %s", sha1_to_hex(sha1));
		return;
	}

	argv_array_push(&rev_argv, "blame");
	argv_array_push(&rev_argv, rev);
	init_revisions(&revs, NULL);
	revs.diffopt.flags.allow_textconv = 1;
	setup_revisions(rev_argv.argc, rev_argv.argv, &revs, NULL);
	init_scoreboard(&sb);
	sb.revs = &revs;
	setup_scoreboard(&sb, path, &o);
	o->suspects = blame_entry_prepend(NULL, 0, sb.num_lines, o);
	prio_queue_put(&sb.commits, o->commit);
	blame_origin_decref(o);
	sb.ent = NULL;
	sb.path = path;
	assign_blame(&sb, 0);
	blame_sort_final(&sb);
	blame_coalesce(&sb);

	cgit_set_title_from_path(path);

	cgit_print_layout_start();
	htmlf("blob: %s (", sha1_to_hex(sha1));
	cgit_plain_link("plain", NULL, NULL, ctx.qry.head, rev, path);
	html(") (");
	cgit_tree_link("tree", NULL, NULL, ctx.qry.head, rev, path);
	html(")\n");

	if (ctx.cfg.max_blob_size && size / 1024 > ctx.cfg.max_blob_size) {
		htmlf("<div class='error'>blob size (%ldKB)"
		      " exceeds display size limit (%dKB).</div>",
		      size / 1024, ctx.cfg.max_blob_size);
		return;
	}

	html("<table class='blame blob'>\n<tr>\n");

	/* Commit hashes */
	html("<td class='hashes'>");
	for (ent = sb.ent; ent; ent = ent->next) {
		html("<div class='alt'><pre>");
		emit_blame_entry_hash(ent);
		html("</pre></div>");
	}
	html("</td>\n");

	/* Line numbers */
	if (ctx.cfg.enable_tree_linenumbers) {
		html("<td class='linenumbers'>");
		for (ent = sb.ent; ent; ent = ent->next) {
			html("<div class='alt'><pre>");
			emit_blame_entry_linenumber(ent);
			html("</pre></div>");
		}
		html("</td>\n");
	}

	html("<td class='lines'><div>");

	/* Colored bars behind lines */
	html("<div>");
	for (ent = sb.ent; ent; ) {
		struct blame_entry *e = ent->next;
		html("<div class='alt'><pre>");
		emit_blame_entry_line_background(&sb, ent);
		html("</pre></div>");
		free(ent);
		ent = e;
	}
	html("</div>");

	free((void *)sb.final_buf);

	/* Lines */
	html("<pre><code>");
	if (ctx.repo->source_filter) {
		char *filter_arg = xstrdup(basename);
		cgit_open_filter(ctx.repo->source_filter, filter_arg);
		html_raw(buf, size);
		cgit_close_filter(ctx.repo->source_filter);
		free(filter_arg);
	} else {
		html_txt(buf);
	}
	html("</code></pre>");

	html("</div></td>\n");

	html("</tr>\n</table>\n");

	cgit_print_layout_end();
}