]> git.pld-linux.org Git - packages/cgit.git/blob - git.patch
24807e0dc30736ef8543d3fa9f627ebc0d2b47b0
[packages/cgit.git] / git.patch
1 diff --git a/Makefile b/Makefile
2 index bbce29d..1127961 100644
3 --- a/Makefile
4 +++ b/Makefile
5 @@ -1,3 +1,5 @@
6 +all::
7 +
8  CGIT_VERSION = v0.9.1
9  CGIT_SCRIPT_NAME = cgit.cgi
10  CGIT_SCRIPT_PATH = /var/www/htdocs/cgit
11 @@ -12,8 +14,8 @@ htmldir = $(docdir)
12  pdfdir = $(docdir)
13  mandir = $(prefix)/share/man
14  SHA1_HEADER = <openssl/sha.h>
15 -GIT_VER = 1.7.4
16 -GIT_URL = https://github.com/git/git/archive/v$(GIT_VER).tar.gz
17 +GIT_VER = 1.7.12.4
18 +GIT_URL = https://git-core.googlecode.com/files/git-$(GIT_VER).tar.gz
19  INSTALL = install
20  MAN5_TXT = $(wildcard *.5.txt)
21  MAN_TXT  = $(MAN5_TXT)
22 @@ -40,22 +42,14 @@ DOC_PDF  = $(patsubst %.txt,%.pdf,$(MAN_TXT))
23  # Platform specific tweaks
24  #
25  
26 +VERSION: force-version
27 +       @./gen-version.sh "$(CGIT_VERSION)"
28 +-include VERSION
29 +
30  uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
31  uname_O := $(shell sh -c 'uname -o 2>/dev/null || echo not')
32  uname_R := $(shell sh -c 'uname -r 2>/dev/null || echo not')
33  
34 -ifeq ($(uname_O),Cygwin)
35 -       NO_STRCASESTR = YesPlease
36 -       NEEDS_LIBICONV = YesPlease
37 -endif
38 -
39 -ifeq ($(uname_S),$(filter $(uname_S),FreeBSD OpenBSD))
40 -       # Apparantly libiconv is installed in /usr/local on BSD
41 -       LDFLAGS ?= -L/usr/local/lib
42 -       CFLAGS ?= -I/usr/local/include
43 -       NEEDS_LIBICONV = yes
44 -endif
45 -
46  #
47  # Let the user override the above settings.
48  #
49 @@ -76,30 +70,62 @@ endif
50  
51  ifndef V
52         QUIET_CC       = @echo '   ' CC $@;
53 -       QUIET_MM       = @echo '   ' MM $@;
54 +       QUIET_LINK     = @echo '   ' LINK $@;
55         QUIET_SUBDIR0  = +@subdir=
56         QUIET_SUBDIR1  = ;$(NO_SUBDIR) echo '   ' SUBDIR $$subdir; \
57                          $(MAKE) $(PRINT_DIR) -C $$subdir
58         QUIET_TAGS     = @echo '   ' TAGS $@;
59 +       export V
60  endif
61  
62 -#
63 -# Define a pattern rule for automatic dependency building
64 -#
65 -%.d: %.c
66 -       $(QUIET_MM)$(CC) $(CFLAGS) -MM -MP $< | sed -e 's/\($*\)\.o:/\1.o $@:/g' >$@
67 +LDFLAGS ?=
68 +CFLAGS ?= -g -Wall
69 +CFLAGS += -Igit
70 +CFLAGS += -DSHA1_HEADER='$(SHA1_HEADER)'
71 +CFLAGS += -DCGIT_VERSION='"$(CGIT_VERSION)"'
72 +CFLAGS += -DCGIT_CONFIG='"$(CGIT_CONFIG)"'
73 +CFLAGS += -DCGIT_SCRIPT_NAME='"$(CGIT_SCRIPT_NAME)"'
74 +CFLAGS += -DCGIT_CACHE_ROOT='"$(CACHE_ROOT)"'
75  
76 -#
77 -# Define a pattern rule for silent object building
78 -#
79 -%.o: %.c
80 -       $(QUIET_CC)$(CC) -o $*.o -c $(CFLAGS) $<
81 +ifeq ($(uname_O),Cygwin)
82 +       NO_STRCASESTR = YesPlease
83 +       NEEDS_LIBICONV = YesPlease
84 +endif
85  
86 +ifeq ($(uname_S),$(filter $(uname_S),FreeBSD OpenBSD))
87 +       # Apparantly libiconv is installed in /usr/local on BSD
88 +       LDFLAGS += -L/usr/local/lib
89 +       CFLAGS += -I/usr/local/include
90 +       NEEDS_LIBICONV = yes
91 +endif
92  
93 -EXTLIBS = git/libgit.a git/xdiff/lib.a -lz -lpthread
94 +GIT_OPTIONS = prefix=/usr NO_GETTEXT=1
95  OBJECTS =
96 -OBJECTS += cache.o
97 +
98 +ifdef NO_ICONV
99 +       CFLAGS += -DNO_ICONV
100 +endif
101 +ifdef NO_STRCASESTR
102 +       CFLAGS += -DNO_STRCASESTR
103 +endif
104 +ifdef NO_C99_FORMAT
105 +       CFLAGS += -DNO_C99_FORMAT
106 +endif
107 +ifdef NO_OPENSSL
108 +       CFLAGS += -DNO_OPENSSL
109 +       GIT_OPTIONS += NO_OPENSSL=1
110 +else
111 +       LDLIBS += -lcrypto
112 +endif
113 +
114 +ifdef NEEDS_LIBICONV
115 +       LDLIBS += -liconv
116 +endif
117 +
118 +LDLIBS += git/libgit.a git/xdiff/lib.a -lz -lpthread
119 +
120  OBJECTS += cgit.o
121 +OBJECTS += cache.o
122  OBJECTS += cmd.o
123  OBJECTS += configfile.o
124  OBJECTS += html.o
125 @@ -125,55 +151,30 @@ OBJECTS += ui-tag.o
126  OBJECTS += ui-tree.o
127  OBJECTS += vector.o
128  
129 -ifdef NEEDS_LIBICONV
130 -       EXTLIBS += -liconv
131 -endif
132 -
133 -
134 -.PHONY: all libgit test install uninstall clean force-version get-git \
135 -       doc clean-doc install-doc install-man install-html install-pdf \
136 -       uninstall-doc uninstall-man uninstall-html uninstall-pdf tags
137 +dep_files := $(foreach f,$(OBJECTS),$(dir $f).deps/$(notdir $f).d)
138 +dep_dirs := $(addsuffix .deps,$(sort $(dir $OBJECTS)))
139  
140 -all: cgit
141 +$(dep_dirs):
142 +       @mkdir -p $@
143  
144 -VERSION: force-version
145 -       @./gen-version.sh "$(CGIT_VERSION)"
146 --include VERSION
147 +missing_dep_dirs := $(filter-out $(wildcard $(dep_dirs)),$(dep_dirs))
148 +dep_file = $(dir $@).deps/$(notdir $@).d
149 +dep_args = -MF $(dep_file) -MMD -MP
150  
151 +.SUFFIXES:
152  
153 -CFLAGS += -g -Wall -Igit
154 -CFLAGS += -DSHA1_HEADER='$(SHA1_HEADER)'
155 -CFLAGS += -DCGIT_VERSION='"$(CGIT_VERSION)"'
156 -CFLAGS += -DCGIT_CONFIG='"$(CGIT_CONFIG)"'
157 -CFLAGS += -DCGIT_SCRIPT_NAME='"$(CGIT_SCRIPT_NAME)"'
158 -CFLAGS += -DCGIT_CACHE_ROOT='"$(CACHE_ROOT)"'
159 -
160 -GIT_OPTIONS = prefix=/usr
161 +$(OBJECTS): %.o: %.c $(missing_dep_dirs)
162 +       $(QUIET_CC)$(CC) -o $*.o -c $(dep_args) $(CFLAGS) $<
163  
164 -ifdef NO_ICONV
165 -       CFLAGS += -DNO_ICONV
166 +dep_files_present := $(wildcard $(dep_files))
167 +ifneq ($(dep_files_present),)
168 +include $(dep_files_present)
169  endif
170 -ifdef NO_STRCASESTR
171 -       CFLAGS += -DNO_STRCASESTR
172 -endif
173 -ifdef NO_C99_FORMAT
174 -       CFLAGS += -DNO_C99_FORMAT
175 -endif
176 -ifdef NO_OPENSSL
177 -       CFLAGS += -DNO_OPENSSL
178 -       GIT_OPTIONS += NO_OPENSSL=1
179 -else
180 -       EXTLIBS += -lcrypto
181 -endif
182 -
183 -cgit: $(OBJECTS) libgit
184 -       $(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) -o cgit $(OBJECTS) $(EXTLIBS)
185  
186 -cgit.o: VERSION
187 +all:: cgit
188  
189 -ifneq "$(MAKECMDGOALS)" "clean"
190 -  -include $(OBJECTS:.o=.d)
191 -endif
192 +cgit: VERSION $(OBJECTS) libgit
193 +       $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) $(LDLIBS)
194  
195  libgit:
196         $(QUIET_SUBDIR0)git $(QUIET_SUBDIR1) NO_CURL=1 $(GIT_OPTIONS) libgit.a
197 @@ -243,13 +244,24 @@ $(DOC_PDF): %.pdf : %.txt
198         a2x -f pdf cgitrc.5.txt
199  
200  clean: clean-doc
201 -       rm -f cgit VERSION *.o *.d tags
202 +       $(RM) cgit VERSION *.o tags
203 +       $(RM) -r .deps
204 +
205 +cleanall: clean
206 +       $(MAKE) -C git clean
207  
208  clean-doc:
209 -       rm -f cgitrc.5 cgitrc.5.html cgitrc.5.pdf cgitrc.5.xml cgitrc.5.fo
210 +       $(RM) cgitrc.5 cgitrc.5.html cgitrc.5.pdf cgitrc.5.xml cgitrc.5.fo
211  
212  get-git:
213         curl -L $(GIT_URL) | tar -xzf - && rm -rf git && mv git-$(GIT_VER) git
214  
215  tags:
216         $(QUIET_TAGS)find . -name '*.[ch]' | xargs ctags
217 +
218 +.PHONY: all cgit get-git libgit force-version
219 +.PHONY: clean clean-doc cleanall
220 +.PHONY: doc doc-html doc-man doc-pdf
221 +.PHONY: install install-doc install-html install-man install-pdf
222 +.PHONY: tags test
223 +.PHONY: uninstall uninstall-doc uninstall-html uninstall-man uninstall-pdf
224 diff --git a/cache.c b/cache.c
225 index d7a8d5a..47cdcb4 100644
226 --- a/cache.c
227 +++ b/cache.c
228 @@ -105,7 +105,7 @@ static int is_expired(struct cache_slot *slot)
229         if (slot->ttl < 0)
230                 return 0;
231         else
232 -               return slot->cache_st.st_mtime + slot->ttl*60 < time(NULL);
233 +               return slot->cache_st.st_mtime + slot->ttl * 60 < time(NULL);
234  }
235  
236  /* Check if the slot has been modified since we opened it.
237 @@ -141,8 +141,8 @@ static int close_lock(struct cache_slot *slot)
238   */
239  static int lock_slot(struct cache_slot *slot)
240  {
241 -       slot->lock_fd = open(slot->lock_name, O_RDWR|O_CREAT|O_EXCL,
242 -                            S_IRUSR|S_IWUSR);
243 +       slot->lock_fd = open(slot->lock_name, O_RDWR | O_CREAT | O_EXCL,
244 +                            S_IRUSR | S_IWUSR);
245         if (slot->lock_fd == -1)
246                 return errno;
247         if (xwrite(slot->lock_fd, slot->key, slot->keylen + 1) < 0)
248 @@ -214,7 +214,7 @@ unsigned long hash_str(const char *str)
249         if (!s)
250                 return h;
251  
252 -       while(*s) {
253 +       while (*s) {
254                 h *= FNV_PRIME;
255                 h ^= *s++;
256         }
257 @@ -342,7 +342,7 @@ int cache_process(int size, const char *path, const char *key, int ttl,
258         strcpy(filename, path);
259         if (filename[len - 1] != '/')
260                 filename[len++] = '/';
261 -       for(i = 0; i < 8; i++) {
262 +       for (i = 0; i < 8; i++) {
263                 sprintf(filename + len++, "%x",
264                         (unsigned char)(hash & 0xf));
265                 hash >>= 4;
266 @@ -407,7 +407,7 @@ int cache_ls(const char *path)
267                 *name = '\0';
268         }
269         slot.cache_name = fullname;
270 -       while((ent = readdir(dir)) != NULL) {
271 +       while ((ent = readdir(dir)) != NULL) {
272                 if (strlen(ent->d_name) != 8)
273                         continue;
274                 strcpy(name, ent->d_name);
275 diff --git a/cgit.c b/cgit.c
276 index a97ed69..2ccf864 100644
277 --- a/cgit.c
278 +++ b/cgit.c
279 @@ -172,6 +172,8 @@ void config_cb(const char *name, const char *value)
280                 ctx.cfg.enable_http_clone = atoi(value);
281         else if (!strcmp(name, "enable-index-links"))
282                 ctx.cfg.enable_index_links = atoi(value);
283 +       else if (!strcmp(name, "enable-index-owner"))
284 +               ctx.cfg.enable_index_owner = atoi(value);
285         else if (!strcmp(name, "enable-commit-graph"))
286                 ctx.cfg.enable_commit_graph = atoi(value);
287         else if (!strcmp(name, "enable-log-filecount"))
288 @@ -313,7 +315,7 @@ static void querystring_cb(const char *name, const char *value)
289                 ctx.qry.name = xstrdup(value);
290         } else if (!strcmp(name, "mimetype")) {
291                 ctx.qry.mimetype = xstrdup(value);
292 -       } else if (!strcmp(name, "s")){
293 +       } else if (!strcmp(name, "s")) {
294                 ctx.qry.sort = xstrdup(value);
295         } else if (!strcmp(name, "showmsg")) {
296                 ctx.qry.showmsg = atoi(value);
297 @@ -354,6 +356,7 @@ static void prepare_context(struct cgit_context *ctx)
298         ctx->cfg.logo = "/cgit.png";
299         ctx->cfg.local_time = 0;
300         ctx->cfg.enable_http_clone = 1;
301 +       ctx->cfg.enable_index_owner = 1;
302         ctx->cfg.enable_tree_linenumbers = 1;
303         ctx->cfg.enable_git_config = 0;
304         ctx->cfg.max_repo_count = 50;
305 @@ -442,12 +445,12 @@ char *find_default_branch(struct cgit_repo *repo)
306         return ref;
307  }
308  
309 -static char *guess_defbranch(const char *repo_path)
310 +static char *guess_defbranch(void)
311  {
312         const char *ref;
313         unsigned char sha1[20];
314  
315 -       ref = resolve_ref("HEAD", sha1, 0, NULL);
316 +       ref = resolve_ref_unsafe("HEAD", sha1, 0, NULL);
317         if (!ref || prefixcmp(ref, "refs/heads/"))
318                 return "master";
319         return xstrdup(ref + 11);
320 @@ -480,7 +483,7 @@ static int prepare_repo_cmd(struct cgit_context *ctx)
321         ctx->page.title = fmt("%s - %s", ctx->repo->name, ctx->repo->desc);
322  
323         if (!ctx->repo->defbranch)
324 -               ctx->repo->defbranch = guess_defbranch(ctx->repo->path);
325 +               ctx->repo->defbranch = guess_defbranch();
326  
327         if (!ctx->qry.head) {
328                 ctx->qry.nohead = 1;
329 @@ -650,7 +653,7 @@ void print_repolist(FILE *f, struct cgit_repolist *list, int start)
330  {
331         int i;
332  
333 -       for(i = start; i < list->count; i++)
334 +       for (i = start; i < list->count; i++)
335                 print_repo(f, &list->repos[i]);
336  }
337  
338 @@ -738,7 +741,7 @@ static void cgit_parse_args(int argc, const char **argv)
339  
340         for (i = 1; i < argc; i++) {
341                 if (!strncmp(argv[i], "--cache=", 8)) {
342 -                       ctx.cfg.cache_root = xstrdup(argv[i]+8);
343 +                       ctx.cfg.cache_root = xstrdup(argv[i] + 8);
344                 }
345                 if (!strcmp(argv[i], "--nocache")) {
346                         ctx.cfg.nocache = 1;
347 @@ -747,24 +750,24 @@ static void cgit_parse_args(int argc, const char **argv)
348                         ctx.env.no_http = "1";
349                 }
350                 if (!strncmp(argv[i], "--query=", 8)) {
351 -                       ctx.qry.raw = xstrdup(argv[i]+8);
352 +                       ctx.qry.raw = xstrdup(argv[i] + 8);
353                 }
354                 if (!strncmp(argv[i], "--repo=", 7)) {
355 -                       ctx.qry.repo = xstrdup(argv[i]+7);
356 +                       ctx.qry.repo = xstrdup(argv[i] + 7);
357                 }
358                 if (!strncmp(argv[i], "--page=", 7)) {
359 -                       ctx.qry.page = xstrdup(argv[i]+7);
360 +                       ctx.qry.page = xstrdup(argv[i] + 7);
361                 }
362                 if (!strncmp(argv[i], "--head=", 7)) {
363 -                       ctx.qry.head = xstrdup(argv[i]+7);
364 +                       ctx.qry.head = xstrdup(argv[i] + 7);
365                         ctx.qry.has_symref = 1;
366                 }
367                 if (!strncmp(argv[i], "--sha1=", 7)) {
368 -                       ctx.qry.sha1 = xstrdup(argv[i]+7);
369 +                       ctx.qry.sha1 = xstrdup(argv[i] + 7);
370                         ctx.qry.has_sha1 = 1;
371                 }
372                 if (!strncmp(argv[i], "--ofs=", 6)) {
373 -                       ctx.qry.ofs = atoi(argv[i]+6);
374 +                       ctx.qry.ofs = atoi(argv[i] + 6);
375                 }
376                 if (!strncmp(argv[i], "--scan-tree=", 12) ||
377                     !strncmp(argv[i], "--scan-path=", 12)) {
378 @@ -831,7 +834,7 @@ int main(int argc, const char **argv)
379                 ctx.cfg.virtual_root = trim_end(ctx.cfg.script_name, '/');
380                 if (!ctx.cfg.virtual_root)
381                         ctx.cfg.virtual_root = "";
382 -        }
383 +       }
384  
385         /* If no url parameter is specified on the querystring, lets
386          * use PATH_INFO as url. This allows cgit to work with virtual
387 @@ -853,7 +856,7 @@ int main(int argc, const char **argv)
388         }
389  
390         ttl = calc_ttl();
391 -       ctx.page.expires += ttl*60;
392 +       ctx.page.expires += ttl * 60;
393         if (ctx.env.request_method && !strcmp(ctx.env.request_method, "HEAD"))
394                 ctx.cfg.nocache = 1;
395         if (ctx.cfg.nocache)
396 diff --git a/cgit.h b/cgit.h
397 index 7a99135..c655bd8 100644
398 --- a/cgit.h
399 +++ b/cgit.h
400 @@ -11,6 +11,7 @@
401  #include <tag.h>
402  #include <diff.h>
403  #include <diffcore.h>
404 +#include <argv-array.h>
405  #include <refs.h>
406  #include <revision.h>
407  #include <log-tree.h>
408 @@ -203,6 +204,7 @@ struct cgit_config {
409         int enable_filter_overrides;
410         int enable_http_clone;
411         int enable_index_links;
412 +       int enable_index_owner;
413         int enable_commit_graph;
414         int enable_log_filecount;
415         int enable_log_linecount;
416 @@ -273,6 +275,8 @@ struct cgit_context {
417         struct cgit_page page;
418  };
419  
420 +typedef int (*write_archive_fn_t)(const char *, const char *);
421 +
422  struct cgit_snapshot_format {
423         const char *suffix;
424         const char *mimetype;
425 diff --git a/cgitrc.5.txt b/cgitrc.5.txt
426 index 95a1049..4d27d9f 100644
427 --- a/cgitrc.5.txt
428 +++ b/cgitrc.5.txt
429 @@ -120,6 +120,10 @@ enable-index-links::
430         each repo in the repository index (specifically, to the "summary",
431         "commit" and "tree" pages). Default value: "0".
432  
433 +enable-index-owner::
434 +       Flag which, when set to "1", will make cgit display the owner of
435 +       each repo in the repository index. Default value: "1".
436 +
437  enable-log-filecount::
438         Flag which, when set to "1", will make cgit print the number of
439         modified files for each commit on the repository log page. Default
440 @@ -244,8 +248,8 @@ mimetype-file::
441         Specifies the file to use for automatic mimetype lookup. If specified
442         then this field is used as a fallback when no "mimetype.<ext>" match is
443         found. If unspecified then no such lookup is performed. The typical file
444 -       to use on a Linux system is /etc/mime.types. Default value: none. See
445 -       also: "mimetype.<ext>". The format of the file must comply to:
446 +       to use on a Linux system is /etc/mime.types. The format of the file must
447 +       comply to:
448         - a comment line is an empty line or a line starting with a hash (#),
449           optionally preceded by whitespace
450         - a non-comment line starts with the mimetype (like image/png), followed
451 diff --git a/cmd.c b/cmd.c
452 index 899e913..198bf2f 100644
453 --- a/cmd.c
454 +++ b/cmd.c
455 @@ -166,7 +166,7 @@ struct cgit_cmd *cgit_get_cmd(struct cgit_context *ctx)
456                         ctx->qry.page = "repolist";
457         }
458  
459 -       for(i = 0; i < sizeof(cmds)/sizeof(*cmds); i++)
460 +       for (i = 0; i < sizeof(cmds)/sizeof(*cmds); i++)
461                 if (!strcmp(ctx->qry.page, cmds[i].name))
462                         return &cmds[i];
463         return NULL;
464 diff --git a/configfile.c b/configfile.c
465 index 4908058..3fa217f 100644
466 --- a/configfile.c
467 +++ b/configfile.c
468 @@ -13,9 +13,9 @@
469  int next_char(FILE *f)
470  {
471         int c = fgetc(f);
472 -       if (c=='\r') {
473 +       if (c == '\r') {
474                 c = fgetc(f);
475 -               if (c!='\n') {
476 +               if (c != '\n') {
477                         ungetc(c, f);
478                         c = '\r';
479                 }
480 @@ -27,7 +27,7 @@ void skip_line(FILE *f)
481  {
482         int c;
483  
484 -       while((c=next_char(f)) && c!='\n' && c!=EOF)
485 +       while ((c = next_char(f)) && c != '\n' && c != EOF)
486                 ;
487  }
488  
489 @@ -36,31 +36,31 @@ int read_config_line(FILE *f, char *line, const char **value, int bufsize)
490         int i = 0, isname = 0;
491  
492         *value = NULL;
493 -       while(i<bufsize-1) {
494 +       while (i < bufsize - 1) {
495                 int c = next_char(f);
496 -               if (!isname && (c=='#' || c==';')) {
497 +               if (!isname && (c == '#' || c == ';')) {
498                         skip_line(f);
499                         continue;
500                 }
501                 if (!isname && isspace(c))
502                         continue;
503  
504 -               if (c=='=' && !*value) {
505 +               if (c == '=' && !*value) {
506                         line[i] = 0;
507 -                       *value = &line[i+1];
508 -               } else if (c=='\n' && !isname) {
509 +                       *value = &line[i + 1];
510 +               } else if (c == '\n' && !isname) {
511                         i = 0;
512                         continue;
513 -               } else if (c=='\n' || c==EOF) {
514 +               } else if (c == '\n' || c == EOF) {
515                         line[i] = 0;
516                         break;
517                 } else {
518 -                       line[i]=c;
519 +                       line[i] = c;
520                 }
521                 isname = 1;
522                 i++;
523         }
524 -       line[i+1] = 0;
525 +       line[i + 1] = 0;
526         return i;
527  }
528  
529 @@ -78,7 +78,7 @@ int parse_configfile(const char *filename, configfile_value_fn fn)
530         if (!(f = fopen(filename, "r")))
531                 return -1;
532         nesting++;
533 -       while((len = read_config_line(f, line, &value, sizeof(line))) > 0)
534 +       while ((len = read_config_line(f, line, &value, sizeof(line))) > 0)
535                 fn(line, value);
536         nesting--;
537         fclose(f);
538 diff --git a/html.c b/html.c
539 index 8f6e4f6..90cc1c0 100644
540 --- a/html.c
541 +++ b/html.c
542 @@ -54,7 +54,7 @@ char *fmt(const char *format, ...)
543         va_start(args, format);
544         len = vsnprintf(buf[bufidx], sizeof(buf[bufidx]), format, args);
545         va_end(args);
546 -       if (len>sizeof(buf[bufidx])) {
547 +       if (len > sizeof(buf[bufidx])) {
548                 fprintf(stderr, "[html.c] string truncated: %s\n", format);
549                 exit(1);
550         }
551 @@ -92,93 +92,93 @@ void html_status(int code, const char *msg, int more_headers)
552  void html_txt(const char *txt)
553  {
554         const char *t = txt;
555 -       while(t && *t){
556 +       while (t && *t) {
557                 int c = *t;
558 -               if (c=='<' || c=='>' || c=='&') {
559 +               if (c == '<' || c == '>' || c == '&') {
560                         html_raw(txt, t - txt);
561 -                       if (c=='>')
562 +                       if (c == '>')
563                                 html("&gt;");
564 -                       else if (c=='<')
565 +                       else if (c == '<')
566                                 html("&lt;");
567 -                       else if (c=='&')
568 +                       else if (c == '&')
569                                 html("&amp;");
570 -                       txt = t+1;
571 +                       txt = t + 1;
572                 }
573                 t++;
574         }
575 -       if (t!=txt)
576 +       if (t != txt)
577                 html(txt);
578  }
579  
580  void html_ntxt(int len, const char *txt)
581  {
582         const char *t = txt;
583 -       while(t && *t && len--){
584 +       while (t && *t && len--) {
585                 int c = *t;
586 -               if (c=='<' || c=='>' || c=='&') {
587 +               if (c == '<' || c == '>' || c == '&') {
588                         html_raw(txt, t - txt);
589 -                       if (c=='>')
590 +                       if (c == '>')
591                                 html("&gt;");
592 -                       else if (c=='<')
593 +                       else if (c == '<')
594                                 html("&lt;");
595 -                       else if (c=='&')
596 +                       else if (c == '&')
597                                 html("&amp;");
598 -                       txt = t+1;
599 +                       txt = t + 1;
600                 }
601                 t++;
602         }
603 -       if (t!=txt)
604 +       if (t != txt)
605                 html_raw(txt, t - txt);
606 -       if (len<0)
607 +       if (len < 0)
608                 html("...");
609  }
610  
611  void html_attr(const char *txt)
612  {
613         const char *t = txt;
614 -       while(t && *t){
615 +       while (t && *t) {
616                 int c = *t;
617 -               if (c=='<' || c=='>' || c=='\'' || c=='\"' || c=='&') {
618 +               if (c == '<' || c == '>' || c == '\'' || c == '\"' || c == '&') {
619                         html_raw(txt, t - txt);
620 -                       if (c=='>')
621 +                       if (c == '>')
622                                 html("&gt;");
623 -                       else if (c=='<')
624 +                       else if (c == '<')
625                                 html("&lt;");
626 -                       else if (c=='\'')
627 +                       else if (c == '\'')
628                                 html("&#x27;");
629 -                       else if (c=='"')
630 +                       else if (c == '"')
631                                 html("&quot;");
632 -                       else if (c=='&')
633 +                       else if (c == '&')
634                                 html("&amp;");
635 -                       txt = t+1;
636 +                       txt = t + 1;
637                 }
638                 t++;
639         }
640 -       if (t!=txt)
641 +       if (t != txt)
642                 html(txt);
643  }
644  
645  void html_url_path(const char *txt)
646  {
647         const char *t = txt;
648 -       while(t && *t){
649 +       while (t && *t) {
650                 unsigned char c = *t;
651                 const char *e = url_escape_table[c];
652 -               if (e && c!='+' && c!='&') {
653 +               if (e && c != '+' && c != '&') {
654                         html_raw(txt, t - txt);
655                         html(e);
656 -                       txt = t+1;
657 +                       txt = t + 1;
658                 }
659                 t++;
660         }
661 -       if (t!=txt)
662 +       if (t != txt)
663                 html(txt);
664  }
665  
666  void html_url_arg(const char *txt)
667  {
668         const char *t = txt;
669 -       while(t && *t){
670 +       while (t && *t) {
671                 unsigned char c = *t;
672                 const char *e = url_escape_table[c];
673                 if (c == ' ')
674 @@ -186,11 +186,11 @@ void html_url_arg(const char *txt)
675                 if (e) {
676                         html_raw(txt, t - txt);
677                         html(e);
678 -                       txt = t+1;
679 +                       txt = t + 1;
680                 }
681                 t++;
682         }
683 -       if (t!=txt)
684 +       if (t != txt)
685                 html(txt);
686  }
687  
688 @@ -260,7 +260,7 @@ int html_include(const char *filename)
689                         filename, strerror(errno), errno);
690                 return -1;
691         }
692 -       while((len = fread(buf, 1, 4096, f)) > 0)
693 +       while ((len = fread(buf, 1, 4096, f)) > 0)
694                 html_raw(buf, len);
695         fclose(f);
696         return 0;
697 @@ -286,14 +286,14 @@ char *convert_query_hexchar(char *txt)
698                 *txt = '\0';
699                 return txt-1;
700         }
701 -       d1 = hextoint(*(txt+1));
702 -       d2 = hextoint(*(txt+2));
703 -       if (d1<0 || d2<0) {
704 -               memmove(txt, txt+3, n-2);
705 +       d1 = hextoint(*(txt + 1));
706 +       d2 = hextoint(*(txt + 2));
707 +       if (d1 < 0 || d2 < 0) {
708 +               memmove(txt, txt + 3, n - 2);
709                 return txt-1;
710         } else {
711                 *txt = d1 * 16 + d2;
712 -               memmove(txt+1, txt+3, n-2);
713 +               memmove(txt + 1, txt + 3, n - 2);
714                 return txt;
715         }
716  }
717 @@ -310,23 +310,23 @@ int http_parse_querystring(const char *txt_, void (*fn)(const char *name, const
718                 printf("Out of memory\n");
719                 exit(1);
720         }
721 -       while((c=*t) != '\0') {
722 -               if (c=='=') {
723 +       while ((c=*t) != '\0') {
724 +               if (c == '=') {
725                         *t = '\0';
726 -                       value = t+1;
727 -               } else if (c=='+') {
728 +                       value = t + 1;
729 +               } else if (c == '+') {
730                         *t = ' ';
731 -               } else if (c=='%') {
732 +               } else if (c == '%') {
733                         t = convert_query_hexchar(t);
734 -               } else if (c=='&') {
735 +               } else if (c == '&') {
736                         *t = '\0';
737                         (*fn)(txt, value);
738 -                       txt = t+1;
739 +                       txt = t + 1;
740                         value = NULL;
741                 }
742                 t++;
743         }
744 -       if (t!=txt)
745 +       if (t != txt)
746                 (*fn)(txt, value);
747         free(o);
748         return 0;
749 diff --git a/parsing.c b/parsing.c
750 index 1b2a551..9b7efb3 100644
751 --- a/parsing.c
752 +++ b/parsing.c
753 @@ -112,7 +112,7 @@ const char *reencode(char **txt, const char *src_enc, const char *dst_enc)
754                 return *txt;
755  
756         /* no encoding needed if src_enc equals dst_enc */
757 -       if(!strcasecmp(src_enc, dst_enc))
758 +       if (!strcasecmp(src_enc, dst_enc))
759                 return *txt;
760  
761         tmp = reencode_string(*txt, dst_enc, src_enc);
762 @@ -170,7 +170,7 @@ struct commitinfo *cgit_parse_commit(struct commit *commit)
763         }
764  
765         /* if no special encoding is found, assume UTF-8 */
766 -       if(!ret->msg_encoding)
767 +       if (!ret->msg_encoding)
768                 ret->msg_encoding = xstrdup("UTF-8");
769  
770         // skip unknown header fields
771 diff --git a/scan-tree.c b/scan-tree.c
772 index 6ce8036..10d90f4 100644
773 --- a/scan-tree.c
774 +++ b/scan-tree.c
775 @@ -106,7 +106,7 @@ static void add_repo(const char *base, const char *path, repo_config_fn fn)
776         config_fn = fn;
777         if (ctx.cfg.enable_git_config)
778                 git_config_from_file(gitconfig_config, fmt("%s/config", path), NULL);
779 -       
780 +
781         if (ctx.cfg.remove_suffix)
782                 if ((p = strrchr(repo->url, '.')) && !strcmp(p, ".git"))
783                         *p = '\0';
784 @@ -185,7 +185,7 @@ static void scan_path(const char *base, const char *path, repo_config_fn fn)
785                 add_repo(base, fmt("%s/.git", path), fn);
786                 goto end;
787         }
788 -       while((ent = readdir(dir)) != NULL) {
789 +       while ((ent = readdir(dir)) != NULL) {
790                 if (ent->d_name[0] == '.') {
791                         if (ent->d_name[1] == '\0')
792                                 continue;
793 @@ -222,7 +222,7 @@ void scan_projects(const char *path, const char *projectsfile, repo_config_fn fn
794         char line[MAX_PATH * 2], *z;
795         FILE *projects;
796         int err;
797 -       
798 +
799         projects = fopen(projectsfile, "r");
800         if (!projects) {
801                 fprintf(stderr, "Error opening projectsfile %s: %s (%d)\n",
802 diff --git a/shared.c b/shared.c
803 index 8e5ae48..e732064 100644
804 --- a/shared.c
805 +++ b/shared.c
806 @@ -28,8 +28,8 @@ int chk_positive(int result, char *msg)
807  
808  int chk_non_negative(int result, char *msg)
809  {
810 -       if (result < 0)
811 -               die("%s: %s",msg, strerror(errno));
812 +       if (result < 0)
813 +               die("%s: %s", msg, strerror(errno));
814         return result;
815  }
816  
817 @@ -80,7 +80,7 @@ struct cgit_repo *cgit_get_repoinfo(const char *url)
818         int i;
819         struct cgit_repo *repo;
820  
821 -       for (i=0; i<cgit_repolist.count; i++) {
822 +       for (i = 0; i < cgit_repolist.count; i++) {
823                 repo = &cgit_repolist.repos[i];
824                 if (!strcmp(repo->url, url))
825                         return repo;
826 @@ -108,7 +108,7 @@ char *trim_end(const char *str, char c)
827         if (str == NULL)
828                 return NULL;
829         len = strlen(str);
830 -       while(len > 0 && str[len - 1] == c)
831 +       while (len > 0 && str[len - 1] == c)
832                 len--;
833         if (len == 0)
834                 return NULL;
835 @@ -207,7 +207,7 @@ static int load_mmfile(mmfile_t *file, const unsigned char *sha1)
836                 file->ptr = (char *)"";
837                 file->size = 0;
838         } else {
839 -               file->ptr = read_sha1_file(sha1, &type, 
840 +               file->ptr = read_sha1_file(sha1, &type,
841                                            (unsigned long *)&file->size);
842         }
843         return 1;
844 @@ -307,7 +307,7 @@ void cgit_diff_tree(const unsigned char *old_sha1,
845                     filepair_fn fn, const char *prefix, int ignorews)
846  {
847         struct diff_options opt;
848 -       int prefixlen;
849 +       struct pathspec_item item;
850  
851         diff_setup(&opt);
852         opt.output_format = DIFF_FORMAT_CALLBACK;
853 @@ -319,10 +319,10 @@ void cgit_diff_tree(const unsigned char *old_sha1,
854         opt.format_callback = cgit_diff_tree_cb;
855         opt.format_callback_data = fn;
856         if (prefix) {
857 -               opt.nr_paths = 1;
858 -               opt.paths = &prefix;
859 -               prefixlen = strlen(prefix);
860 -               opt.pathlens = &prefixlen;
861 +               item.match = prefix;
862 +               item.len = strlen(prefix);
863 +               opt.pathspec.nr = 1;
864 +               opt.pathspec.items = &item;
865         }
866         diff_setup_done(&opt);
867  
868 @@ -351,17 +351,17 @@ int cgit_parse_snapshots_mask(const char *str)
869         int tl, sl, rv = 0;
870  
871         /* favor legacy setting */
872 -       if(atoi(str))
873 +       if (atoi(str))
874                 return 1;
875 -       for(;;) {
876 -               str += strspn(str,delim);
877 -               tl = strcspn(str,delim);
878 +       for (;;) {
879 +               str += strspn(str, delim);
880 +               tl = strcspn(str, delim);
881                 if (!tl)
882                         break;
883                 for (f = cgit_snapshot_formats; f->suffix; f++) {
884                         sl = strlen(f->suffix);
885 -                       if((tl == sl && !strncmp(f->suffix, str, tl)) ||
886 -                          (tl == sl-1 && !strncmp(f->suffix+1, str, tl-1))) {
887 +                       if ((tl == sl && !strncmp(f->suffix, str, tl)) ||
888 +                          (tl == sl - 1 && !strncmp(f->suffix + 1, str, tl - 1))) {
889                                 rv |= f->bit;
890                                 break;
891                         }
892 diff --git a/tests/t0101-index.sh b/tests/t0101-index.sh
893 index 573a351..ab63aca 100755
894 --- a/tests/t0101-index.sh
895 +++ b/tests/t0101-index.sh
896 @@ -5,14 +5,14 @@
897  prepare_tests "Check content on index page"
898  
899  run_test 'generate index page' 'cgit_url "" >trash/tmp'
900 -run_test 'find foo repo' 'grep -e "foo" trash/tmp'
901 -run_test 'find foo description' 'grep -e "\[no description\]" trash/tmp'
902 -run_test 'find bar repo' 'grep -e "bar" trash/tmp'
903 -run_test 'find bar description' 'grep -e "the bar repo" trash/tmp'
904 -run_test 'find foo+bar repo' 'grep -e ">foo+bar<" trash/tmp'
905 -run_test 'verify foo+bar link' 'grep -e "/foo+bar/" trash/tmp'
906 -run_test 'verify "with%20space" link' 'grep -e "/with%20space/" trash/tmp'
907 -run_test 'no tree-link' '! grep -e "foo/tree" trash/tmp'
908 -run_test 'no log-link' '! grep -e "foo/log" trash/tmp'
909 +run_test 'find foo repo' 'grep "foo" trash/tmp'
910 +run_test 'find foo description' 'grep "\[no description\]" trash/tmp'
911 +run_test 'find bar repo' 'grep "bar" trash/tmp'
912 +run_test 'find bar description' 'grep "the bar repo" trash/tmp'
913 +run_test 'find foo+bar repo' 'grep ">foo+bar<" trash/tmp'
914 +run_test 'verify foo+bar link' 'grep "/foo+bar/" trash/tmp'
915 +run_test 'verify "with%20space" link' 'grep "/with%20space/" trash/tmp'
916 +run_test 'no tree-link' '! grep "foo/tree" trash/tmp'
917 +run_test 'no log-link' '! grep "foo/log" trash/tmp'
918  
919  tests_done
920 diff --git a/tests/t0102-summary.sh b/tests/t0102-summary.sh
921 index f299c5a..f778cb4 100755
922 --- a/tests/t0102-summary.sh
923 +++ b/tests/t0102-summary.sh
924 @@ -5,22 +5,22 @@
925  prepare_tests "Check content on summary page"
926  
927  run_test 'generate foo summary' 'cgit_url "foo" >trash/tmp'
928 -run_test 'find commit 1' 'grep -e "commit 1" trash/tmp'
929 -run_test 'find commit 5' 'grep -e "commit 5" trash/tmp'
930 -run_test 'find branch master' 'grep -e "master" trash/tmp'
931 -run_test 'no tags' '! grep -e "tags" trash/tmp'
932 +run_test 'find commit 1' 'grep "commit 1" trash/tmp'
933 +run_test 'find commit 5' 'grep "commit 5" trash/tmp'
934 +run_test 'find branch master' 'grep "master" trash/tmp'
935 +run_test 'no tags' '! grep "tags" trash/tmp'
936  run_test 'clone-url expanded correctly' '
937 -       grep -e "git://example.org/foo.git" trash/tmp
938 +       grep "git://example.org/foo.git" trash/tmp
939  '
940  
941  run_test 'generate bar summary' 'cgit_url "bar" >trash/tmp'
942 -run_test 'no commit 45' '! grep -e "commit 45" trash/tmp'
943 -run_test 'find commit 46' 'grep -e "commit 46" trash/tmp'
944 -run_test 'find commit 50' 'grep -e "commit 50" trash/tmp'
945 -run_test 'find branch master' 'grep -e "master" trash/tmp'
946 -run_test 'no tags' '! grep -e "tags" trash/tmp'
947 +run_test 'no commit 45' '! grep "commit 45" trash/tmp'
948 +run_test 'find commit 46' 'grep "commit 46" trash/tmp'
949 +run_test 'find commit 50' 'grep "commit 50" trash/tmp'
950 +run_test 'find branch master' 'grep "master" trash/tmp'
951 +run_test 'no tags' '! grep "tags" trash/tmp'
952  run_test 'clone-url expanded correctly' '
953 -       grep -e "git://example.org/bar.git" trash/tmp
954 +       grep "git://example.org/bar.git" trash/tmp
955  '
956  
957  tests_done
958 diff --git a/tests/t0103-log.sh b/tests/t0103-log.sh
959 index 7fa6754..67fcba0 100755
960 --- a/tests/t0103-log.sh
961 +++ b/tests/t0103-log.sh
962 @@ -5,21 +5,21 @@
963  prepare_tests "Check content on log page"
964  
965  run_test 'generate foo/log' 'cgit_url "foo/log" >trash/tmp'
966 -run_test 'find commit 1' 'grep -e "commit 1" trash/tmp'
967 -run_test 'find commit 5' 'grep -e "commit 5" trash/tmp'
968 +run_test 'find commit 1' 'grep "commit 1" trash/tmp'
969 +run_test 'find commit 5' 'grep "commit 5" trash/tmp'
970  
971  run_test 'generate bar/log' 'cgit_url "bar/log" >trash/tmp'
972 -run_test 'find commit 1' 'grep -e "commit 1" trash/tmp'
973 -run_test 'find commit 50' 'grep -e "commit 50" trash/tmp'
974 +run_test 'find commit 1' 'grep "commit 1" trash/tmp'
975 +run_test 'find commit 50' 'grep "commit 50" trash/tmp'
976  
977  run_test 'generate "with%20space/log?qt=grep&q=commit+1"' '
978         cgit_url "with+space/log&qt=grep&q=commit+1" >trash/tmp
979  '
980 -run_test 'find commit 1' 'grep -e "commit 1" trash/tmp'
981 -run_test 'find link with %20 in path' 'grep -e "/with%20space/log/?qt=grep" trash/tmp'
982 -run_test 'find link with + in arg' 'grep -e "/log/?qt=grep&amp;q=commit+1" trash/tmp'
983 -run_test 'no links with space in path' '! grep -e "href=./with space/" trash/tmp'
984 -run_test 'no links with space in arg' '! grep -e "q=commit 1" trash/tmp'
985 -run_test 'commit 2 is not visible' '! grep -e "commit 2" trash/tmp'
986 +run_test 'find commit 1' 'grep "commit 1" trash/tmp'
987 +run_test 'find link with %20 in path' 'grep "/with%20space/log/?qt=grep" trash/tmp'
988 +run_test 'find link with + in arg' 'grep "/log/?qt=grep&amp;q=commit+1" trash/tmp'
989 +run_test 'no links with space in path' '! grep "href=./with space/" trash/tmp'
990 +run_test 'no links with space in arg' '! grep "q=commit 1" trash/tmp'
991 +run_test 'commit 2 is not visible' '! grep "commit 2" trash/tmp'
992  
993  tests_done
994 diff --git a/tests/t0104-tree.sh b/tests/t0104-tree.sh
995 index 2ce1251..7aa3b8d 100755
996 --- a/tests/t0104-tree.sh
997 +++ b/tests/t0104-tree.sh
998 @@ -5,29 +5,29 @@
999  prepare_tests "Check content on tree page"
1000  
1001  run_test 'generate bar/tree' 'cgit_url "bar/tree" >trash/tmp'
1002 -run_test 'find file-1' 'grep -e "file-1" trash/tmp'
1003 -run_test 'find file-50' 'grep -e "file-50" trash/tmp'
1004 +run_test 'find file-1' 'grep "file-1" trash/tmp'
1005 +run_test 'find file-50' 'grep "file-50" trash/tmp'
1006  
1007  run_test 'generate bar/tree/file-50' 'cgit_url "bar/tree/file-50" >trash/tmp'
1008  
1009  run_test 'find line 1' '
1010 -       grep -e "<a class=.no. id=.n1. name=.n1. href=.#n1.>1</a>" trash/tmp
1011 +       grep "<a class=.no. id=.n1. name=.n1. href=.#n1.>1</a>" trash/tmp
1012  '
1013  
1014  run_test 'no line 2' '
1015 -       ! grep -e "<a class=.no. id=.n2. name=.n2. href=.#n2.>2</a>" trash/tmp
1016 +       ! grep "<a class=.no. id=.n2. name=.n2. href=.#n2.>2</a>" trash/tmp
1017  '
1018  
1019  run_test 'generate foo+bar/tree' 'cgit_url "foo%2bbar/tree" >trash/tmp'
1020  
1021  run_test 'verify a+b link' '
1022 -       grep -e "/foo+bar/tree/a+b" trash/tmp
1023 +       grep "/foo+bar/tree/a+b" trash/tmp
1024  '
1025  
1026  run_test 'generate foo+bar/tree?h=1+2' 'cgit_url "foo%2bbar/tree&h=1%2b2" >trash/tmp'
1027  
1028  run_test 'verify a+b?h=1+2 link' '
1029 -       grep -e "/foo+bar/tree/a+b?h=1%2b2" trash/tmp
1030 +       grep "/foo+bar/tree/a+b?h=1%2b2" trash/tmp
1031  '
1032  
1033  tests_done
1034 diff --git a/tests/t0105-commit.sh b/tests/t0105-commit.sh
1035 index ae794c8..31b554b 100755
1036 --- a/tests/t0105-commit.sh
1037 +++ b/tests/t0105-commit.sh
1038 @@ -5,33 +5,33 @@
1039  prepare_tests "Check content on commit page"
1040  
1041  run_test 'generate foo/commit' 'cgit_url "foo/commit" >trash/tmp'
1042 -run_test 'find tree link' 'grep -e "<a href=./foo/tree/.>" trash/tmp'
1043 +run_test 'find tree link' 'grep "<a href=./foo/tree/.>" trash/tmp'
1044  run_test 'find parent link' 'grep -E "<a href=./foo/commit/\?id=.+>" trash/tmp'
1045  
1046  run_test 'find commit subject' '
1047 -       grep -e "<div class=.commit-subject.>commit 5<" trash/tmp
1048 +       grep "<div class=.commit-subject.>commit 5<" trash/tmp
1049  '
1050  
1051 -run_test 'find commit msg' 'grep -e "<div class=.commit-msg.></div>" trash/tmp'
1052 -run_test 'find diffstat' 'grep -e "<table summary=.diffstat. class=.diffstat.>" trash/tmp'
1053 +run_test 'find commit msg' 'grep "<div class=.commit-msg.></div>" trash/tmp'
1054 +run_test 'find diffstat' 'grep "<table summary=.diffstat. class=.diffstat.>" trash/tmp'
1055  
1056  run_test 'find diff summary' '
1057 -        grep -e "1 files changed, 1 insertions, 0 deletions" trash/tmp
1058 +       grep "1 files changed, 1 insertions, 0 deletions" trash/tmp
1059  '
1060  
1061  run_test 'get root commit' '
1062 -        root=$(cd trash/repos/foo && git rev-list --reverse HEAD | head -1) &&
1063 -        cgit_url "foo/commit&id=$root" >trash/tmp &&
1064 -        grep "</html>" trash/tmp
1065 +       root=$(cd trash/repos/foo && git rev-list --reverse HEAD | head -1) &&
1066 +       cgit_url "foo/commit&id=$root" >trash/tmp &&
1067 +       grep "</html>" trash/tmp
1068  '
1069  
1070  run_test 'root commit contains diffstat' '
1071 -        grep "<a href=./foo/diff/file-1.id=[0-9a-f]\{40\}.>file-1</a>" trash/tmp
1072 +       grep "<a href=./foo/diff/file-1.id=[0-9a-f]\{40\}.>file-1</a>" trash/tmp
1073  '
1074  
1075  run_test 'root commit contains diff' '
1076 -        grep ">diff --git a/file-1 b/file-1<" trash/tmp &&
1077 -        grep -e "<div class=.add.>+1</div>" trash/tmp
1078 +       grep ">diff --git a/file-1 b/file-1<" trash/tmp &&
1079 +       grep "<div class=.add.>+1</div>" trash/tmp
1080  '
1081  
1082  tests_done
1083 diff --git a/tests/t0106-diff.sh b/tests/t0106-diff.sh
1084 index e140bcc..eee0c8c 100755
1085 --- a/tests/t0106-diff.sh
1086 +++ b/tests/t0106-diff.sh
1087 @@ -5,16 +5,16 @@
1088  prepare_tests "Check content on diff page"
1089  
1090  run_test 'generate foo/diff' 'cgit_url "foo/diff" >trash/tmp'
1091 -run_test 'find diff header' 'grep -e "a/file-5 b/file-5" trash/tmp'
1092 -run_test 'find blob link' 'grep -e "<a href=./foo/tree/file-5?id=" trash/tmp'
1093 -run_test 'find added file' 'grep -e "new file mode 100644" trash/tmp'
1094 +run_test 'find diff header' 'grep "a/file-5 b/file-5" trash/tmp'
1095 +run_test 'find blob link' 'grep "<a href=./foo/tree/file-5?id=" trash/tmp'
1096 +run_test 'find added file' 'grep "new file mode 100644" trash/tmp'
1097  
1098  run_test 'find hunk header' '
1099 -       grep -e "<div class=.hunk.>@@ -0,0 +1 @@</div>" trash/tmp
1100 +       grep "<div class=.hunk.>@@ -0,0 +1 @@</div>" trash/tmp
1101  '
1102  
1103  run_test 'find added line' '
1104 -       grep -e "<div class=.add.>+5</div>" trash/tmp
1105 +       grep "<div class=.add.>+5</div>" trash/tmp
1106  '
1107  
1108  tests_done
1109 diff --git a/tests/t0107-snapshot.sh b/tests/t0107-snapshot.sh
1110 index 8ab4912..132d2e9 100755
1111 --- a/tests/t0107-snapshot.sh
1112 +++ b/tests/t0107-snapshot.sh
1113 @@ -10,17 +10,20 @@ run_test 'get foo/snapshot/master.tar.gz' '
1114  
1115  run_test 'check html headers' '
1116         head -n 1 trash/tmp |
1117 -            grep -e "Content-Type: application/x-gzip" &&
1118 +       grep "Content-Type: application/x-gzip" &&
1119  
1120         head -n 2 trash/tmp |
1121 -            grep -e "Content-Disposition: inline; filename=.master.tar.gz."
1122 +       grep "Content-Disposition: inline; filename=.master.tar.gz."
1123  '
1124  
1125  run_test 'strip off the header lines' '
1126 -        tail -n +6 trash/tmp > trash/master.tar.gz
1127 +       tail -n +6 trash/tmp > trash/master.tar.gz
1128 +'
1129 +
1130 +run_test 'verify gzip format' '
1131 +       gunzip --test trash/master.tar.gz
1132  '
1133  
1134 -run_test 'verify gzip format' 'gunzip --test trash/master.tar.gz'
1135  run_test 'untar' '
1136         rm -rf trash/master &&
1137         tar -xf trash/master.tar.gz -C trash
1138 @@ -32,7 +35,42 @@ run_test 'count files' '
1139  '
1140  
1141  run_test 'verify untarred file-5' '
1142 -        grep -e "^5$" trash/master/file-5 &&
1143 +       grep "^5$" trash/master/file-5 &&
1144 +       test $(cat trash/master/file-5 | wc -l) = 1
1145 +'
1146 +
1147 +run_test 'get foo/snapshot/master.zip' '
1148 +       cgit_url "foo/snapshot/master.zip" >trash/tmp
1149 +'
1150 +
1151 +run_test 'check HTML headers (zip)' '
1152 +       head -n 1 trash/tmp |
1153 +       grep "Content-Type: application/x-zip" &&
1154 +
1155 +       head -n 2 trash/tmp |
1156 +       grep "Content-Disposition: inline; filename=.master.zip."
1157 +'
1158 +
1159 +run_test 'strip off the header lines (zip)' '
1160 +       tail -n +6 trash/tmp >trash/master.zip
1161 +'
1162 +
1163 +run_test 'verify zip format' '
1164 +       unzip -t trash/master.zip
1165 +'
1166 +
1167 +run_test 'unzip' '
1168 +       rm -rf trash/master &&
1169 +       unzip trash/master.zip -d trash
1170 +'
1171 +
1172 +run_test 'count files (zip)' '
1173 +       c=$(ls -1 trash/master/ | wc -l) &&
1174 +       test $c = 5
1175 +'
1176 +
1177 +run_test 'verify unzipped file-5' '
1178 +        grep "^5$" trash/master/file-5 &&
1179          test $(cat trash/master/file-5 | wc -l) = 1
1180  '
1181  
1182 diff --git a/tests/t0108-patch.sh b/tests/t0108-patch.sh
1183 index 6ee70b3..f92f69c 100755
1184 --- a/tests/t0108-patch.sh
1185 +++ b/tests/t0108-patch.sh
1186 @@ -9,19 +9,19 @@ run_test 'generate foo/patch' '
1187  '
1188  
1189  run_test 'find `From:` line' '
1190 -       grep -e "^From: " trash/tmp
1191 +       grep "^From: " trash/tmp
1192  '
1193  
1194  run_test 'find `Date:` line' '
1195 -       grep -e "^Date: " trash/tmp
1196 +       grep "^Date: " trash/tmp
1197  '
1198  
1199  run_test 'find `Subject:` line' '
1200 -       grep -e "^Subject: commit 5" trash/tmp
1201 +       grep "^Subject: commit 5" trash/tmp
1202  '
1203  
1204  run_test 'find `cgit` signature' '
1205 -        tail -1 trash/tmp | grep -e "^cgit"
1206 +       tail -1 trash/tmp | grep "^cgit"
1207  '
1208  
1209  run_test 'find initial commit' '
1210 @@ -33,7 +33,7 @@ run_test 'generate patch for initial commit' '
1211  '
1212  
1213  run_test 'find `cgit` signature' '
1214 -       tail -1 trash/tmp | grep -e "^cgit"
1215 +       tail -1 trash/tmp | grep "^cgit"
1216  '
1217  
1218  tests_done
1219 diff --git a/ui-blob.c b/ui-blob.c
1220 index ec435e1..c59fbcb 100644
1221 --- a/ui-blob.c
1222 +++ b/ui-blob.c
1223 @@ -11,17 +11,22 @@
1224  #include "html.h"
1225  #include "ui-shared.h"
1226  
1227 -static char *match_path;
1228 -static unsigned char *matched_sha1;
1229 -static int found_path;
1230 +struct walk_tree_context {
1231 +       char *match_path;
1232 +       unsigned char *matched_sha1;
1233 +       int found_path;
1234 +};
1235  
1236 -static int walk_tree(const unsigned char *sha1, const char *base,int baselen,
1237 -       const char *pathname, unsigned mode, int stage, void *cbdata) {
1238 -       if(strncmp(base,match_path,baselen)
1239 -               || strcmp(match_path+baselen,pathname) )
1240 +static int walk_tree(const unsigned char *sha1, const char *base, int baselen,
1241 +       const char *pathname, unsigned mode, int stage, void *cbdata)
1242 +{
1243 +       struct walk_tree_context *walk_tree_ctx = cbdata;
1244 +
1245 +       if (strncmp(base, walk_tree_ctx->match_path, baselen)
1246 +               || strcmp(walk_tree_ctx->match_path + baselen, pathname))
1247                 return READ_TREE_RECURSIVE;
1248 -       memmove(matched_sha1,sha1,20);
1249 -       found_path = 1;
1250 +       memmove(walk_tree_ctx->matched_sha1, sha1, 20);
1251 +       walk_tree_ctx->found_path = 1;
1252         return 0;
1253  }
1254  
1255 @@ -32,17 +37,27 @@ int cgit_print_file(char *path, const char *head)
1256         char *buf;
1257         unsigned long size;
1258         struct commit *commit;
1259 -       const char *paths[] = {path, NULL};
1260 +       struct pathspec_item path_items = {
1261 +               .match = path,
1262 +               .len = strlen(path)
1263 +       };
1264 +       struct pathspec paths = {
1265 +               .nr = 1,
1266 +               .items = &path_items
1267 +       };
1268 +       struct walk_tree_context walk_tree_ctx = {
1269 +               .match_path = path,
1270 +               .matched_sha1 = sha1,
1271 +               .found_path = 0
1272 +       };
1273 +
1274         if (get_sha1(head, sha1))
1275                 return -1;
1276         type = sha1_object_info(sha1, &size);
1277 -       if(type == OBJ_COMMIT && path) {
1278 +       if (type == OBJ_COMMIT && path) {
1279                 commit = lookup_commit_reference(sha1);
1280 -               match_path = path;
1281 -               matched_sha1 = sha1;
1282 -               found_path = 0;
1283 -               read_tree_recursive(commit->tree, "", 0, 0, paths, walk_tree, NULL);
1284 -               if (!found_path)
1285 +               read_tree_recursive(commit->tree, "", 0, 0, &paths, walk_tree, &walk_tree_ctx);
1286 +               if (!walk_tree_ctx.found_path)
1287                         return -1;
1288                 type = sha1_object_info(sha1, &size);
1289         }
1290 @@ -63,15 +78,26 @@ void cgit_print_blob(const char *hex, char *path, const char *head)
1291         char *buf;
1292         unsigned long size;
1293         struct commit *commit;
1294 -       const char *paths[] = {path, NULL};
1295 +       struct pathspec_item path_items = {
1296 +               .match = path,
1297 +               .len = strlen(path)
1298 +       };
1299 +       struct pathspec paths = {
1300 +               .nr = 1,
1301 +               .items = &path_items
1302 +       };
1303 +       struct walk_tree_context walk_tree_ctx = {
1304 +               .match_path = path,
1305 +               .matched_sha1 = sha1,
1306 +       };
1307  
1308         if (hex) {
1309 -               if (get_sha1_hex(hex, sha1)){
1310 +               if (get_sha1_hex(hex, sha1)) {
1311                         cgit_print_error(fmt("Bad hex value: %s", hex));
1312                         return;
1313                 }
1314         } else {
1315 -               if (get_sha1(head,sha1)) {
1316 +               if (get_sha1(head, sha1)) {
1317                         cgit_print_error(fmt("Bad ref: %s", head));
1318                         return;
1319                 }
1320 @@ -79,11 +105,9 @@ void cgit_print_blob(const char *hex, char *path, const char *head)
1321  
1322         type = sha1_object_info(sha1, &size);
1323  
1324 -       if((!hex) && type == OBJ_COMMIT && path) {
1325 +       if ((!hex) && type == OBJ_COMMIT && path) {
1326                 commit = lookup_commit_reference(sha1);
1327 -               match_path = path;
1328 -               matched_sha1 = sha1;
1329 -               read_tree_recursive(commit->tree, "", 0, 0, paths, walk_tree, NULL);
1330 +               read_tree_recursive(commit->tree, "", 0, 0, &paths, walk_tree, &walk_tree_ctx);
1331                 type = sha1_object_info(sha1,&size);
1332         }
1333  
1334 diff --git a/ui-clone.c b/ui-clone.c
1335 index 81e7a4e..fdea24f 100644
1336 --- a/ui-clone.c
1337 +++ b/ui-clone.c
1338 @@ -19,12 +19,10 @@ static int print_ref_info(const char *refname, const unsigned char *sha1,
1339         if (!(obj = parse_object(sha1)))
1340                 return 0;
1341  
1342 -       if (!strcmp(refname, "HEAD") || !prefixcmp(refname, "refs/heads/"))
1343 -               htmlf("%s\t%s\n", sha1_to_hex(sha1), refname);
1344 -       else if (!prefixcmp(refname, "refs/tags") && obj->type == OBJ_TAG) {
1345 +       htmlf("%s\t%s\n", sha1_to_hex(sha1), refname);
1346 +       if (obj->type == OBJ_TAG) {
1347                 if (!(obj = deref_tag(obj, refname, 0)))
1348                         return 0;
1349 -               htmlf("%s\t%s\n", sha1_to_hex(sha1), refname);
1350                 htmlf("%s\t%s^{}\n", sha1_to_hex(obj->sha1), refname);
1351         }
1352         return 0;
1353 diff --git a/ui-commit.c b/ui-commit.c
1354 index 536a8e8..74f37c8 100644
1355 --- a/ui-commit.c
1356 +++ b/ui-commit.c
1357 @@ -39,7 +39,7 @@ void cgit_print_commit(char *hex, const char *prefix)
1358         format_note(NULL, sha1, &notes, PAGE_ENCODING, 0);
1359  
1360         load_ref_decorations(DECORATE_FULL_REFS);
1361 -       
1362 +
1363         cgit_print_diff_ctrls();
1364         html("<table summary='commit info' class='commit-info'>\n");
1365         html("<tr><th>author</th><td>");
1366 @@ -75,7 +75,7 @@ void cgit_print_commit(char *hex, const char *prefix)
1367                 cgit_tree_link(prefix, NULL, NULL, ctx.qry.head, tmp, prefix);
1368         }
1369         html("</td></tr>\n");
1370 -       for (p = commit->parents; p ; p = p->next) {
1371 +       for (p = commit->parents; p; p = p->next) {
1372                 parent = lookup_commit_reference(p->item->object.sha1);
1373                 if (!parent) {
1374                         html("<tr><td colspan='3'>");
1375 diff --git a/ui-diff.c b/ui-diff.c
1376 index 3d46da2..49e5b46 100644
1377 --- a/ui-diff.c
1378 +++ b/ui-diff.c
1379 @@ -184,7 +184,7 @@ void cgit_print_diffstat(const unsigned char *old_sha1,
1380         max_changes = 0;
1381         cgit_diff_tree(old_sha1, new_sha1, inspect_filepair, prefix,
1382                        ctx.qry.ignorews);
1383 -       for(i = 0; i<files; i++)
1384 +       for (i = 0; i<files; i++)
1385                 print_fileinfo(&items[i]);
1386         html("</table>");
1387         html("<div class='diffstat-summary'>");
1388 diff --git a/ui-plain.c b/ui-plain.c
1389 index 85877d7..8ef4ec6 100644
1390 --- a/ui-plain.c
1391 +++ b/ui-plain.c
1392 @@ -11,8 +11,10 @@
1393  #include "html.h"
1394  #include "ui-shared.h"
1395  
1396 -int match_baselen;
1397 -int match;
1398 +struct walk_tree_context {
1399 +       int match_baselen;
1400 +       int match;
1401 +};
1402  
1403  static char *get_mimetype_from_file(const char *filename, const char *ext)
1404  {
1405 @@ -54,7 +56,7 @@ static char *get_mimetype_from_file(const char *filename, const char *ext)
1406         return result;
1407  }
1408  
1409 -static void print_object(const unsigned char *sha1, const char *path)
1410 +static int print_object(const unsigned char *sha1, const char *path)
1411  {
1412         enum object_type type;
1413         char *buf, *ext;
1414 @@ -65,13 +67,13 @@ static void print_object(const unsigned char *sha1, const char *path)
1415         type = sha1_object_info(sha1, &size);
1416         if (type == OBJ_BAD) {
1417                 html_status(404, "Not found", 0);
1418 -               return;
1419 +               return 0;
1420         }
1421  
1422         buf = read_sha1_file(sha1, &type, &size);
1423         if (!buf) {
1424                 html_status(404, "Not found", 0);
1425 -               return;
1426 +               return 0;
1427         }
1428         ctx.page.mimetype = NULL;
1429         ext = strrchr(path, '.');
1430 @@ -97,9 +99,9 @@ static void print_object(const unsigned char *sha1, const char *path)
1431         ctx.page.etag = sha1_to_hex(sha1);
1432         cgit_print_http_headers(&ctx);
1433         html_raw(buf, size);
1434 -       match = 1;
1435         if (freemime)
1436                 free(ctx.page.mimetype);
1437 +       return 1;
1438  }
1439  
1440  static char *buildpath(const char *base, int baselen, const char *path)
1441 @@ -138,7 +140,6 @@ static void print_dir(const unsigned char *sha1, const char *base,
1442                                 fullpath);
1443                 html("</li>\n");
1444         }
1445 -       match = 2;
1446  }
1447  
1448  static void print_dir_entry(const unsigned char *sha1, const char *base,
1449 @@ -156,7 +157,6 @@ static void print_dir_entry(const unsigned char *sha1, const char *base,
1450                 cgit_plain_link(path, NULL, NULL, ctx.qry.head, ctx.qry.sha1,
1451                                 fullpath);
1452         html("</li>\n");
1453 -       match = 2;
1454  }
1455  
1456  static void print_dir_tail(void)
1457 @@ -168,18 +168,23 @@ static int walk_tree(const unsigned char *sha1, const char *base, int baselen,
1458                      const char *pathname, unsigned mode, int stage,
1459                      void *cbdata)
1460  {
1461 -       if (baselen == match_baselen) {
1462 -               if (S_ISREG(mode))
1463 -                       print_object(sha1, pathname);
1464 -               else if (S_ISDIR(mode)) {
1465 +       struct walk_tree_context *walk_tree_ctx = cbdata;
1466 +
1467 +       if (baselen == walk_tree_ctx->match_baselen) {
1468 +               if (S_ISREG(mode)) {
1469 +                       if (print_object(sha1, pathname))
1470 +                               walk_tree_ctx->match = 1;
1471 +               } else if (S_ISDIR(mode)) {
1472                         print_dir(sha1, base, baselen, pathname);
1473 +                       walk_tree_ctx->match = 2;
1474                         return READ_TREE_RECURSIVE;
1475                 }
1476 -       }
1477 -       else if (baselen > match_baselen)
1478 +       } else if (baselen > walk_tree_ctx->match_baselen) {
1479                 print_dir_entry(sha1, base, baselen, pathname, mode);
1480 -       else if (S_ISDIR(mode))
1481 +               walk_tree_ctx->match = 2;
1482 +       } else if (S_ISDIR(mode)) {
1483                 return READ_TREE_RECURSIVE;
1484 +       }
1485  
1486         return 0;
1487  }
1488 @@ -197,7 +202,17 @@ void cgit_print_plain(struct cgit_context *ctx)
1489         const char *rev = ctx->qry.sha1;
1490         unsigned char sha1[20];
1491         struct commit *commit;
1492 -       const char *paths[] = {ctx->qry.path, NULL};
1493 +       struct pathspec_item path_items = {
1494 +               .match = ctx->qry.path,
1495 +               .len = ctx->qry.path ? strlen(ctx->qry.path) : 0
1496 +       };
1497 +       struct pathspec paths = {
1498 +               .nr = 1,
1499 +               .items = &path_items
1500 +       };
1501 +       struct walk_tree_context walk_tree_ctx = {
1502 +               .match = 0
1503 +       };
1504  
1505         if (!rev)
1506                 rev = ctx->qry.head;
1507 @@ -211,16 +226,17 @@ void cgit_print_plain(struct cgit_context *ctx)
1508                 html_status(404, "Not found", 0);
1509                 return;
1510         }
1511 -       if (!paths[0]) {
1512 -               paths[0] = "";
1513 -               match_baselen = -1;
1514 +       if (!path_items.match) {
1515 +               path_items.match = "";
1516 +               walk_tree_ctx.match_baselen = -1;
1517                 print_dir(commit->tree->object.sha1, "", 0, "");
1518 +               walk_tree_ctx.match = 2;
1519         }
1520         else
1521 -               match_baselen = basedir_len(paths[0]);
1522 -       read_tree_recursive(commit->tree, "", 0, 0, paths, walk_tree, NULL);
1523 -       if (!match)
1524 +               walk_tree_ctx.match_baselen = basedir_len(path_items.match);
1525 +       read_tree_recursive(commit->tree, "", 0, 0, &paths, walk_tree, &walk_tree_ctx);
1526 +       if (!walk_tree_ctx.match)
1527                 html_status(404, "Not found", 0);
1528 -       else if (match == 2)
1529 +       else if (walk_tree_ctx.match == 2)
1530                 print_dir_tail();
1531  }
1532 diff --git a/ui-refs.c b/ui-refs.c
1533 index caddfbc..ce06b08 100644
1534 --- a/ui-refs.c
1535 +++ b/ui-refs.c
1536 @@ -200,7 +200,7 @@ void cgit_print_branches(int maxcount)
1537                 qsort(list.refs, maxcount, sizeof(*list.refs), cmp_ref_name);
1538         }
1539  
1540 -       for(i=0; i<maxcount; i++)
1541 +       for (i = 0; i < maxcount; i++)
1542                 print_branch(list.refs[i]);
1543  
1544         if (maxcount < list.count)
1545 @@ -224,7 +224,7 @@ void cgit_print_tags(int maxcount)
1546         else if (maxcount > list.count)
1547                 maxcount = list.count;
1548         print_tag_header();
1549 -       for(i=0; i<maxcount; i++)
1550 +       for (i = 0; i < maxcount; i++)
1551                 print_tag(list.refs[i]);
1552  
1553         if (maxcount < list.count)
1554 diff --git a/ui-repolist.c b/ui-repolist.c
1555 index dead1bf..1ae22aa 100644
1556 --- a/ui-repolist.c
1557 +++ b/ui-repolist.c
1558 @@ -110,12 +110,13 @@ void print_sort_header(const char *title, const char *sort)
1559         htmlf("'>%s</a></th>", title);
1560  }
1561  
1562 -void print_header(int columns)
1563 +void print_header()
1564  {
1565         html("<tr class='nohover'>");
1566         print_sort_header("Name", "name");
1567         print_sort_header("Description", "desc");
1568 -       print_sort_header("Owner", "owner");
1569 +       if (ctx.cfg.enable_index_owner)
1570 +               print_sort_header("Owner", "owner");
1571         print_sort_header("Idle", "idle");
1572         if (ctx.cfg.enable_index_links)
1573                 html("<th class='left'>Links</th>");
1574 @@ -128,10 +129,10 @@ void print_pager(int items, int pagelen, char *search, char *sort)
1575         int i, ofs;
1576         char *class = NULL;
1577         html("<div class='pager'>");
1578 -       for(i = 0, ofs = 0; ofs < items; i++, ofs = i * pagelen) {
1579 +       for (i = 0, ofs = 0; ofs < items; i++, ofs = i * pagelen) {
1580                 class = (ctx.qry.ofs == ofs) ? "current" : NULL;
1581 -               cgit_index_link(fmt("[%d]", i+1), fmt("Page %d", i+1), class,
1582 -                               search, sort, ofs);
1583 +               cgit_index_link(fmt("[%d]", i + 1), fmt("Page %d", i + 1),
1584 +                               class, search, sort, ofs);
1585         }
1586         html("</div>");
1587  }
1588 @@ -239,13 +240,15 @@ int sort_repolist(char *field)
1589  
1590  void cgit_print_repolist()
1591  {
1592 -       int i, columns = 4, hits = 0, header = 0;
1593 +       int i, columns = 3, hits = 0, header = 0;
1594         char *last_section = NULL;
1595         char *section;
1596         int sorted = 0;
1597  
1598         if (ctx.cfg.enable_index_links)
1599 -               columns++;
1600 +               ++columns;
1601 +       if (ctx.cfg.enable_index_owner)
1602 +               ++columns;
1603  
1604         ctx.page.title = ctx.cfg.root_title;
1605         cgit_print_http_headers(&ctx);
1606 @@ -255,13 +258,13 @@ void cgit_print_repolist()
1607         if (ctx.cfg.index_header)
1608                 html_include(ctx.cfg.index_header);
1609  
1610 -       if(ctx.qry.sort)
1611 +       if (ctx.qry.sort)
1612                 sorted = sort_repolist(ctx.qry.sort);
1613         else if (ctx.cfg.section_sort)
1614                 sort_repolist("section");
1615  
1616         html("<table summary='repository list' class='list nowrap'>");
1617 -       for (i=0; i<cgit_repolist.count; i++) {
1618 +       for (i = 0; i < cgit_repolist.count; i++) {
1619                 ctx.repo = &cgit_repolist.repos[i];
1620                 if (!(is_match(ctx.repo) && is_in_url(ctx.repo)))
1621                         continue;
1622 @@ -271,7 +274,7 @@ void cgit_print_repolist()
1623                 if (hits > ctx.qry.ofs + ctx.cfg.max_repo_count)
1624                         continue;
1625                 if (!header++)
1626 -                       print_header(columns);
1627 +                       print_header();
1628                 section = ctx.repo->section;
1629                 if (section && !strcmp(section, ""))
1630                         section = NULL;
1631 @@ -294,8 +297,10 @@ void cgit_print_repolist()
1632                 html_ntxt(ctx.cfg.max_repodesc_len, ctx.repo->desc);
1633                 html_link_close();
1634                 html("</td><td>");
1635 -               html_txt(ctx.repo->owner);
1636 -               html("</td><td>");
1637 +               if (ctx.cfg.enable_index_owner) {
1638 +                       html_txt(ctx.repo->owner);
1639 +                       html("</td><td>");
1640 +               }
1641                 print_modtime(ctx.repo);
1642                 html("</td>");
1643                 if (ctx.cfg.enable_index_links) {
1644 diff --git a/ui-shared.c b/ui-shared.c
1645 index 75b97a1..af5310b 100644
1646 --- a/ui-shared.c
1647 +++ b/ui-shared.c
1648 @@ -23,7 +23,7 @@ static char *http_date(time_t t)
1649                  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
1650         struct tm *tm = gmtime(&t);
1651         return fmt("%s, %02d %s %04d %02d:%02d:%02d GMT", day[tm->tm_wday],
1652 -                  tm->tm_mday, month[tm->tm_mon], 1900+tm->tm_year,
1653 +                  tm->tm_mday, month[tm->tm_mon], 1900 + tm->tm_year,
1654                    tm->tm_hour, tm->tm_min, tm->tm_sec);
1655  }
1656  
1657 @@ -93,7 +93,7 @@ char *cgit_fileurl(const char *reponame, const char *pagename,
1658  char *cgit_pageurl(const char *reponame, const char *pagename,
1659                    const char *query)
1660  {
1661 -       return cgit_fileurl(reponame,pagename,0,query);
1662 +       return cgit_fileurl(reponame, pagename, 0, query);
1663  }
1664  
1665  const char *cgit_repobasename(const char *reponame)
1666 @@ -102,21 +102,21 @@ const char *cgit_repobasename(const char *reponame)
1667         static char rvbuf[1024];
1668         int p;
1669         const char *rv;
1670 -       strncpy(rvbuf,reponame,sizeof(rvbuf));
1671 -       if(rvbuf[sizeof(rvbuf)-1])
1672 +       strncpy(rvbuf, reponame, sizeof(rvbuf));
1673 +       if (rvbuf[sizeof(rvbuf)-1])
1674                 die("cgit_repobasename: truncated repository name '%s'", reponame);
1675         p = strlen(rvbuf)-1;
1676         /* strip trailing slashes */
1677 -       while(p && rvbuf[p]=='/') rvbuf[p--]=0;
1678 +       while (p && rvbuf[p] == '/') rvbuf[p--] = 0;
1679         /* strip trailing .git */
1680 -       if(p>=3 && !strncmp(&rvbuf[p-3],".git",4)) {
1681 +       if (p >= 3 && !strncmp(&rvbuf[p-3], ".git", 4)) {
1682                 p -= 3; rvbuf[p--] = 0;
1683         }
1684         /* strip more trailing slashes if any */
1685 -       while( p && rvbuf[p]=='/') rvbuf[p--]=0;
1686 +       while ( p && rvbuf[p] == '/') rvbuf[p--] = 0;
1687         /* find last slash in the remaining string */
1688         rv = strrchr(rvbuf,'/');
1689 -       if(rv)
1690 +       if (rv)
1691                 return ++rv;
1692         return rvbuf;
1693  }
1694 @@ -499,7 +499,7 @@ void cgit_object_link(struct object *obj)
1695         shortrev = xstrdup(fullrev);
1696         shortrev[10] = '\0';
1697         if (obj->type == OBJ_COMMIT) {
1698 -                cgit_commit_link(fmt("commit %s...", shortrev), NULL, NULL,
1699 +               cgit_commit_link(fmt("commit %s...", shortrev), NULL, NULL,
1700                                  ctx.qry.head, fullrev, NULL, 0);
1701                 return;
1702         } else if (obj->type == OBJ_TREE)
1703 @@ -564,6 +564,7 @@ void cgit_submodule_link(const char *class, char *path, const char *rev)
1704         html("'>");
1705         html_txt(path);
1706         html("</a>");
1707 +       html_txt(fmt(" @ %.7s", rev));
1708         if (item && tail)
1709                 path[len - 1] = tail;
1710  }
1711 @@ -575,7 +576,7 @@ void cgit_print_date(time_t secs, const char *format, int local_time)
1712  
1713         if (!secs)
1714                 return;
1715 -       if(local_time)
1716 +       if (local_time)
1717                 time = localtime(&secs);
1718         else
1719                 time = gmtime(&secs);
1720 @@ -735,7 +736,7 @@ int print_archive_ref(const char *refname, const unsigned char *sha1,
1721  
1722         if (prefixcmp(refname, "refs/archives"))
1723                 return 0;
1724 -       strncpy(buf, refname+14, sizeof(buf));
1725 +       strncpy(buf, refname + 14, sizeof(buf));
1726         obj = parse_object(sha1);
1727         if (!obj)
1728                 return 1;
1729 @@ -967,7 +968,7 @@ void cgit_print_snapshot_links(const char *repo, const char *head,
1730  {
1731         const struct cgit_snapshot_format* f;
1732         char *prefix;
1733 -       char *filename;
1734 +       char *filename;
1735         unsigned char sha1[20];
1736  
1737         if (get_sha1(fmt("refs/tags/%s", hex), sha1) == 0 &&
1738 diff --git a/ui-snapshot.c b/ui-snapshot.c
1739 index 47432bd..54e659c 100644
1740 --- a/ui-snapshot.c
1741 +++ b/ui-snapshot.c
1742 @@ -11,7 +11,32 @@
1743  #include "html.h"
1744  #include "ui-shared.h"
1745  
1746 -static int write_compressed_tar_archive(struct archiver_args *args, char *filter_argv[])
1747 +static int write_archive_type(const char *format, const char *hex, const char *prefix)
1748 +{
1749 +       struct argv_array argv = ARGV_ARRAY_INIT;
1750 +       argv_array_push(&argv, "snapshot");
1751 +       argv_array_push(&argv, format);
1752 +       if (prefix) {
1753 +               argv_array_push(&argv, "--prefix");
1754 +               argv_array_push(&argv, fmt("%s/", prefix));
1755 +       }
1756 +       argv_array_push(&argv, hex);
1757 +       return write_archive(argv.argc, argv.argv, NULL, 1, NULL, 0);
1758 +}
1759 +
1760 +static int write_tar_archive(const char *hex, const char *prefix)
1761 +{
1762 +       return write_archive_type("--format=tar", hex, prefix);
1763 +}
1764 +
1765 +static int write_zip_archive(const char *hex, const char *prefix)
1766 +{
1767 +       return write_archive_type("--format=zip", hex, prefix);
1768 +}
1769 +
1770 +static int write_compressed_tar_archive(const char *hex,
1771 +                                       const char *prefix,
1772 +                                       char *filter_argv[])
1773  {
1774         int rv;
1775         struct cgit_filter f;
1776 @@ -19,27 +44,27 @@ static int write_compressed_tar_archive(struct archiver_args *args, char *filter
1777         f.cmd = filter_argv[0];
1778         f.argv = filter_argv;
1779         cgit_open_filter(&f);
1780 -       rv = write_tar_archive(args);
1781 +       rv = write_tar_archive(hex, prefix);
1782         cgit_close_filter(&f);
1783         return rv;
1784  }
1785  
1786 -static int write_tar_gzip_archive(struct archiver_args *args)
1787 +static int write_tar_gzip_archive(const char *hex, const char *prefix)
1788  {
1789         char *argv[] = { "gzip", "-n", NULL };
1790 -       return write_compressed_tar_archive(args, argv);
1791 +       return write_compressed_tar_archive(hex, prefix, argv);
1792  }
1793  
1794 -static int write_tar_bzip2_archive(struct archiver_args *args)
1795 +static int write_tar_bzip2_archive(const char *hex, const char *prefix)
1796  {
1797         char *argv[] = { "bzip2", NULL };
1798 -       return write_compressed_tar_archive(args, argv);
1799 +       return write_compressed_tar_archive(hex, prefix, argv);
1800  }
1801  
1802 -static int write_tar_xz_archive(struct archiver_args *args)
1803 +static int write_tar_xz_archive(const char *hex, const char *prefix)
1804  {
1805         char *argv[] = { "xz", NULL };
1806 -       return write_compressed_tar_archive(args, argv);
1807 +       return write_compressed_tar_archive(hex, prefix, argv);
1808  }
1809  
1810  const struct cgit_snapshot_format cgit_snapshot_formats[] = {
1811 @@ -48,7 +73,7 @@ const struct cgit_snapshot_format cgit_snapshot_formats[] = {
1812         { ".tar.bz2", "application/x-bzip2", write_tar_bzip2_archive, 0x04 },
1813         { ".tar", "application/x-tar", write_tar_archive, 0x08 },
1814         { ".tar.xz", "application/x-xz", write_tar_xz_archive, 0x10 },
1815 -       {}
1816 +       { NULL }
1817  };
1818  
1819  static const struct cgit_snapshot_format *get_format(const char *filename)
1820 @@ -57,7 +82,7 @@ static const struct cgit_snapshot_format *get_format(const char *filename)
1821         int fl, sl;
1822  
1823         fl = strlen(filename);
1824 -       for(fmt = cgit_snapshot_formats; fmt->suffix; fmt++) {
1825 +       for (fmt = cgit_snapshot_formats; fmt->suffix; fmt++) {
1826                 sl = strlen(fmt->suffix);
1827                 if (sl >= fl)
1828                         continue;
1829 @@ -71,34 +96,20 @@ static int make_snapshot(const struct cgit_snapshot_format *format,
1830                          const char *hex, const char *prefix,
1831                          const char *filename)
1832  {
1833 -       struct archiver_args args;
1834 -       struct commit *commit;
1835         unsigned char sha1[20];
1836  
1837 -       if(get_sha1(hex, sha1)) {
1838 +       if (get_sha1(hex, sha1)) {
1839                 cgit_print_error(fmt("Bad object id: %s", hex));
1840                 return 1;
1841         }
1842 -       commit = lookup_commit_reference(sha1);
1843 -       if(!commit) {
1844 +       if (!lookup_commit_reference(sha1)) {
1845                 cgit_print_error(fmt("Not a commit reference: %s", hex));
1846                 return 1;
1847         }
1848 -       memset(&args, 0, sizeof(args));
1849 -       if (prefix) {
1850 -               args.base = fmt("%s/", prefix);
1851 -               args.baselen = strlen(prefix) + 1;
1852 -       } else {
1853 -               args.base = "";
1854 -               args.baselen = 0;
1855 -       }
1856 -       args.tree = commit->tree;
1857 -       args.time = commit->date;
1858 -       args.compression_level = Z_DEFAULT_COMPRESSION;
1859         ctx.page.mimetype = xstrdup(format->mimetype);
1860         ctx.page.filename = xstrdup(filename);
1861         cgit_print_http_headers(&ctx);
1862 -       format->write_func(&args);
1863 +       format->write_func(hex, prefix);
1864         return 0;
1865  }
1866  
1867 diff --git a/ui-ssdiff.c b/ui-ssdiff.c
1868 index 7108779..3d3dad6 100644
1869 --- a/ui-ssdiff.c
1870 +++ b/ui-ssdiff.c
1871 @@ -138,9 +138,8 @@ static char *replace_tabs(char *line)
1872                         strcat(result, prev_buf);
1873                         break;
1874                 } else {
1875 -                       strcat(result, " ");
1876 -                       strncat(result, spaces, 8 - (strlen(result) % 8));
1877                         strncat(result, prev_buf, cur_buf - prev_buf);
1878 +                       strncat(result, spaces, 8 - (strlen(result) % 8));
1879                 }
1880                 prev_buf = cur_buf + 1;
1881         }
1882 diff --git a/ui-stats.c b/ui-stats.c
1883 index 59f4c1e..9cf1dbd 100644
1884 --- a/ui-stats.c
1885 +++ b/ui-stats.c
1886 @@ -23,21 +23,21 @@ static void trunc_week(struct tm *tm)
1887  {
1888         time_t t = timegm(tm);
1889         t -= ((tm->tm_wday + 6) % 7) * DAY_SECS;
1890 -       gmtime_r(&t, tm);       
1891 +       gmtime_r(&t, tm);
1892  }
1893  
1894  static void dec_week(struct tm *tm)
1895  {
1896         time_t t = timegm(tm);
1897         t -= WEEK_SECS;
1898 -       gmtime_r(&t, tm);       
1899 +       gmtime_r(&t, tm);
1900  }
1901  
1902  static void inc_week(struct tm *tm)
1903  {
1904         time_t t = timegm(tm);
1905         t += WEEK_SECS;
1906 -       gmtime_r(&t, tm);       
1907 +       gmtime_r(&t, tm);
1908  }
1909  
1910  static char *pretty_week(struct tm *tm)
1911 @@ -83,7 +83,7 @@ static char *pretty_month(struct tm *tm)
1912  static void trunc_quarter(struct tm *tm)
1913  {
1914         trunc_month(tm);
1915 -       while(tm->tm_mon % 3 != 0)
1916 +       while (tm->tm_mon % 3 != 0)
1917                 dec_month(tm);
1918  }
1919  
1920 @@ -153,7 +153,7 @@ int cgit_find_stats_period(const char *expr, struct cgit_period **period)
1921                 if (periods[i].code == code || !strcmp(periods[i].name, expr)) {
1922                         if (period)
1923                                 *period = &periods[i];
1924 -                       return i+1;
1925 +                       return i + 1;
1926                 }
1927         return 0;
1928  }
1929 @@ -239,7 +239,7 @@ struct string_list collect_stats(struct cgit_context *ctx,
1930         init_revisions(&rev, NULL);
1931         rev.abbrev = DEFAULT_ABBREV;
1932         rev.commit_format = CMIT_FMT_DEFAULT;
1933 -       rev.no_merges = 1;
1934 +       rev.max_parents = 1;
1935         rev.verbose_header = 1;
1936         rev.show_root_diff = 0;
1937         setup_revisions(argc, argv, &rev, NULL);
1938 diff --git a/ui-tag.c b/ui-tag.c
1939 index 39e4cb8..cab96b1 100644
1940 --- a/ui-tag.c
1941 +++ b/ui-tag.c
1942 @@ -99,6 +99,6 @@ void cgit_print_tag(char *revname)
1943                 if (ctx.repo->snapshots)
1944                         print_download_links(revname);
1945                 html("</table>\n");
1946 -        }
1947 +       }
1948         return;
1949  }
1950 diff --git a/ui-tree.c b/ui-tree.c
1951 index b1adcc7..561f9e7 100644
1952 --- a/ui-tree.c
1953 +++ b/ui-tree.c
1954 @@ -11,9 +11,11 @@
1955  #include "html.h"
1956  #include "ui-shared.h"
1957  
1958 -char *curr_rev;
1959 -char *match_path;
1960 -int header = 0;
1961 +struct walk_tree_context {
1962 +       char *curr_rev;
1963 +       char *match_path;
1964 +       int state;
1965 +};
1966  
1967  static void print_text_buffer(const char *name, char *buf, unsigned long size)
1968  {
1969 @@ -27,10 +29,10 @@ static void print_text_buffer(const char *name, char *buf, unsigned long size)
1970                 html("<tr><td class='linenumbers'><pre>");
1971                 idx = 0;
1972                 lineno = 0;
1973 -       
1974 +
1975                 if (size) {
1976                         htmlf(numberfmt, ++lineno);
1977 -                       while(idx < size - 1) { // skip absolute last newline
1978 +                       while (idx < size - 1) { // skip absolute last newline
1979                                 if (buf[idx] == '\n')
1980                                         htmlf(numberfmt, ++lineno);
1981                                 idx++;
1982 @@ -84,7 +86,7 @@ static void print_binary_buffer(char *buf, unsigned long size)
1983         html("</table>\n");
1984  }
1985  
1986 -static void print_object(const unsigned char *sha1, char *path, const char *basename)
1987 +static void print_object(const unsigned char *sha1, char *path, const char *basename, const char *rev)
1988  {
1989         enum object_type type;
1990         char *buf;
1991 @@ -106,7 +108,7 @@ static void print_object(const unsigned char *sha1, char *path, const char *base
1992  
1993         htmlf("blob: %s (", sha1_to_hex(sha1));
1994         cgit_plain_link("plain", NULL, NULL, ctx.qry.head,
1995 -                       curr_rev, path);
1996 +                       rev, path);
1997         html(")\n");
1998  
1999         if (ctx.cfg.max_blob_size && size / 1024 > ctx.cfg.max_blob_size) {
2000 @@ -126,6 +128,7 @@ static int ls_item(const unsigned char *sha1, const char *base, int baselen,
2001                    const char *pathname, unsigned int mode, int stage,
2002                    void *cbdata)
2003  {
2004 +       struct walk_tree_context *walk_tree_ctx = cbdata;
2005         char *name;
2006         char *fullpath;
2007         char *class;
2008 @@ -153,7 +156,7 @@ static int ls_item(const unsigned char *sha1, const char *base, int baselen,
2009                 cgit_submodule_link("ls-mod", fullpath, sha1_to_hex(sha1));
2010         } else if (S_ISDIR(mode)) {
2011                 cgit_tree_link(name, NULL, "ls-dir", ctx.qry.head,
2012 -                              curr_rev, fullpath);
2013 +                              walk_tree_ctx->curr_rev, fullpath);
2014         } else {
2015                 class = strrchr(name, '.');
2016                 if (class != NULL) {
2017 @@ -161,19 +164,20 @@ static int ls_item(const unsigned char *sha1, const char *base, int baselen,
2018                 } else
2019                         class = "ls-blob";
2020                 cgit_tree_link(name, NULL, class, ctx.qry.head,
2021 -                              curr_rev, fullpath);
2022 +                              walk_tree_ctx->curr_rev, fullpath);
2023         }
2024         htmlf("</td><td class='ls-size'>%li</td>", size);
2025  
2026         html("<td>");
2027 -       cgit_log_link("log", NULL, "button", ctx.qry.head, curr_rev,
2028 -                     fullpath, 0, NULL, NULL, ctx.qry.showmsg);
2029 +       cgit_log_link("log", NULL, "button", ctx.qry.head,
2030 +                     walk_tree_ctx->curr_rev, fullpath, 0, NULL, NULL,
2031 +                     ctx.qry.showmsg);
2032         if (ctx.repo->max_stats)
2033                 cgit_stats_link("stats", NULL, "button", ctx.qry.head,
2034                                 fullpath);
2035         if (!S_ISGITLINK(mode))
2036 -               cgit_plain_link("plain", NULL, "button", ctx.qry.head, curr_rev,
2037 -                               fullpath);
2038 +               cgit_plain_link("plain", NULL, "button", ctx.qry.head,
2039 +                               walk_tree_ctx->curr_rev, fullpath);
2040         html("</td></tr>\n");
2041         free(name);
2042         return 0;
2043 @@ -188,20 +192,19 @@ static void ls_head()
2044         html("<th class='right'>Size</th>");
2045         html("<th/>");
2046         html("</tr>\n");
2047 -       header = 1;
2048  }
2049  
2050  static void ls_tail()
2051  {
2052 -       if (!header)
2053 -               return;
2054         html("</table>\n");
2055 -       header = 0;
2056  }
2057  
2058 -static void ls_tree(const unsigned char *sha1, char *path)
2059 +static void ls_tree(const unsigned char *sha1, char *path, struct walk_tree_context *walk_tree_ctx)
2060  {
2061         struct tree *tree;
2062 +       struct pathspec paths = {
2063 +               .nr = 0
2064 +       };
2065  
2066         tree = parse_tree_indirect(sha1);
2067         if (!tree) {
2068 @@ -211,7 +214,7 @@ static void ls_tree(const unsigned char *sha1, char *path)
2069         }
2070  
2071         ls_head();
2072 -       read_tree_recursive(tree, "", 0, 1, NULL, ls_item, NULL);
2073 +       read_tree_recursive(tree, "", 0, 1, &paths, ls_item, walk_tree_ctx);
2074         ls_tail();
2075  }
2076  
2077 @@ -220,25 +223,25 @@ static int walk_tree(const unsigned char *sha1, const char *base, int baselen,
2078                      const char *pathname, unsigned mode, int stage,
2079                      void *cbdata)
2080  {
2081 -       static int state;
2082 +       struct walk_tree_context *walk_tree_ctx = cbdata;
2083         static char buffer[PATH_MAX];
2084  
2085 -       if (state == 0) {
2086 +       if (walk_tree_ctx->state == 0) {
2087                 memcpy(buffer, base, baselen);
2088 -               strcpy(buffer+baselen, pathname);
2089 -               if (strcmp(match_path, buffer))
2090 +               strcpy(buffer + baselen, pathname);
2091 +               if (strcmp(walk_tree_ctx->match_path, buffer))
2092                         return READ_TREE_RECURSIVE;
2093  
2094                 if (S_ISDIR(mode)) {
2095 -                       state = 1;
2096 +                       walk_tree_ctx->state = 1;
2097                         ls_head();
2098                         return READ_TREE_RECURSIVE;
2099                 } else {
2100 -                       print_object(sha1, buffer, pathname);
2101 +                       print_object(sha1, buffer, pathname, walk_tree_ctx->curr_rev);
2102                         return 0;
2103                 }
2104         }
2105 -       ls_item(sha1, base, baselen, pathname, mode, stage, NULL);
2106 +       ls_item(sha1, base, baselen, pathname, mode, stage, walk_tree_ctx);
2107         return 0;
2108  }
2109  
2110 @@ -252,12 +255,23 @@ void cgit_print_tree(const char *rev, char *path)
2111  {
2112         unsigned char sha1[20];
2113         struct commit *commit;
2114 -       const char *paths[] = {path, NULL};
2115 +       struct pathspec_item path_items = {
2116 +               .match = path,
2117 +               .len = path ? strlen(path) : 0
2118 +       };
2119 +       struct pathspec paths = {
2120 +               .nr = path ? 1 : 0,
2121 +               .items = &path_items
2122 +       };
2123 +       struct walk_tree_context walk_tree_ctx = {
2124 +               .match_path = path,
2125 +               .state = 0
2126 +       };
2127  
2128         if (!rev)
2129                 rev = ctx.qry.head;
2130  
2131 -       curr_rev = xstrdup(rev);
2132 +       walk_tree_ctx.curr_rev = xstrdup(rev);
2133         if (get_sha1(rev, sha1)) {
2134                 cgit_print_error(fmt("Invalid revision name: %s", rev));
2135                 return;
2136 @@ -269,11 +283,11 @@ void cgit_print_tree(const char *rev, char *path)
2137         }
2138  
2139         if (path == NULL) {
2140 -               ls_tree(commit->tree->object.sha1, NULL);
2141 +               ls_tree(commit->tree->object.sha1, NULL, &walk_tree_ctx);
2142                 return;
2143         }
2144  
2145 -       match_path = path;
2146 -       read_tree_recursive(commit->tree, "", 0, 0, paths, walk_tree, NULL);
2147 -       ls_tail();
2148 +       read_tree_recursive(commit->tree, "", 0, 0, &paths, walk_tree, &walk_tree_ctx);
2149 +       if (walk_tree_ctx.state == 1)
2150 +               ls_tail();
2151  }
This page took 0.35272 seconds and 2 git commands to generate.