]> gitweb.ps.run Git - ps-cgit/commitdiff
Merge branch 'full-log'
authorLars Hjemli <hjemli@gmail.com>
Sat, 6 Dec 2008 10:37:37 +0000 (11:37 +0100)
committerLars Hjemli <hjemli@gmail.com>
Sat, 6 Dec 2008 10:37:37 +0000 (11:37 +0100)
Conflicts:
cgit.c
cgit.h

1  2 
cgit.c
cgit.h
ui-log.c
ui-refs.c
ui-repolist.c
ui-shared.c

diff --combined cgit.c
index e09c86eaae248ead1fbcca8ee51224b98ccf94af,db5d342ceb196a0ae8f50e1131d1f65f5b41f731..166fbc649607fcc1872eb61c6c0cd2b7e7c6de31
--- 1/cgit.c
--- 2/cgit.c
+++ b/cgit.c
@@@ -154,8 -154,8 +154,10 @@@ static void querystring_cb(const char *
                ctx.qry.name = xstrdup(value);
        } else if (!strcmp(name, "mimetype")) {
                ctx.qry.mimetype = xstrdup(value);
 +      } else if (!strcmp(name, "s")){
 +              ctx.qry.sort = xstrdup(value);
+       } else if (!strcmp(name, "showmsg")) {
+               ctx.qry.showmsg = atoi(value);
        }
  }
  
diff --combined cgit.h
index f1fbeca0be7f08dc70221cb2d7cac433df039901,aab898b03bdbff524059b17b2ebc136243fa605d..cb2f176f621f52d60489dd817d2776411360b3bf
--- 1/cgit.h
--- 2/cgit.h
+++ b/cgit.h
@@@ -61,7 -61,6 +61,7 @@@ struct cgit_repo 
        int snapshots;
        int enable_log_filecount;
        int enable_log_linecount;
 +      time_t mtime;
  };
  
  struct cgit_repolist {
@@@ -122,7 -121,7 +122,8 @@@ struct cgit_query 
        char *url;
        int   ofs;
        int nohead;
 +      char *sort;
+       int showmsg;
  };
  
  struct cgit_config {
@@@ -235,5 -234,11 +236,5 @@@ extern const char *cgit_repobasename(co
  
  extern int cgit_parse_snapshots_mask(const char *str);
  
 -/* libgit.a either links against or compiles its own implementation of
 - * strcasestr(), and we'd like to reuse it. Simply re-declaring it
 - * seems to do the trick.
 - */
 -extern char *strcasestr(const char *haystack, const char *needle);
 -
  
  #endif /* CGIT_H */
diff --combined ui-log.c
index d2129844032d59aebfa8172c3a6f34e8ad85c2cf,00ecd4e3e0c8d3200a716c77daacb00b4a62da2b..2f90778c70b22d80a6282eea60190f2cdf78c521
+++ b/ui-log.c
@@@ -35,15 -35,18 +35,18 @@@ void print_commit(struct commit *commit
  {
        struct commitinfo *info;
        char *tmp;
+       int cols = 2;
  
        info = cgit_parse_commit(commit);
-       html("<tr><td>");
+       htmlf("<tr%s><td>",
+               ctx.qry.showmsg ? " class='logheader'" : "");
        tmp = fmt("id=%s", sha1_to_hex(commit->object.sha1));
        tmp = cgit_pageurl(ctx.repo->url, "commit", tmp);
        html_link_open(tmp, NULL, NULL);
        cgit_print_age(commit->date, TM_WEEK * 2, FMT_SHORTDATE);
        html_link_close();
-       html("</td><td>");
+       htmlf("</td><td%s>",
+               ctx.qry.showmsg ? " class='logsubject'" : "");
        cgit_commit_link(info->subject, NULL, NULL, ctx.qry.head,
                         sha1_to_hex(commit->object.sha1));
        html("</td><td>");
                }
        }
        html("</td></tr>\n");
+       if (ctx.qry.showmsg) {
+               if (ctx.repo->enable_log_filecount) {
+                       cols++;
+                       if (ctx.repo->enable_log_linecount)
+                               cols++;
+               }
+               htmlf("<tr class='nohover'><td/><td colspan='%d' class='logmsg'>",
+                       cols);
+               html_txt(info->msg);
+               html("</td></tr>\n");
+       }
        cgit_free_commitinfo(info);
  }
  
 +static const char *disambiguate_ref(const char *ref)
 +{
 +      unsigned char sha1[20];
 +      const char *longref;
 +
 +      longref = fmt("refs/heads/%s", ref);
 +      if (get_sha1(longref, sha1) == 0)
 +              return longref;
 +
 +      return ref;
 +}
  
  void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern,
                    char *path, int pager)
  {
        struct rev_info rev;
        struct commit *commit;
 -      const char *argv[] = {NULL, tip, NULL, NULL, NULL};
 +      const char *argv[] = {NULL, NULL, NULL, NULL, NULL};
        int argc = 2;
        int i, columns = 3;
  
        if (!tip)
 -              argv[1] = ctx.qry.head;
 +              tip = ctx.qry.head;
 +
 +      argv[1] = disambiguate_ref(tip);
  
        if (grep && pattern && (!strcmp(grep, "grep") ||
                                !strcmp(grep, "author") ||
                html("<table class='list nowrap'>");
  
        html("<tr class='nohover'><th class='left'>Age</th>"
-            "<th class='left'>Commit message</th>"
-            "<th class='left'>Author</th>");
+             "<th class='left'>Commit message");
+       if (pager) {
+               html(" (");
+               cgit_log_link("toggle", NULL, NULL, ctx.qry.head, ctx.qry.sha1,
+                             ctx.qry.path, ctx.qry.ofs, ctx.qry.grep,
+                             ctx.qry.search, ctx.qry.showmsg ? 0 : 1);
+               html(")");
+       }
+       html("</th><th class='left'>Author</th>");
        if (ctx.repo->enable_log_filecount) {
                html("<th class='left'>Files</th>");
                columns++;
                        cgit_log_link("[prev]", NULL, NULL, ctx.qry.head,
                                      ctx.qry.sha1, ctx.qry.path,
                                      ofs - cnt, ctx.qry.grep,
-                                     ctx.qry.search);
+                                     ctx.qry.search, ctx.qry.showmsg);
                        html("&nbsp;");
                }
                if ((commit = get_revision(&rev)) != NULL) {
                        cgit_log_link("[next]", NULL, NULL, ctx.qry.head,
                                      ctx.qry.sha1, ctx.qry.path,
                                      ofs + cnt, ctx.qry.grep,
-                                     ctx.qry.search);
+                                     ctx.qry.search, ctx.qry.showmsg);
                }
                html("</div>");
        } else if ((commit = get_revision(&rev)) != NULL) {
                html("<tr class='nohover'><td colspan='3'>");
                cgit_log_link("[...]", NULL, NULL, ctx.qry.head, NULL, NULL, 0,
-                             NULL, NULL);
+                             NULL, NULL, ctx.qry.showmsg);
                html("</td></tr>\n");
        }
  }
diff --combined ui-refs.c
index 0805fc8e00522373e8527580eb9e12cec5d4cc4d,7eb16d58c1097f2f2e3c5cfb625d7814caea34cb..d61ee7c8d150d1adf5da535148bf9a1114f1440a
+++ b/ui-refs.c
@@@ -58,7 -58,8 +58,8 @@@ static int print_branch(struct refinfo 
        if (!info)
                return 1;
        html("<tr><td>");
-       cgit_log_link(name, NULL, NULL, name, NULL, NULL, 0, NULL, NULL);
+       cgit_log_link(name, NULL, NULL, name, NULL, NULL, 0, NULL, NULL,
+                     ctx.qry.showmsg);
        html("</td><td>");
  
        if (ref->object->type == OBJ_COMMIT) {
  static void print_tag_header()
  {
        html("<tr class='nohover'><th class='left'>Tag</th>"
 -           "<th class='left'>Reference</th>"
 +           "<th class='left'>Download</th>"
             "<th class='left'>Author</th>"
             "<th class='left' colspan='2'>Age</th></tr>\n");
        header = 1;
  }
  
 +static void print_tag_downloads(const struct cgit_repo *repo, const char *ref)
 +{
 +      const struct cgit_snapshot_format* f;
 +      char *filename;
 +      const char *basename;
 +
 +      if (!ref || strlen(ref) < 2)
 +              return;
 +
 +      basename = cgit_repobasename(repo->url);
 +      if (prefixcmp(ref, basename) != 0) {
 +              if ((ref[0] == 'v' || ref[0] == 'V') && isdigit(ref[1]))
 +                      ref++;
 +              if (isdigit(ref[0]))
 +                      ref = xstrdup(fmt("%s-%s", basename, ref));
 +      }
 +
 +      for (f = cgit_snapshot_formats; f->suffix; f++) {
 +              if (!(repo->snapshots & f->bit))
 +                      continue;
 +              filename = fmt("%s%s", ref, f->suffix);
 +              cgit_snapshot_link(filename, NULL, NULL, NULL, NULL, filename);
 +              html("&nbsp;&nbsp;");
 +      }
 +}
  static int print_tag(struct refinfo *ref)
  {
        struct tag *tag;
                html("<tr><td>");
                cgit_tag_link(name, NULL, NULL, ctx.qry.head, name);
                html("</td><td>");
 -              cgit_object_link(tag->tagged);
 +              if (ctx.repo->snapshots && (tag->tagged->type == OBJ_COMMIT))
 +                      print_tag_downloads(ctx.repo, name);
 +              else
 +                      cgit_object_link(tag->tagged);
                html("</td><td>");
                if (info->tagger)
                        html(info->tagger);
                html("<tr><td>");
                html_txt(name);
                html("</td><td>");
 -              cgit_object_link(ref->object);
 +              if (ctx.repo->snapshots && (tag->tagged->type == OBJ_COMMIT))
 +                      print_tag_downloads(ctx.repo, name);
 +              else
 +                      cgit_object_link(ref->object);
                html("</td></tr>\n");
        }
        return 0;
diff --combined ui-repolist.c
index 87196f048548e4c0627b62c67811a102dbc939b6,58331404b7e45482fd3162e6c5f624c89b4c7959..2c13d5041b2a4931358b241b6316db3d96a9a6b5
@@@ -6,10 -6,6 +6,10 @@@
   *   (see COPYING for full license text)
   */
  
 +/* This is needed for strcasestr to be defined by <string.h> */
 +#define _GNU_SOURCE 1
 +#include <string.h>
 +
  #include <time.h>
  
  #include "cgit.h"
@@@ -32,38 -28,21 +32,38 @@@ time_t read_agefile(char *path
                return 0;
  }
  
 -static void print_modtime(struct cgit_repo *repo)
 +static int get_repo_modtime(const struct cgit_repo *repo, time_t *mtime)
  {
        char *path;
        struct stat s;
 +      struct cgit_repo *r = (struct cgit_repo *)repo;
  
 +      if (repo->mtime != -1) {
 +              *mtime = repo->mtime;
 +              return 1;
 +      }
        path = fmt("%s/%s", repo->path, ctx.cfg.agefile);
        if (stat(path, &s) == 0) {
 -              cgit_print_age(read_agefile(path), -1, NULL);
 -              return;
 +              *mtime = read_agefile(path);
 +              r->mtime = *mtime;
 +              return 1;
        }
  
        path = fmt("%s/refs/heads/%s", repo->path, repo->defbranch);
 -      if (stat(path, &s) != 0)
 -              return;
 -      cgit_print_age(s.st_mtime, -1, NULL);
 +      if (stat(path, &s) == 0)
 +              *mtime = s.st_mtime;
 +      else
 +              *mtime = 0;
 +
 +      r->mtime = *mtime;
 +      return (r->mtime != 0);
 +}
 +
 +static void print_modtime(struct cgit_repo *repo)
 +{
 +      time_t t;
 +      if (get_repo_modtime(repo, &t))
 +              cgit_print_age(t, -1, NULL);
  }
  
  int is_match(struct cgit_repo *repo)
@@@ -90,23 -69,13 +90,23 @@@ int is_in_url(struct cgit_repo *repo
        return 0;
  }
  
 +void print_sort_header(const char *title, const char *sort)
 +{
 +      htmlf("<th class='left'><a href='./?s=%s", sort);
 +      if (ctx.qry.search) {
 +              html("&q=");
 +              html_url_arg(ctx.qry.search);
 +      }
 +      htmlf("'>%s</a></th>", title);
 +}
 +
  void print_header(int columns)
  {
 -      html("<tr class='nohover'>"
 -           "<th class='left'>Name</th>"
 -           "<th class='left'>Description</th>"
 -           "<th class='left'>Owner</th>"
 -           "<th class='left'>Idle</th>");
 +      html("<tr class='nohover'>");
 +      print_sort_header("Name", "name");
 +      print_sort_header("Description", "desc");
 +      print_sort_header("Owner", "owner");
 +      print_sort_header("Idle", "idle");
        if (ctx.cfg.enable_index_links)
                html("<th class='left'>Links</th>");
        html("</tr>\n");
@@@ -123,86 -92,10 +123,86 @@@ void print_pager(int items, int pagelen
        html("</div>");
  }
  
 +static int cmp(const char *s1, const char *s2)
 +{
 +      if (s1 && s2)
 +              return strcmp(s1, s2);
 +      if (s1 && !s2)
 +              return -1;
 +      if (s2 && !s1)
 +              return 1;
 +      return 0;
 +}
 +
 +static int sort_name(const void *a, const void *b)
 +{
 +      const struct cgit_repo *r1 = a;
 +      const struct cgit_repo *r2 = b;
 +
 +      return cmp(r1->name, r2->name);
 +}
 +
 +static int sort_desc(const void *a, const void *b)
 +{
 +      const struct cgit_repo *r1 = a;
 +      const struct cgit_repo *r2 = b;
 +
 +      return cmp(r1->desc, r2->desc);
 +}
 +
 +static int sort_owner(const void *a, const void *b)
 +{
 +      const struct cgit_repo *r1 = a;
 +      const struct cgit_repo *r2 = b;
 +
 +      return cmp(r1->owner, r2->owner);
 +}
 +
 +static int sort_idle(const void *a, const void *b)
 +{
 +      const struct cgit_repo *r1 = a;
 +      const struct cgit_repo *r2 = b;
 +      time_t t1, t2;
 +
 +      t1 = t2 = 0;
 +      get_repo_modtime(r1, &t1);
 +      get_repo_modtime(r2, &t2);
 +      return t2 - t1;
 +}
 +
 +struct sortcolumn {
 +      const char *name;
 +      int (*fn)(const void *a, const void *b);
 +};
 +
 +struct sortcolumn sortcolumn[] = {
 +      {"name", sort_name},
 +      {"desc", sort_desc},
 +      {"owner", sort_owner},
 +      {"idle", sort_idle},
 +      {NULL, NULL}
 +};
 +
 +int sort_repolist(char *field)
 +{
 +      struct sortcolumn *column;
 +
 +      for (column = &sortcolumn[0]; column->name; column++) {
 +              if (strcmp(field, column->name))
 +                      continue;
 +              qsort(cgit_repolist.repos, cgit_repolist.count,
 +                      sizeof(struct cgit_repo), column->fn);
 +              return 1;
 +      }
 +      return 0;
 +}
 +
 +
  void cgit_print_repolist()
  {
        int i, columns = 4, hits = 0, header = 0;
        char *last_group = NULL;
 +      int sorted = 0;
  
        if (ctx.cfg.enable_index_links)
                columns++;
        if (ctx.cfg.index_header)
                html_include(ctx.cfg.index_header);
  
 +      if(ctx.qry.sort)
 +              sorted = sort_repolist(ctx.qry.sort);
 +
        html("<table summary='repository list' class='list nowrap'>");
        for (i=0; i<cgit_repolist.count; i++) {
                ctx.repo = &cgit_repolist.repos[i];
                        continue;
                if (!header++)
                        print_header(columns);
 -              if ((last_group == NULL && ctx.repo->group != NULL) ||
 +              if (!sorted &&
 +                  ((last_group == NULL && ctx.repo->group != NULL) ||
                    (last_group != NULL && ctx.repo->group == NULL) ||
                    (last_group != NULL && ctx.repo->group != NULL &&
 -                   strcmp(ctx.repo->group, last_group))) {
 +                   strcmp(ctx.repo->group, last_group)))) {
                        htmlf("<tr class='nohover'><td colspan='%d' class='repogroup'>",
                              columns);
                        html_txt(ctx.repo->group);
                        last_group = ctx.repo->group;
                }
                htmlf("<tr><td class='%s'>",
 -                    ctx.repo->group ? "sublevel-repo" : "toplevel-repo");
 +                    !sorted && ctx.repo->group ? "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("<td>");
                        cgit_summary_link("summary", NULL, "button", NULL);
                        cgit_log_link("log", NULL, "button", NULL, NULL, NULL,
-                                     0, NULL, NULL);
+                                     0, NULL, NULL, ctx.qry.showmsg);
                        cgit_tree_link("tree", NULL, "button", NULL, NULL, NULL);
                        html("</td>");
                }
diff --combined ui-shared.c
index 9319881de108132650bc026bd90f3548162bdbd7,dc39e64ceea8dd0851b2233d72cbbffb704bd25a..95dfeb443e7b41ad2bf438a93396bc90adebc38e
@@@ -281,7 -281,8 +281,8 @@@ void cgit_plain_link(char *name, char *
  }
  
  void cgit_log_link(char *name, char *title, char *class, char *head,
-                  char *rev, char *path, int ofs, char *grep, char *pattern)
+                  char *rev, char *path, int ofs, char *grep, char *pattern,
+                  int showmsg)
  {
        char *delim;
  
                html(delim);
                html("ofs=");
                htmlf("%d", ofs);
+               delim = "&";
+       }
+       if (showmsg) {
+               html(delim);
+               html("showmsg=1");
        }
        html("'>");
        html_txt(name);
@@@ -365,14 -371,11 +371,14 @@@ void cgit_patch_link(char *name, char *
  
  void cgit_object_link(struct object *obj)
  {
 -      char *page, *rev, *name;
 +      char *page, *shortrev, *fullrev, *name;
  
 +      fullrev = sha1_to_hex(obj->sha1);
 +      shortrev = xstrdup(fullrev);
 +      shortrev[10] = '\0';
        if (obj->type == OBJ_COMMIT) {
 -                cgit_commit_link(fmt("commit %s", sha1_to_hex(obj->sha1)), NULL, NULL,
 -                               ctx.qry.head, sha1_to_hex(obj->sha1));
 +                cgit_commit_link(fmt("commit %s...", shortrev), NULL, NULL,
 +                               ctx.qry.head, fullrev);
                return;
        } else if (obj->type == OBJ_TREE)
                page = "tree";
                page = "tag";
        else
                page = "blob";
 -      rev = sha1_to_hex(obj->sha1);
 -      name = fmt("%s %s", typename(obj->type), rev);
 -      reporevlink(page, name, NULL, NULL, ctx.qry.head, rev, NULL);
 +      name = fmt("%s %s...", typename(obj->type), shortrev);
 +      reporevlink(page, name, NULL, NULL, ctx.qry.head, fullrev, NULL);
  }
  
  void cgit_print_date(time_t secs, char *format, int local_time)
@@@ -570,6 -574,8 +576,8 @@@ void add_hidden_formfields(int incl_hea
                html_hidden("id", ctx.qry.sha1);
        if (ctx.qry.sha2)
                html_hidden("id2", ctx.qry.sha2);
+       if (ctx.qry.showmsg)
+               html_hidden("showmsg", "1");
  
        if (incl_search) {
                if (ctx.qry.grep)
@@@ -636,7 -642,7 +644,7 @@@ void cgit_print_pageheader(struct cgit_
                cgit_refs_link("refs", NULL, hc(cmd, "refs"), ctx->qry.head,
                               ctx->qry.sha1, NULL);
                cgit_log_link("log", NULL, hc(cmd, "log"), ctx->qry.head,
-                             NULL, NULL, 0, NULL, NULL);
+                             NULL, NULL, 0, NULL, NULL, ctx->qry.showmsg);
                cgit_tree_link("tree", NULL, hc(cmd, "tree"), ctx->qry.head,
                               ctx->qry.sha1, NULL);
                cgit_commit_link("commit", NULL, hc(cmd, "commit"),
@@@ -709,7 -715,8 +717,7 @@@ void cgit_print_snapshot_links(const ch
                        continue;
                filename = fmt("%s-%s%s", cgit_repobasename(repo), hex,
                               f->suffix);
 -              cgit_snapshot_link(filename, NULL, NULL, (char *)head,
 -                                 (char *)hex, filename);
 +              cgit_snapshot_link(filename, NULL, NULL, NULL, NULL, filename);
                html("<br/>");
        }
  }