Functions for displayin and handling branches
[webgit] / src / branch.c
1 /*
2     cehtehs git web frontend
3
4   Copyright (C)
5     2007, 2008,         Christian Thaeter <ct@pipapo.org>
6
7   This program is free software; you can redistribute it and/or
8   modify it under the terms of the GNU General Public License as
9   published by the Free Software Foundation; either version 2 of the
10   License, or (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program; if not, write to the Free Software
19   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "branch.h"
23 #include "object.h"
24 #include "age.h"
25 #include "log.h"
26
27 #include <cwa.h>
28
29 #define SHA1_HEADER <openssl/sha.h>
30 #include "git/cache.h"
31 #include "git/commit.h"
32 #include "git/refs.h"
33
34 struct branch_context
35 {
36   struct webgit_repo_info* repo;
37   Html table;
38   Html cont;
39   const char* start;
40   int count;
41 };
42
43 Html
44 webgit_branch_link (struct webgit_repo_info* repo, const char* branch, int count, Html text)
45 {
46   return html (
47                html_tag ("a",
48                          html_attr ("href", html(
49                                                  html_fmt ("%s?repo=%s&action=branch",
50                                                            repo->query->request->script_name,
51                                                            repo->name),
52                                                  branch ? html_fmt("&ref=%s", branch) : html (),
53                                                  count > 0 ? html_fmt("&count=%d",
54                                                                       count) : html ()
55                                                  )
56                                     )
57                          ),
58                text
59                );
60
61 }
62
63 static int
64 show_branch_ref (const char *refname, const unsigned char *sha1, int flags, void *data)
65 {
66   (void) flags;
67
68   struct branch_context* ctx = (struct branch_context*) data;
69   struct webgit_repo_info* repo = ctx->repo;
70
71   if (ctx->start)
72     {
73       if (!strcmp (ctx->start, refname))
74         ctx->start = NULL;
75       else
76         return 0;
77     }
78
79   if (!ctx->count--)
80     {
81       /* displayed query->count lines, finish */
82       html_list_append (ctx->cont,
83                         webgit_branch_link (
84                                             repo, refname,
85                                             repo->query->count,
86                                             html ("More..."))
87                         );
88       return 1;
89     }
90
91   struct commit* commit = lookup_commit_reference (sha1);
92
93   unsigned long date =
94     webgit_commit_committer_date_parse (commit, NULL);
95
96   html_list_append (ctx->table,
97                     html (
98                           html_tag ("tr"),
99                           html (
100                                 html_tag ("td"),
101                                 webgit_log_link (repo->query,
102                                                  repo->name,
103                                                  refname,
104                                                  NULL, 0,
105                                                  repo->query->count,
106                                                  html ((char*)refname)
107                                                  )
108                                 ),
109                           html (
110                                 html_tag ("td"),
111                                 webgit_object_link (repo->query,
112                                                     repo->name, strlen(repo->name),
113                                                     sha1_to_hex (sha1), 40,
114                                                     NULL,
115                                                     webgit_pretty_age (repo->query->now - date))
116                                 ),
117                           html (
118                                 html_tag ("td"),
119                                 webgit_email_link (
120                                                    webgit_commit_committer_name_parse (commit),
121                                                    webgit_commit_committer_email_parse (commit)
122                                                    )
123                                 ),
124                           html (
125                                 html_tag ("td"),
126                                 webgit_object_link (repo->query,
127                                                     repo->name, strlen(repo->name),
128                                                     webgit_commit_tree_parse (commit), 40,
129                                                     NULL,
130                                                     html ("Tree")
131                                                     ),
132                                 html (" Snapshot")
133                                 )
134                           )
135                     );
136
137   free(commit->buffer);
138   commit->buffer = NULL;
139   free_commit_list(commit->parents);
140   commit->parents = NULL;
141
142   return 0;
143 }
144
145
146 Html
147 webgit_branch_table (struct webgit_repo_info* repo, const char* head, int count)
148 {
149   struct branch_context ctx;
150   ctx.repo = repo;
151   ctx.table = html_list ();
152   ctx.cont = html_list ();
153   ctx.count = count;
154   ctx.start = head;
155
156   for_each_branch_ref (show_branch_ref, &ctx);
157
158   return html (html ( html_tag ("table"), ctx.table), ctx.cont);
159 }