Merge branch 'filter-refs'

* filter-refs:
  Add links to the new refs page from summary page
  Add support for refs view
  Make cgit_print_branches()/cgit_print_tags() external
  Add descriptions of summary-branches and summary-tags to cgitrc
  Add support for config param summary-branches
  Move logic for age comparision from cmp_tag_age into cmp_age()
  Add support for config param summary-tags
  Sort tags by age
  Use reflist to print tag info
  Use reflist to print branch info
  Add functions and types for ref lists
This commit is contained in:
Lars Hjemli 2007-10-27 10:55:10 +02:00
commit dd0f27eb36
8 changed files with 229 additions and 37 deletions

View File

@ -16,7 +16,7 @@ GIT_URL = http://www.kernel.org/pub/software/scm/git/git-$(GIT_VER).tar.bz2
EXTLIBS = git/libgit.a git/xdiff/lib.a -lz -lcrypto EXTLIBS = git/libgit.a git/xdiff/lib.a -lz -lcrypto
OBJECTS = shared.o cache.o parsing.o html.o ui-shared.o ui-repolist.o \ OBJECTS = shared.o cache.o parsing.o html.o ui-shared.o ui-repolist.o \
ui-summary.o ui-log.o ui-tree.o ui-commit.o ui-diff.o \ ui-summary.o ui-log.o ui-tree.o ui-commit.o ui-diff.o \
ui-snapshot.o ui-blob.o ui-tag.o ui-snapshot.o ui-blob.o ui-tag.o ui-refs.o
.PHONY: all git install clean distclean force-version get-git .PHONY: all git install clean distclean force-version get-git

3
cgit.c
View File

@ -103,6 +103,9 @@ static void cgit_print_repo_page(struct cacheitem *item)
case CMD_COMMIT: case CMD_COMMIT:
cgit_print_commit(cgit_query_sha1); cgit_print_commit(cgit_query_sha1);
break; break;
case CMD_REFS:
cgit_print_refs();
break;
case CMD_TAG: case CMD_TAG:
cgit_print_tag(cgit_query_sha1); cgit_print_tag(cgit_query_sha1);
break; break;

27
cgit.h
View File

@ -28,6 +28,7 @@
#define CMD_BLOB 5 #define CMD_BLOB 5
#define CMD_SNAPSHOT 6 #define CMD_SNAPSHOT 6
#define CMD_TAG 7 #define CMD_TAG 7
#define CMD_REFS 8
/* /*
* Dateformats used on misc. pages * Dateformats used on misc. pages
@ -98,6 +99,21 @@ struct taginfo {
char *msg; char *msg;
}; };
struct refinfo {
const char *refname;
struct object *object;
union {
struct taginfo *tag;
struct commitinfo *commit;
};
};
struct reflist {
struct refinfo **refs;
int alloc;
int count;
};
extern const char *cgit_version; extern const char *cgit_version;
extern struct repolist cgit_repolist; extern struct repolist cgit_repolist;
@ -128,6 +144,8 @@ extern int cgit_cache_dynamic_ttl;
extern int cgit_cache_static_ttl; extern int cgit_cache_static_ttl;
extern int cgit_cache_max_create_time; extern int cgit_cache_max_create_time;
extern int cgit_summary_log; extern int cgit_summary_log;
extern int cgit_summary_tags;
extern int cgit_summary_branches;
extern int cgit_max_msg_len; extern int cgit_max_msg_len;
extern int cgit_max_repodesc_len; extern int cgit_max_repodesc_len;
@ -162,6 +180,10 @@ extern int chk_non_negative(int result, char *msg);
extern int hextoint(char c); extern int hextoint(char c);
extern char *trim_end(const char *str, char c); extern char *trim_end(const char *str, char c);
extern void cgit_add_ref(struct reflist *list, struct refinfo *ref);
extern int cgit_refs_cb(const char *refname, const unsigned char *sha1,
int flags, void *cb_data);
extern void *cgit_free_commitinfo(struct commitinfo *info); extern void *cgit_free_commitinfo(struct commitinfo *info);
extern int cgit_diff_files(const unsigned char *old_sha1, extern int cgit_diff_files(const unsigned char *old_sha1,
@ -214,6 +236,8 @@ extern void cgit_log_link(char *name, char *title, char *class, char *head,
char *rev, char *path, int ofs); char *rev, char *path, int ofs);
extern void cgit_commit_link(char *name, char *title, char *class, char *head, extern void cgit_commit_link(char *name, char *title, char *class, char *head,
char *rev); char *rev);
extern void cgit_refs_link(char *name, char *title, char *class, char *head,
char *rev, char *path);
extern void cgit_snapshot_link(char *name, char *title, char *class, extern void cgit_snapshot_link(char *name, char *title, char *class,
char *head, char *rev, char *archivename); char *head, char *rev, char *archivename);
extern void cgit_diff_link(char *name, char *title, char *class, char *head, extern void cgit_diff_link(char *name, char *title, char *class, char *head,
@ -230,6 +254,8 @@ extern void cgit_print_pageheader(char *title, int show_search);
extern void cgit_print_snapshot_start(const char *mimetype, extern void cgit_print_snapshot_start(const char *mimetype,
const char *filename, const char *filename,
struct cacheitem *item); struct cacheitem *item);
extern void cgit_print_branches(int maxcount);
extern void cgit_print_tags(int maxcount);
extern void cgit_print_repolist(struct cacheitem *item); extern void cgit_print_repolist(struct cacheitem *item);
extern void cgit_print_summary(); extern void cgit_print_summary();
@ -237,6 +263,7 @@ extern void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *
extern void cgit_print_blob(struct cacheitem *item, 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, char *path); extern void cgit_print_tree(const char *rev, char *path);
extern void cgit_print_commit(char *hex); extern void cgit_print_commit(char *hex);
extern void cgit_print_refs();
extern void cgit_print_tag(char *revname); extern void cgit_print_tag(char *revname);
extern void cgit_print_diff(const char *new_hex, const char *old_hex, const char *prefix); extern void cgit_print_diff(const char *new_hex, const char *old_hex, const char *prefix);
extern void cgit_print_snapshot(struct cacheitem *item, const char *head, extern void cgit_print_snapshot(struct cacheitem *item, const char *head,

10
cgitrc
View File

@ -30,6 +30,16 @@
#summary-log=0 #summary-log=0
## Restrict the number of branches printed in summary view. Set to 0 to
## print all branches.
#summary-branches=0
## Restrict the number of tags printed in summary view. Set to 0 to
## print all tags.
#summary-tags=0
## The "Idle" column on the repository index page can read a timestamp ## The "Idle" column on the repository index page can read a timestamp
## from the specified agefile (if this file cannot be found, the mtime ## from the specified agefile (if this file cannot be found, the mtime
## of HEAD is used). ## of HEAD is used).

View File

@ -38,6 +38,8 @@ int cgit_cache_dynamic_ttl = 5;
int cgit_cache_static_ttl = -1; int cgit_cache_static_ttl = -1;
int cgit_cache_max_create_time = 5; int cgit_cache_max_create_time = 5;
int cgit_summary_log = 0; int cgit_summary_log = 0;
int cgit_summary_tags = 0;
int cgit_summary_branches = 0;
int cgit_renamelimit = -1; int cgit_renamelimit = -1;
int cgit_max_msg_len = 60; int cgit_max_msg_len = 60;
@ -64,7 +66,7 @@ int htmlfd = 0;
int cgit_get_cmd_index(const char *cmd) int cgit_get_cmd_index(const char *cmd)
{ {
static char *cmds[] = {"log", "commit", "diff", "tree", "blob", static char *cmds[] = {"log", "commit", "diff", "tree", "blob",
"snapshot", "tag", NULL}; "snapshot", "tag", "refs", NULL};
int i; int i;
for(i = 0; cmds[i]; i++) for(i = 0; cmds[i]; i++)
@ -181,6 +183,10 @@ void cgit_global_config_cb(const char *name, const char *value)
cgit_max_commit_count = atoi(value); cgit_max_commit_count = atoi(value);
else if (!strcmp(name, "summary-log")) else if (!strcmp(name, "summary-log"))
cgit_summary_log = atoi(value); cgit_summary_log = atoi(value);
else if (!strcmp(name, "summary-branches"))
cgit_summary_branches = atoi(value);
else if (!strcmp(name, "summary-tags"))
cgit_summary_tags = atoi(value);
else if (!strcmp(name, "agefile")) else if (!strcmp(name, "agefile"))
cgit_agefile = xstrdup(value); cgit_agefile = xstrdup(value);
else if (!strcmp(name, "renamelimit")) else if (!strcmp(name, "renamelimit"))
@ -291,6 +297,47 @@ char *trim_end(const char *str, char c)
return s; return s;
} }
void cgit_add_ref(struct reflist *list, struct refinfo *ref)
{
size_t size;
if (list->count >= list->alloc) {
list->alloc += (list->alloc ? list->alloc : 4);
size = list->alloc * sizeof(struct refinfo *);
list->refs = xrealloc(list->refs, size);
}
list->refs[list->count++] = ref;
}
struct refinfo *cgit_mk_refinfo(const char *refname, const unsigned char *sha1)
{
struct refinfo *ref;
ref = xmalloc(sizeof (struct refinfo));
ref->refname = xstrdup(refname);
ref->object = parse_object(sha1);
switch (ref->object->type) {
case OBJ_TAG:
ref->tag = cgit_parse_tag((struct tag *)ref->object);
break;
case OBJ_COMMIT:
ref->commit = cgit_parse_commit((struct commit *)ref->object);
break;
}
return ref;
}
int cgit_refs_cb(const char *refname, const unsigned char *sha1, int flags,
void *cb_data)
{
struct reflist *list = (struct reflist *)cb_data;
struct refinfo *info = cgit_mk_refinfo(refname, sha1);
if (info)
cgit_add_ref(list, info);
return 0;
}
void cgit_diff_tree_cb(struct diff_queue_struct *q, void cgit_diff_tree_cb(struct diff_queue_struct *q,
struct diff_options *options, void *data) struct diff_options *options, void *data)
{ {

30
ui-refs.c Normal file
View File

@ -0,0 +1,30 @@
/* ui-refs.c: browse symbolic refs
*
* Copyright (C) 2006 Lars Hjemli
*
* Licensed under GNU General Public License v2
* (see COPYING for full license text)
*/
#include "cgit.h"
void cgit_print_refs()
{
html("<table class='list nowrap'>");
if (cgit_query_path && !strncmp(cgit_query_path, "heads", 5))
cgit_print_branches(0);
else if (cgit_query_path && !strncmp(cgit_query_path, "tags", 4))
cgit_print_tags(0);
else {
cgit_print_branches(0);
html("<tr class='nohover'><td colspan='4'>&nbsp;</td></tr>");
cgit_print_tags(0);
}
html("</table>");
}

View File

@ -227,6 +227,12 @@ void cgit_commit_link(char *name, char *title, char *class, char *head,
reporevlink("commit", name, title, class, head, rev, NULL); reporevlink("commit", name, title, class, head, rev, NULL);
} }
void cgit_refs_link(char *name, char *title, char *class, char *head,
char *rev, char *path)
{
reporevlink("refs", name, title, class, head, rev, path);
}
void cgit_snapshot_link(char *name, char *title, char *class, char *head, void cgit_snapshot_link(char *name, char *title, char *class, char *head,
char *rev, char *archivename) char *rev, char *archivename)
{ {

View File

@ -10,41 +10,73 @@
static int header; static int header;
static int cgit_print_branch_cb(const char *refname, const unsigned char *sha1, static int cmp_age(int age1, int age2)
int flags, void *cb_data) {
if (age1 != 0 && age2 != 0)
return age2 - age1;
if (age1 == 0 && age2 == 0)
return 0;
if (age1 == 0)
return +1;
return -1;
}
static int cmp_ref_name(const void *a, const void *b)
{
struct refinfo *r1 = *(struct refinfo **)a;
struct refinfo *r2 = *(struct refinfo **)b;
return strcmp(r1->refname, r2->refname);
}
static int cmp_branch_age(const void *a, const void *b)
{
struct refinfo *r1 = *(struct refinfo **)a;
struct refinfo *r2 = *(struct refinfo **)b;
return cmp_age(r1->commit->committer_date, r2->commit->committer_date);
}
static int cmp_tag_age(const void *a, const void *b)
{
struct refinfo *r1 = *(struct refinfo **)a;
struct refinfo *r2 = *(struct refinfo **)b;
return cmp_age(r1->tag->tagger_date, r2->tag->tagger_date);
}
static void cgit_print_branch(struct refinfo *ref)
{ {
struct commit *commit; struct commit *commit;
struct commitinfo *info; struct commitinfo *info;
char buf[256]; char *name = (char *)ref->refname;
char *ref;
ref = xstrdup(refname); commit = lookup_commit(ref->object->sha1);
strncpy(buf, refname, sizeof(buf));
commit = lookup_commit(sha1);
// object is not really parsed at this point, because of some fallout // object is not really parsed at this point, because of some fallout
// from previous calls to git functions in cgit_print_log() // from previous calls to git functions in cgit_print_log()
commit->object.parsed = 0; commit->object.parsed = 0;
if (commit && !parse_commit(commit)){ if (commit && !parse_commit(commit)){
info = cgit_parse_commit(commit); info = cgit_parse_commit(commit);
html("<tr><td>"); html("<tr><td>");
cgit_log_link(ref, NULL, NULL, ref, NULL, NULL, 0); cgit_log_link(name, NULL, NULL, name, NULL, NULL, 0);
html("</td><td>"); html("</td><td>");
cgit_print_age(commit->date, -1, NULL); cgit_print_age(commit->date, -1, NULL);
html("</td><td>"); html("</td><td>");
html_txt(info->author); html_txt(info->author);
html("</td><td>"); html("</td><td>");
cgit_commit_link(info->subject, NULL, NULL, ref, NULL); cgit_commit_link(info->subject, NULL, NULL, name, NULL);
html("</td></tr>\n"); html("</td></tr>\n");
cgit_free_commitinfo(info); cgit_free_commitinfo(info);
} else { } else {
html("<tr><td>"); html("<tr><td>");
html_txt(buf); html_txt(name);
html("</td><td colspan='3'>"); html("</td><td colspan='3'>");
htmlf("*** bad ref %s ***", sha1_to_hex(sha1)); htmlf("*** bad ref %s ***", sha1_to_hex(ref->object->sha1));
html("</td></tr>\n"); html("</td></tr>\n");
} }
free(ref);
return 0;
} }
static void print_tag_header() static void print_tag_header()
@ -56,29 +88,21 @@ static void print_tag_header()
header = 1; header = 1;
} }
static int cgit_print_tag_cb(const char *refname, const unsigned char *sha1, static int print_tag(struct refinfo *ref)
int flags, void *cb_data)
{ {
struct tag *tag; struct tag *tag;
struct taginfo *info; struct taginfo *info;
struct object *obj; char *url, *name = (char *)ref->refname;
char buf[256], *url;
strncpy(buf, refname, sizeof(buf)); if (ref->object->type == OBJ_TAG) {
obj = parse_object(sha1); tag = lookup_tag(ref->object->sha1);
if (!obj)
return 1;
if (obj->type == OBJ_TAG) {
tag = lookup_tag(sha1);
if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag))) if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag)))
return 2; return 2;
if (!header)
print_tag_header();
html("<tr><td>"); html("<tr><td>");
url = cgit_pageurl(cgit_query_repo, "tag", url = cgit_pageurl(cgit_query_repo, "tag",
fmt("id=%s", refname)); fmt("id=%s", name));
html_link_open(url, NULL, NULL); html_link_open(url, NULL, NULL);
html_txt(buf); html_txt(name);
html_link_close(); html_link_close();
html("</td><td>"); html("</td><td>");
if (info->tagger_date > 0) if (info->tagger_date > 0)
@ -93,9 +117,9 @@ static int cgit_print_tag_cb(const char *refname, const unsigned char *sha1,
if (!header) if (!header)
print_tag_header(); print_tag_header();
html("<tr><td>"); html("<tr><td>");
html_txt(buf); html_txt(name);
html("</td><td colspan='2'/><td>"); html("</td><td colspan='2'/><td>");
cgit_object_link(obj); cgit_object_link(ref->object);
html("</td></tr>\n"); html("</td></tr>\n");
} }
return 0; return 0;
@ -142,19 +166,64 @@ static int cgit_print_archive_cb(const char *refname, const unsigned char *sha1,
return 0; return 0;
} }
static void cgit_print_branches() static void print_refs_link(char *path)
{ {
html("<tr class='nohover'><td colspan='4'>");
cgit_refs_link("[...]", NULL, NULL, cgit_query_head, NULL, path);
html("</td></tr>");
}
void cgit_print_branches(int maxcount)
{
struct reflist list;
int i;
html("<tr class='nohover'><th class='left'>Branch</th>" html("<tr class='nohover'><th class='left'>Branch</th>"
"<th class='left'>Idle</th>" "<th class='left'>Idle</th>"
"<th class='left'>Author</th>" "<th class='left'>Author</th>"
"<th class='left'>Head commit</th></tr>\n"); "<th class='left'>Head commit</th></tr>\n");
for_each_branch_ref(cgit_print_branch_cb, NULL);
list.refs = NULL;
list.alloc = list.count = 0;
for_each_branch_ref(cgit_refs_cb, &list);
if (maxcount == 0 || maxcount > list.count)
maxcount = list.count;
if (maxcount < list.count) {
qsort(list.refs, list.count, sizeof(*list.refs), cmp_branch_age);
qsort(list.refs, maxcount, sizeof(*list.refs), cmp_ref_name);
}
for(i=0; i<maxcount; i++)
cgit_print_branch(list.refs[i]);
if (maxcount < list.count)
print_refs_link("heads");
} }
static void cgit_print_tags() void cgit_print_tags(int maxcount)
{ {
struct reflist list;
int i;
header = 0; header = 0;
for_each_tag_ref(cgit_print_tag_cb, NULL); list.refs = NULL;
list.alloc = list.count = 0;
for_each_tag_ref(cgit_refs_cb, &list);
if (list.count == 0)
return;
qsort(list.refs, list.count, sizeof(*list.refs), cmp_tag_age);
if (!maxcount)
maxcount = list.count;
else if (maxcount > list.count)
maxcount = list.count;
print_tag_header();
for(i=0; i<maxcount; i++)
print_tag(list.refs[i]);
if (maxcount < list.count)
print_refs_link("tags");
} }
static void cgit_print_archives() static void cgit_print_archives()
@ -182,8 +251,8 @@ void cgit_print_summary()
html("<table class='list nowrap'>"); html("<table class='list nowrap'>");
if (cgit_summary_log > 0) if (cgit_summary_log > 0)
html("<tr class='nohover'><td colspan='4'>&nbsp;</td></tr>"); html("<tr class='nohover'><td colspan='4'>&nbsp;</td></tr>");
cgit_print_branches(); cgit_print_branches(cgit_summary_branches);
html("<tr class='nohover'><td colspan='4'>&nbsp;</td></tr>"); html("<tr class='nohover'><td colspan='4'>&nbsp;</td></tr>");
cgit_print_tags(); cgit_print_tags(cgit_summary_tags);
html("</table>"); html("</table>");
} }