From d7de00f7e0d2374cb7933d2ee1ebe5273a8acf53 Mon Sep 17 00:00:00 2001 From: Timo Hirvonen Date: Sat, 24 Jun 2006 20:26:49 +0300 Subject: [PATCH 001/160] --name-only, --name-status, --check and -s are mutually exclusive Signed-off-by: Timo Hirvonen Signed-off-by: Junio C Hamano --- diff.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/diff.c b/diff.c index 1c131ff4dc..5358fd0c14 100644 --- a/diff.c +++ b/diff.c @@ -1433,6 +1433,19 @@ void diff_setup(struct diff_options *options) int diff_setup_done(struct diff_options *options) { + int count = 0; + + if (options->output_format & DIFF_FORMAT_NAME) + count++; + if (options->output_format & DIFF_FORMAT_NAME_STATUS) + count++; + if (options->output_format & DIFF_FORMAT_CHECKDIFF) + count++; + if (options->output_format & DIFF_FORMAT_NO_OUTPUT) + count++; + if (count > 1) + die("--name-only, --name-status, --check and -s are mutually exclusive"); + if ((options->find_copies_harder && options->detect_rename != DIFF_DETECT_COPY) || (0 <= options->rename_limit && !options->detect_rename)) From 5faf64cd28bf79f0c2939717d2ba117498717059 Mon Sep 17 00:00:00 2001 From: Timo Hirvonen Date: Sat, 24 Jun 2006 20:28:42 +0300 Subject: [PATCH 002/160] Remove awkward compatibility warts Signed-off-by: Timo Hirvonen Signed-off-by: Junio C Hamano --- builtin-diff-files.c | 7 ------- builtin-diff.c | 7 ------- 2 files changed, 14 deletions(-) diff --git a/builtin-diff-files.c b/builtin-diff-files.c index a655eea91e..3361898ada 100644 --- a/builtin-diff-files.c +++ b/builtin-diff-files.c @@ -47,12 +47,5 @@ int cmd_diff_files(int argc, const char **argv, char **envp) if (rev.pending.nr || rev.min_age != -1 || rev.max_age != -1) usage(diff_files_usage); - /* - * Backward compatibility wart - "diff-files -s" used to - * defeat the common diff option "-s" which asked for - * DIFF_FORMAT_NO_OUTPUT. - */ - if (rev.diffopt.output_format == DIFF_FORMAT_NO_OUTPUT) - rev.diffopt.output_format = DIFF_FORMAT_RAW; return run_diff_files(&rev, silent); } diff --git a/builtin-diff.c b/builtin-diff.c index d520c7ca29..059eb6de49 100644 --- a/builtin-diff.c +++ b/builtin-diff.c @@ -56,13 +56,6 @@ static int builtin_diff_files(struct rev_info *revs, if (revs->max_count < 0 && (revs->diffopt.output_format & DIFF_FORMAT_PATCH)) revs->combine_merges = revs->dense_combined_merges = 1; - /* - * Backward compatibility wart - "diff-files -s" used to - * defeat the common diff option "-s" which asked for - * DIFF_FORMAT_NO_OUTPUT. - */ - if (revs->diffopt.output_format == DIFF_FORMAT_NO_OUTPUT) - revs->diffopt.output_format = DIFF_FORMAT_RAW; return run_diff_files(revs, silent); } From 6ece0d3030ae2dc5b49fcfcc83df4966a52e0d0b Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 5 Jul 2006 17:41:39 -0700 Subject: [PATCH 003/160] upload-pack: use object pointer not copy of sha1 to keep track of has/needs. This does not change what happens in the command in any way, but is to prepare for further work. Signed-off-by: Junio C Hamano --- upload-pack.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/upload-pack.c b/upload-pack.c index b18eb9ba0d..d98d59f921 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -18,8 +18,8 @@ static const char upload_pack_usage[] = "git-upload-pack [--strict] [--timeout=n #define MAX_NEEDS 256 static int nr_has = 0, nr_needs = 0, multi_ack = 0, nr_our_refs = 0; static int use_thin_pack = 0; -static unsigned char has_sha1[MAX_HAS][20]; -static unsigned char needs_sha1[MAX_NEEDS][20]; +static struct object *has_tip[MAX_HAS]; +static struct object *needs_tip[MAX_NEEDS]; static unsigned int timeout = 0; static int use_sideband = 0; @@ -119,7 +119,7 @@ static void create_pack_file(void) else { for (i = 0; i < nr_needs; i++) { *p++ = buf; - memcpy(buf, sha1_to_hex(needs_sha1[i]), 41); + memcpy(buf, sha1_to_hex(needs_tip[i]->sha1), 41); buf += 41; } } @@ -127,7 +127,7 @@ static void create_pack_file(void) for (i = 0; i < nr_has; i++) { *p++ = buf; *buf++ = '^'; - memcpy(buf, sha1_to_hex(has_sha1[i]), 41); + memcpy(buf, sha1_to_hex(has_tip[i]->sha1), 41); buf += 41; } *p++ = NULL; @@ -336,7 +336,7 @@ static int got_sha1(char *hex, unsigned char *sha1) parents = parents->next) parents->item->object.flags |= THEY_HAVE; } - memcpy(has_sha1[nr_has++], sha1, 20); + has_tip[nr_has++] = o; } return 1; } @@ -395,23 +395,21 @@ static int receive_needs(void) needs = 0; for (;;) { struct object *o; - unsigned char dummy[20], *sha1_buf; + unsigned char sha1_buf[20]; len = packet_read_line(0, line, sizeof(line)); reset_timeout(); if (!len) return needs; - sha1_buf = dummy; if (needs == MAX_NEEDS) { fprintf(stderr, "warning: supporting only a max of %d requests. " "sending everything instead.\n", MAX_NEEDS); } - else if (needs < MAX_NEEDS) - sha1_buf = needs_sha1[needs]; - if (strncmp("want ", line, 5) || get_sha1_hex(line+5, sha1_buf)) + if (strncmp("want ", line, 5) || + get_sha1_hex(line+5, sha1_buf)) die("git-upload-pack: protocol error, " "expected to get sha, not '%s'", line); if (strstr(line+45, "multi_ack")) @@ -434,6 +432,8 @@ static int receive_needs(void) die("git-upload-pack: not our ref %s", line+5); if (!(o->flags & WANTED)) { o->flags |= WANTED; + if (needs < MAX_NEEDS) + needs_tip[needs] = o; needs++; } } From b1e9fff7e76c13cc16f0b4a4eda19600320bd7e7 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 5 Jul 2006 18:00:02 -0700 Subject: [PATCH 004/160] upload-pack: lift MAX_NEEDS and MAX_HAS limitation By using object_array data structure, lift the old limitation of MAX_HAS/MAX_NEEDS. While we are at it, rename the variables that hold the objects we use to compute common ancestor to match the message used at the protocol level. What the other end has and we also do are "have"s, and what the other end asks for are "want"s. Signed-off-by: Junio C Hamano --- upload-pack.c | 93 +++++++++++++++++++++++---------------------------- 1 file changed, 41 insertions(+), 52 deletions(-) diff --git a/upload-pack.c b/upload-pack.c index d98d59f921..5a911d6fb5 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -14,12 +14,10 @@ static const char upload_pack_usage[] = "git-upload-pack [--strict] [--timeout=n #define THEY_HAVE (1U << 0) #define OUR_REF (1U << 1) #define WANTED (1U << 2) -#define MAX_HAS 256 -#define MAX_NEEDS 256 -static int nr_has = 0, nr_needs = 0, multi_ack = 0, nr_our_refs = 0; +static int multi_ack = 0, nr_our_refs = 0; static int use_thin_pack = 0; -static struct object *has_tip[MAX_HAS]; -static struct object *needs_tip[MAX_NEEDS]; +static struct object_array have_obj; +static struct object_array want_obj; static unsigned int timeout = 0; static int use_sideband = 0; @@ -79,7 +77,7 @@ static void create_pack_file(void) */ int lp_pipe[2], pu_pipe[2], pe_pipe[2]; pid_t pid_rev_list, pid_pack_objects; - int create_full_pack = (nr_our_refs == nr_needs && !nr_has); + int create_full_pack = (nr_our_refs == want_obj.nr && !have_obj.nr); char data[8193], progress[128]; char abort_msg[] = "aborting due to possible repository " "corruption on the remote side."; @@ -103,7 +101,7 @@ static void create_pack_file(void) use_thin_pack = 0; /* no point doing it */ } else - args = nr_has + nr_needs + 5; + args = have_obj.nr + want_obj.nr + 5; p = xmalloc(args * sizeof(char *)); argv = (const char **) p; buf = xmalloc(args * 45); @@ -114,20 +112,22 @@ static void create_pack_file(void) close(lp_pipe[1]); *p++ = "rev-list"; *p++ = use_thin_pack ? "--objects-edge" : "--objects"; - if (create_full_pack || MAX_NEEDS <= nr_needs) + if (create_full_pack) *p++ = "--all"; else { - for (i = 0; i < nr_needs; i++) { + for (i = 0; i < want_obj.nr; i++) { + struct object *o = want_obj.objects[i].item; *p++ = buf; - memcpy(buf, sha1_to_hex(needs_tip[i]->sha1), 41); + memcpy(buf, sha1_to_hex(o->sha1), 41); buf += 41; } } if (!create_full_pack) - for (i = 0; i < nr_has; i++) { + for (i = 0; i < have_obj.nr; i++) { + struct object *o = have_obj.objects[i].item; *p++ = buf; *buf++ = '^'; - memcpy(buf, sha1_to_hex(has_tip[i]->sha1), 41); + memcpy(buf, sha1_to_hex(o->sha1), 41); buf += 41; } *p++ = NULL; @@ -316,28 +316,29 @@ static void create_pack_file(void) static int got_sha1(char *hex, unsigned char *sha1) { + struct object *o; + if (get_sha1_hex(hex, sha1)) die("git-upload-pack: expected SHA1 object, got '%s'", hex); if (!has_sha1_file(sha1)) return 0; - if (nr_has < MAX_HAS) { - struct object *o = lookup_object(sha1); - if (!(o && o->parsed)) - o = parse_object(sha1); - if (!o) - die("oops (%s)", sha1_to_hex(sha1)); - if (o->type == TYPE_COMMIT) { - struct commit_list *parents; - if (o->flags & THEY_HAVE) - return 0; - o->flags |= THEY_HAVE; - for (parents = ((struct commit*)o)->parents; - parents; - parents = parents->next) - parents->item->object.flags |= THEY_HAVE; - } - has_tip[nr_has++] = o; + + o = lookup_object(sha1); + if (!(o && o->parsed)) + o = parse_object(sha1); + if (!o) + die("oops (%s)", sha1_to_hex(sha1)); + if (o->type == TYPE_COMMIT) { + struct commit_list *parents; + if (o->flags & THEY_HAVE) + return 0; + o->flags |= THEY_HAVE; + for (parents = ((struct commit*)o)->parents; + parents; + parents = parents->next) + parents->item->object.flags |= THEY_HAVE; } + add_object_array(o, NULL, &have_obj); return 1; } @@ -355,26 +356,24 @@ static int get_common_commits(void) reset_timeout(); if (!len) { - if (nr_has == 0 || multi_ack) + if (have_obj.nr == 0 || multi_ack) packet_write(1, "NAK\n"); continue; } len = strip(line, len); if (!strncmp(line, "have ", 5)) { if (got_sha1(line+5, sha1) && - (multi_ack || nr_has == 1)) { - if (nr_has >= MAX_HAS) - multi_ack = 0; + (multi_ack || have_obj.nr == 1)) { packet_write(1, "ACK %s%s\n", - sha1_to_hex(sha1), - multi_ack ? " continue" : ""); + sha1_to_hex(sha1), + multi_ack ? " continue" : ""); if (multi_ack) memcpy(last_sha1, sha1, 20); } continue; } if (!strcmp(line, "done")) { - if (nr_has > 0) { + if (have_obj.nr > 0) { if (multi_ack) packet_write(1, "ACK %s\n", sha1_to_hex(last_sha1)); @@ -387,26 +386,18 @@ static int get_common_commits(void) } } -static int receive_needs(void) +static void receive_needs(void) { static char line[1000]; - int len, needs; + int len; - needs = 0; for (;;) { struct object *o; unsigned char sha1_buf[20]; len = packet_read_line(0, line, sizeof(line)); reset_timeout(); if (!len) - return needs; - - if (needs == MAX_NEEDS) { - fprintf(stderr, - "warning: supporting only a max of %d requests. " - "sending everything instead.\n", - MAX_NEEDS); - } + return; if (strncmp("want ", line, 5) || get_sha1_hex(line+5, sha1_buf)) @@ -432,9 +423,7 @@ static int receive_needs(void) die("git-upload-pack: not our ref %s", line+5); if (!(o->flags & WANTED)) { o->flags |= WANTED; - if (needs < MAX_NEEDS) - needs_tip[needs] = o; - needs++; + add_object_array(o, NULL, &want_obj); } } } @@ -470,8 +459,8 @@ static int upload_pack(void) head_ref(send_ref); for_each_ref(send_ref); packet_flush(1); - nr_needs = receive_needs(); - if (!nr_needs) + receive_needs(); + if (!want_obj.nr) return 0; get_common_commits(); create_pack_file(); From bb6b8e4f877e8b59b3756960e29d1955072dab56 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 17 Jul 2006 15:04:47 -0700 Subject: [PATCH 005/160] sha1_file.c: expose map_sha1_file() interface. This exposes map_sha1_file() interface to mmap a loose object file, and legacy_loose_object() function, split from unpack_sha1_header(). They will be used in the next patch to reuse the deflated data from new-style loose object files when generating packs. Signed-off-by: Junio C Hamano --- cache.h | 2 ++ sha1_file.c | 35 ++++++++++++++++++++++------------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/cache.h b/cache.h index eee5fc9f8d..01835ef432 100644 --- a/cache.h +++ b/cache.h @@ -240,6 +240,8 @@ extern int move_temp_to_file(const char *tmpfile, char *filename); extern int has_sha1_pack(const unsigned char *sha1); extern int has_sha1_file(const unsigned char *sha1); +extern void *map_sha1_file(const unsigned char *sha1, unsigned long *); +extern int legacy_loose_object(unsigned char *); extern int has_pack_file(const unsigned char *sha1); extern int has_pack_index(const unsigned char *sha1); diff --git a/sha1_file.c b/sha1_file.c index 43bc2ea0cf..51e07d5a45 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -646,8 +646,7 @@ int check_sha1_signature(const unsigned char *sha1, void *map, unsigned long siz return memcmp(sha1, real_sha1, 20) ? -1 : 0; } -static void *map_sha1_file_internal(const unsigned char *sha1, - unsigned long *size) +void *map_sha1_file(const unsigned char *sha1, unsigned long *size) { struct stat st; void *map; @@ -684,10 +683,26 @@ static void *map_sha1_file_internal(const unsigned char *sha1, return map; } +int legacy_loose_object(unsigned char *map) +{ + unsigned int word; + + /* + * Is it a zlib-compressed buffer? If so, the first byte + * must be 0x78 (15-bit window size, deflated), and the + * first 16-bit word is evenly divisible by 31 + */ + word = (map[0] << 8) + map[1]; + if (map[0] == 0x78 && !(word % 31)) + return 1; + else + return 0; +} + static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz) { unsigned char c; - unsigned int word, bits; + unsigned int bits; unsigned long size; static const char *typename[8] = { NULL, /* OBJ_EXT */ @@ -703,13 +718,7 @@ static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned lon stream->next_out = buffer; stream->avail_out = bufsiz; - /* - * Is it a zlib-compressed buffer? If so, the first byte - * must be 0x78 (15-bit window size, deflated), and the - * first 16-bit word is evenly divisible by 31 - */ - word = (map[0] << 8) + map[1]; - if (map[0] == 0x78 && !(word % 31)) { + if (legacy_loose_object(map)) { inflateInit(stream); return inflate(stream, 0); } @@ -1246,7 +1255,7 @@ int sha1_object_info(const unsigned char *sha1, char *type, unsigned long *sizep z_stream stream; char hdr[128]; - map = map_sha1_file_internal(sha1, &mapsize); + map = map_sha1_file(sha1, &mapsize); if (!map) { struct pack_entry e; @@ -1291,7 +1300,7 @@ void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size if (find_pack_entry(sha1, &e)) return read_packed_sha1(sha1, type, size); - map = map_sha1_file_internal(sha1, &mapsize); + map = map_sha1_file(sha1, &mapsize); if (map) { buf = unpack_sha1_file(map, mapsize, type, size); munmap(map, mapsize); @@ -1629,7 +1638,7 @@ int write_sha1_to_fd(int fd, const unsigned char *sha1) { int retval; unsigned long objsize; - void *buf = map_sha1_file_internal(sha1, &objsize); + void *buf = map_sha1_file(sha1, &objsize); if (buf) { retval = write_buffer(fd, buf, objsize); From ceec1361ebbc4613813ba42976503f5e304cfacf Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 17 Jul 2006 15:06:23 -0700 Subject: [PATCH 006/160] pack-objects: reuse deflated data from new-style loose objects. When packing an object without deltifying, if the data is stored in a loose object that is encoded with a new style header, copy it without inflating and deflating. Signed-off-by: Junio C Hamano --- pack-objects.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pack-objects.c b/pack-objects.c index 861c7f08ff..e52e9774e5 100644 --- a/pack-objects.c +++ b/pack-objects.c @@ -269,6 +269,22 @@ static unsigned long write_object(struct sha1file *f, * and we do not need to deltify it. */ + if (!entry->in_pack && !entry->delta) { + unsigned char *map; + unsigned long mapsize; + map = map_sha1_file(entry->sha1, &mapsize); + if (map && !legacy_loose_object(map)) { + /* We can copy straight into the pack file */ + sha1write(f, map, mapsize); + munmap(map, mapsize); + written++; + reused++; + return mapsize; + } + if (map) + munmap(map, mapsize); + } + if (! to_reuse) { buf = read_sha1_file(entry->sha1, type, &size); if (!buf) From 8e27364128b091e76059229d4f009bc7f869fa9f Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 17 Jul 2006 15:10:10 -0700 Subject: [PATCH 007/160] unpack-objects: read configuration data upon startup. With this, unpack-objects will write out the loose objects with new-style headers when core.legacyheaders configuration is set to false. One unfortunate thing is that we still need inflate/deflate cycle when unpacking, even for objects in the pack stream that are not deltified, because it is not possible to determine the boundary of objects in the encoded stream cheaply without inflating it first. Signed-off-by: Junio C Hamano --- unpack-objects.c | 1 + 1 file changed, 1 insertion(+) diff --git a/unpack-objects.c b/unpack-objects.c index 48c1ee7968..b23fe58ce1 100644 --- a/unpack-objects.c +++ b/unpack-objects.c @@ -266,6 +266,7 @@ int main(int argc, char **argv) unsigned char sha1[20]; setup_git_directory(); + git_config(git_default_config); quiet = !isatty(2); From 5be01bc8d5cf9c63827311ad76dd8b66353253e1 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sat, 29 Jul 2006 22:43:40 +0200 Subject: [PATCH 008/160] gitweb: whitespace cleanup Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 58 ++++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index e5fca63b9c..323dfca3f3 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -36,7 +36,7 @@ our $git_version = qx($GIT --version) =~ m/git version (.*)$/ ? $1 : "unknown"; # location for temporary files needed for diffs our $git_temp = "/tmp/gitweb"; if (! -d $git_temp) { - mkdir($git_temp, 0700) || die_error("Couldn't mkdir $git_temp"); + mkdir($git_temp, 0700) || die_error("Couldn't mkdir $git_temp"); } # target of the home link on top of all pages @@ -104,7 +104,7 @@ if (defined $project) { die_error(undef, "No such project."); } $rss_link = ""; + "$my_uri?" . esc_param("p=$project;a=rss") . "\" type=\"application/rss+xml\"/>"; $ENV{'GIT_DIR'} = "$projectroot/$project"; } else { git_project_list(); @@ -303,7 +303,7 @@ sub git_header_html { } else { $content_type = 'text/html'; } - print $cgi->header(-type=>$content_type, -charset => 'utf-8', -status=> $status, -expires => $expires); + print $cgi->header(-type=>$content_type, -charset => 'utf-8', -status=> $status, -expires => $expires); print < @@ -1138,17 +1138,17 @@ sub git_summary { "\n" . ""; if (defined($comment)) { - print $cgi->a({-class => "list", -href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}")}, esc_html($comment)); + print $cgi->a({-class => "list", -href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}")}, esc_html($comment)); } print "\n" . ""; if ($tag{'type'} eq "tag") { - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}")}, "tag") . " | "; + print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}")}, "tag") . " | "; } print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$tag{'reftype'};h=$tag{'refid'}")}, $tag{'reftype'}); if ($tag{'reftype'} eq "commit") { - print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog;h=$tag{'name'}")}, "shortlog") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log;h=$tag{'refid'}")}, "log"); + print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog;h=$tag{'name'}")}, "shortlog") . + " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log;h=$tag{'refid'}")}, "log"); } print "\n" . ""; @@ -1457,17 +1457,17 @@ sub git_tags { "\n" . ""; if (defined($comment)) { - print $cgi->a({-class => "list", -href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}")}, $comment); + print $cgi->a({-class => "list", -href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}")}, $comment); } print "\n" . ""; if ($tag{'type'} eq "tag") { - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}")}, "tag") . " | "; + print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}")}, "tag") . " | "; } print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$tag{'reftype'};h=$tag{'refid'}")}, $tag{'reftype'}); if ($tag{'reftype'} eq "commit") { - print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog;h=$tag{'name'}")}, "shortlog") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log;h=$tag{'refid'}")}, "log"); + print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog;h=$tag{'name'}")}, "shortlog") . + " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log;h=$tag{'refid'}")}, "log"); } print "\n" . ""; @@ -1613,13 +1613,14 @@ sub git_blob_plain_mimetype { sub git_blob_plain { if (!defined $hash) { - if (defined $file_name) { - my $base = $hash_base || git_read_head($project); - $hash = git_get_hash_by_path($base, $file_name, "blob") || die_error(undef, "Error lookup file."); - } else { - die_error(undef, "No file name defined."); - } - } + if (defined $file_name) { + my $base = $hash_base || git_read_head($project); + $hash = git_get_hash_by_path($base, $file_name, "blob") + or die_error(undef, "Error lookup file."); + } else { + die_error(undef, "No file name defined."); + } + } my $type = shift; open my $fd, "-|", "$GIT cat-file blob $hash" or die_error("Couldn't cat $file_name, $hash"); @@ -1644,13 +1645,14 @@ sub git_blob_plain { sub git_blob { if (!defined $hash) { - if (defined $file_name) { - my $base = $hash_base || git_read_head($project); - $hash = git_get_hash_by_path($base, $file_name, "blob") || die_error(undef, "Error lookup file."); - } else { - die_error(undef, "No file name defined."); - } - } + if (defined $file_name) { + my $base = $hash_base || git_read_head($project); + $hash = git_get_hash_by_path($base, $file_name, "blob") + or die_error(undef, "Error lookup file."); + } else { + die_error(undef, "No file name defined."); + } + } my $have_blame = git_get_project_config_bool ('blame'); open my $fd, "-|", "$GIT cat-file blob $hash" or die_error(undef, "Open failed."); my $mimetype = git_blob_plain_mimetype($fd, $file_name); @@ -1677,7 +1679,7 @@ sub git_blob { print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;h=$hash")}, "plain") . "
\n"; } print "\n". - "
" . + "
" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base"), -class => "title"}, esc_html($co{'title'})) . "
\n"; } else { @@ -2305,7 +2307,7 @@ sub git_commitdiff { my $status = $5; my $file = validate_input(unquote($6)); if ($status eq "A") { - print "
" . file_type($to_mode) . ":" . + print "
" . file_type($to_mode) . ":" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$file")}, $to_id) . "(new)" . "
\n"; git_diff_print(undef, "/dev/null", $to_id, "b/$file"); @@ -2359,7 +2361,7 @@ sub git_commitdiff_plain { "Date: $ad{'rfc2822'} ($ad{'tz_local'})\n". "Subject: $co{'title'}\n"; if (defined $tagname) { - print "X-Git-Tag: $tagname\n"; + print "X-Git-Tag: $tagname\n"; } print "X-Git-Url: $my_url?p=$project;a=commitdiff;h=$hash\n" . "\n"; From b9182987a80f7e820cbe1f8c7c4dc26f8586e8cd Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sun, 30 Jul 2006 18:28:34 -0700 Subject: [PATCH 009/160] gitweb: Use list for of open for running git commands, thorougly. Use list form of open for running git commands and reading their output through pipe, for example open my $fd, "-|", $GIT, "rev-list", "--header", "--parents", $hash instead of open my $fd, "-|", "$GIT rev-list --header --parents $hash" Single letter options use ' instead of " as quotes, according to style used in list form of magic "-|" open. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 51 +++++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index 323dfca3f3..8f7341f458 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -388,7 +388,7 @@ sub die_error { sub git_get_type { my $hash = shift; - open my $fd, "-|", "$GIT cat-file -t $hash" or return; + open my $fd, "-|", $GIT, "cat-file", '-t', $hash or return; my $type = <$fd>; close $fd or return; chomp $type; @@ -440,7 +440,7 @@ sub git_read_tag { my %tag; my @comment; - open my $fd, "-|", "$GIT cat-file tag $tag_id" or return; + open my $fd, "-|", $GIT, "cat-file", "tag", $tag_id or return; $tag{'id'} = $tag_id; while (my $line = <$fd>) { chomp $line; @@ -512,7 +512,7 @@ sub git_read_commit { @commit_lines = @$commit_text; } else { $/ = "\0"; - open my $fd, "-|", "$GIT rev-list --header --parents --max-count=1 $commit_id" or return; + open my $fd, "-|", $GIT, "rev-list", "--header", "--parents", "--max-count=1", $commit_id or return; @commit_lines = split '\n', <$fd>; close $fd or return; $/ = "\n"; @@ -610,7 +610,7 @@ sub git_diff_print { if (defined $from) { $from_tmp = "$git_temp/gitweb_" . $$ . "_from"; open my $fd2, "> $from_tmp"; - open my $fd, "-|", "$GIT cat-file blob $from"; + open my $fd, "-|", $GIT, "cat-file", "blob", $from; my @file = <$fd>; print $fd2 @file; close $fd2; @@ -621,7 +621,7 @@ sub git_diff_print { if (defined $to) { $to_tmp = "$git_temp/gitweb_" . $$ . "_to"; open my $fd2, "> $to_tmp"; - open my $fd, "-|", "$GIT cat-file blob $to"; + open my $fd, "-|", $GIT, "cat-file", "blob", $to; my @file = <$fd>; print $fd2 @file; close $fd2; @@ -1062,7 +1062,8 @@ sub git_summary { "owner$owner\n" . "last change$cd{'rfc2822'}\n" . "\n"; - open my $fd, "-|", "$GIT rev-list --max-count=17 " . git_read_head($project) or die_error(undef, "Open failed."); + open my $fd, "-|", $GIT, "rev-list", "--max-count=17", git_read_head($project) + or die_error(undef, "Open failed."); my (@revlist) = map { chomp; $_ } <$fd>; close $fd; print "
\n" . @@ -1526,7 +1527,7 @@ sub git_get_hash_by_path { my $tree = $base; my @parts = split '/', $path; while (my $part = shift @parts) { - open my $fd, "-|", "$GIT ls-tree $tree" or die_error(undef, "Open git-ls-tree failed."); + open my $fd, "-|", $GIT, "ls-tree", $tree or die_error(undef, "Open git-ls-tree failed."); my (@entries) = map { chomp; $_ } <$fd>; close $fd or return undef; foreach my $line (@entries) { @@ -1622,7 +1623,7 @@ sub git_blob_plain { } } my $type = shift; - open my $fd, "-|", "$GIT cat-file blob $hash" or die_error("Couldn't cat $file_name, $hash"); + open my $fd, "-|", $GIT, "cat-file", "blob", $hash or die_error("Couldn't cat $file_name, $hash"); $type ||= git_blob_plain_mimetype($fd, $file_name); @@ -1654,7 +1655,7 @@ sub git_blob { } } my $have_blame = git_get_project_config_bool ('blame'); - open my $fd, "-|", "$GIT cat-file blob $hash" or die_error(undef, "Open failed."); + open my $fd, "-|", $GIT, "cat-file", "blob", $hash or die_error(undef, "Open failed."); my $mimetype = git_blob_plain_mimetype($fd, $file_name); if ($mimetype !~ m/^text\//) { close $fd; @@ -1718,7 +1719,7 @@ sub git_tree { } } $/ = "\0"; - open my $fd, "-|", "$GIT ls-tree -z $hash" or die_error(undef, "Open git-ls-tree failed."); + open my $fd, "-|", $GIT, "ls-tree", '-z', $hash or die_error(undef, "Open git-ls-tree failed."); chomp (my (@entries) = <$fd>); close $fd or die_error(undef, "Reading tree failed."); $/ = "\n"; @@ -1799,7 +1800,8 @@ sub git_tree { sub git_rss { # http://www.notestips.com/80256B3A007F2692/1/NAMO5P9UPQ - open my $fd, "-|", "$GIT rev-list --max-count=150 " . git_read_head($project) or die_error(undef, "Open failed."); + open my $fd, "-|", $GIT, "rev-list", "--max-count=150", git_read_head($project) + or die_error(undef, "Open failed."); my (@revlist) = map { chomp; $_ } <$fd>; close $fd or die_error(undef, "Reading rev-list failed."); print $cgi->header(-type => 'text/xml', -charset => 'utf-8'); @@ -1819,7 +1821,7 @@ sub git_rss { last; } my %cd = date_str($co{'committer_epoch'}); - open $fd, "-|", "$GIT diff-tree -r $co{'parent'} $co{'id'}" or next; + open $fd, "-|", $GIT, "diff-tree", '-r', $co{'parent'}, $co{'id'} or next; my @difftree = map { chomp; $_ } <$fd>; close $fd or next; print "\n" . @@ -1907,7 +1909,7 @@ sub git_log { " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$hash;hb=$hash")}, "tree") . "
\n"; my $limit = sprintf("--max-count=%i", (100 * ($page+1))); - open my $fd, "-|", "$GIT rev-list $limit $hash" or die_error(undef, "Open failed."); + open my $fd, "-|", $GIT, "rev-list", $limit, $hash or die_error(undef, "Open failed."); my (@revlist) = map { chomp; $_ } <$fd>; close $fd; @@ -1992,15 +1994,14 @@ sub git_commit { my %cd = date_str($co{'committer_epoch'}, $co{'committer_tz'}); my @difftree; - my $root = ""; my $parent = $co{'parent'}; if (!defined $parent) { - $root = " --root"; - $parent = ""; + $parent = "--root"; } - open my $fd, "-|", "$GIT diff-tree -r -M $root $parent $hash" or die_error(undef, "Open failed."); + open my $fd, "-|", $GIT, "diff-tree", '-r', '-M', $parent, $hash + or die_error(undef, "Open failed."); @difftree = map { chomp; $_ } <$fd>; - close $fd or die_error(undef, "Reading diff-tree failed."); + close $fd or die_error(undef, "Reading git-diff-tree failed."); # non-textual hash id's can be cached my $expires; @@ -2244,7 +2245,8 @@ sub git_commitdiff { if (!defined $hash_parent) { $hash_parent = $co{'parent'}; } - open my $fd, "-|", "$GIT diff-tree -r $hash_parent $hash" or die_error(undef, "Open failed."); + open my $fd, "-|", $GIT, "diff-tree", '-r', $hash_parent, $hash + or die_error(undef, "Open failed."); my (@difftree) = map { chomp; $_ } <$fd>; close $fd or die_error(undef, "Reading diff-tree failed."); @@ -2334,14 +2336,15 @@ sub git_commitdiff { sub git_commitdiff_plain { mkdir($git_temp, 0700); - open my $fd, "-|", "$GIT diff-tree -r $hash_parent $hash" or die_error(undef, "Open failed."); + open my $fd, "-|", $GIT, "diff-tree", '-r', $hash_parent, $hash + or die_error(undef, "Open failed."); my (@difftree) = map { chomp; $_ } <$fd>; close $fd or die_error(undef, "Reading diff-tree failed."); # try to figure out the next tag after this commit my $tagname; my $refs = read_info_ref("tags"); - open $fd, "-|", "$GIT rev-list HEAD"; + open $fd, "-|", $GIT, "rev-list", "HEAD"; chomp (my (@commits) = <$fd>); close $fd; foreach my $commit (@commits) { @@ -2419,7 +2422,7 @@ sub git_history { git_print_page_path($file_name, $ftype); open my $fd, "-|", - "$GIT rev-list --full-history $hash_base -- \'$file_name\'"; + $GIT, "rev-list", "--full-history", $hash_base, "--", "\'$file_name\'"; print "\n"; my $alternate = 0; while (my $line = <$fd>) { @@ -2506,7 +2509,7 @@ sub git_search { my $alternate = 0; if ($commit_search) { $/ = "\0"; - open my $fd, "-|", "$GIT rev-list --header --parents $hash" or next; + open my $fd, "-|", $GIT, "rev-list", "--header", "--parents", $hash or next; while (my $commit_text = <$fd>) { if (!grep m/$searchtext/i, $commit_text) { next; @@ -2627,7 +2630,7 @@ sub git_shortlog { " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$hash;hb=$hash")}, "tree") . "
\n"; my $limit = sprintf("--max-count=%i", (100 * ($page+1))); - open my $fd, "-|", "$GIT rev-list $limit $hash" or die_error(undef, "Open failed."); + open my $fd, "-|", $GIT, "rev-list", $limit, $hash or die_error(undef, "Open failed."); my (@revlist) = map { chomp; $_ } <$fd>; close $fd; From dda754f7d4fa1bccd9f3349d73304856144a7cd2 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sat, 29 Jul 2006 22:55:01 +0200 Subject: [PATCH 010/160] gitweb: simplify git_get_hash_by_path Simplify git_get_hash_by_path by using git-ls-tree to do path limiting, instead of finding correct ttree and parsing unconstrained git-ls-tree output. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index 8f7341f458..9c214f534b 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -1525,29 +1525,15 @@ sub git_get_hash_by_path { my $path = shift || return undef; my $tree = $base; - my @parts = split '/', $path; - while (my $part = shift @parts) { - open my $fd, "-|", $GIT, "ls-tree", $tree or die_error(undef, "Open git-ls-tree failed."); - my (@entries) = map { chomp; $_ } <$fd>; - close $fd or return undef; - foreach my $line (@entries) { - #'100644 blob 0fa3f3a66fb6a137f6ec2c19351ed4d807070ffa panic.c' - $line =~ m/^([0-9]+) (.+) ([0-9a-fA-F]{40})\t(.+)$/; - my $t_mode = $1; - my $t_type = $2; - my $t_hash = $3; - my $t_name = validate_input(unquote($4)); - if ($t_name eq $part) { - if (!(@parts)) { - return $t_hash; - } - if ($t_type eq "tree") { - $tree = $t_hash; - } - last; - } - } - } + + open my $fd, "-|", $GIT, "ls-tree", $base, "--", $path + or die_error(undef, "Open git-ls-tree failed."); + my $line = <$fd>; + close $fd or return undef; + + #'100644 blob 0fa3f3a66fb6a137f6ec2c19351ed4d807070ffa panic.c' + $line =~ m/^([0-9]+) (.+) ([0-9a-fA-F]{40})\t(.+)$/; + return $3; } sub mimetype_guess_file { From 044bfdc8cbc4955f20afd7f9a245dfc20527ecbd Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sat, 29 Jul 2006 23:01:00 +0200 Subject: [PATCH 011/160] gitweb: More explicit error messages for open "-|" Use more explicit error messages when failing magical "-|" open, stating at least the name of the git command that failed. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index 9c214f534b..bf3e2ca5d1 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -1063,7 +1063,7 @@ sub git_summary { "\n" . "
last change$cd{'rfc2822'}
\n"; open my $fd, "-|", $GIT, "rev-list", "--max-count=17", git_read_head($project) - or die_error(undef, "Open failed."); + or die_error(undef, "Open git-rev-list failed."); my (@revlist) = map { chomp; $_ } <$fd>; close $fd; print "
\n" . @@ -1271,7 +1271,7 @@ sub git_blame2 { die_error("400 Bad Request", "object is not a blob"); } open ($fd, "-|", $GIT, "blame", '-l', $file_name, $hash_base) - or die_error(undef, "Open failed"); + or die_error(undef, "Open git-blame failed."); git_header_html(); print "
\n" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary")}, "summary") . @@ -1333,7 +1333,7 @@ sub git_blame { or die_error(undef, "Error lookup file."); } open ($fd, "-|", $GIT, "annotate", '-l', '-t', '-r', $file_name, $hash_base) - or die_error(undef, "Open failed."); + or die_error(undef, "Open git-annotate failed."); git_header_html(); print "
\n" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary")}, "summary") . @@ -1609,7 +1609,8 @@ sub git_blob_plain { } } my $type = shift; - open my $fd, "-|", $GIT, "cat-file", "blob", $hash or die_error("Couldn't cat $file_name, $hash"); + open my $fd, "-|", $GIT, "cat-file", "blob", $hash + or die_error("Couldn't cat $file_name, $hash"); $type ||= git_blob_plain_mimetype($fd, $file_name); @@ -1641,7 +1642,8 @@ sub git_blob { } } my $have_blame = git_get_project_config_bool ('blame'); - open my $fd, "-|", $GIT, "cat-file", "blob", $hash or die_error(undef, "Open failed."); + open my $fd, "-|", $GIT, "cat-file", "blob", $hash + or die_error(undef, "Couldn't cat $file_name, $hash."); my $mimetype = git_blob_plain_mimetype($fd, $file_name); if ($mimetype !~ m/^text\//) { close $fd; @@ -1705,7 +1707,8 @@ sub git_tree { } } $/ = "\0"; - open my $fd, "-|", $GIT, "ls-tree", '-z', $hash or die_error(undef, "Open git-ls-tree failed."); + open my $fd, "-|", $GIT, "ls-tree", '-z', $hash + or die_error(undef, "Open git-ls-tree failed."); chomp (my (@entries) = <$fd>); close $fd or die_error(undef, "Reading tree failed."); $/ = "\n"; @@ -1787,7 +1790,7 @@ sub git_tree { sub git_rss { # http://www.notestips.com/80256B3A007F2692/1/NAMO5P9UPQ open my $fd, "-|", $GIT, "rev-list", "--max-count=150", git_read_head($project) - or die_error(undef, "Open failed."); + or die_error(undef, "Open git-rev-list failed."); my (@revlist) = map { chomp; $_ } <$fd>; close $fd or die_error(undef, "Reading rev-list failed."); print $cgi->header(-type => 'text/xml', -charset => 'utf-8'); @@ -1895,7 +1898,8 @@ sub git_log { " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$hash;hb=$hash")}, "tree") . "
\n"; my $limit = sprintf("--max-count=%i", (100 * ($page+1))); - open my $fd, "-|", $GIT, "rev-list", $limit, $hash or die_error(undef, "Open failed."); + open my $fd, "-|", $GIT, "rev-list", $limit, $hash + or die_error(undef, "Open git-rev-list failed."); my (@revlist) = map { chomp; $_ } <$fd>; close $fd; @@ -1985,7 +1989,7 @@ sub git_commit { $parent = "--root"; } open my $fd, "-|", $GIT, "diff-tree", '-r', '-M', $parent, $hash - or die_error(undef, "Open failed."); + or die_error(undef, "Open git-diff-tree failed."); @difftree = map { chomp; $_ } <$fd>; close $fd or die_error(undef, "Reading git-diff-tree failed."); @@ -2232,7 +2236,7 @@ sub git_commitdiff { $hash_parent = $co{'parent'}; } open my $fd, "-|", $GIT, "diff-tree", '-r', $hash_parent, $hash - or die_error(undef, "Open failed."); + or die_error(undef, "Open git-diff-tree failed."); my (@difftree) = map { chomp; $_ } <$fd>; close $fd or die_error(undef, "Reading diff-tree failed."); @@ -2323,7 +2327,7 @@ sub git_commitdiff { sub git_commitdiff_plain { mkdir($git_temp, 0700); open my $fd, "-|", $GIT, "diff-tree", '-r', $hash_parent, $hash - or die_error(undef, "Open failed."); + or die_error(undef, "Open git-diff-tree failed."); my (@difftree) = map { chomp; $_ } <$fd>; close $fd or die_error(undef, "Reading diff-tree failed."); @@ -2616,7 +2620,8 @@ sub git_shortlog { " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$hash;hb=$hash")}, "tree") . "
\n"; my $limit = sprintf("--max-count=%i", (100 * ($page+1))); - open my $fd, "-|", $GIT, "rev-list", $limit, $hash or die_error(undef, "Open failed."); + open my $fd, "-|", $GIT, "rev-list", $limit, $hash + or die_error(undef, "Open git-rev-list failed."); my (@revlist) = map { chomp; $_ } <$fd>; close $fd; From cefda27f741a948a78ce27180f5332c2d19199c4 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sun, 30 Jul 2006 04:08:17 +0200 Subject: [PATCH 012/160] gitweb: Cleanup - chomp $line in consistent style Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index bf3e2ca5d1..e7ae65adfc 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -635,7 +635,7 @@ sub git_diff_print { $/ = "\n"; } else { while (my $line = <$fd>) { - chomp($line); + chomp $line; my $char = substr($line, 0, 1); my $diff_class = ""; if ($char eq '+') { @@ -944,7 +944,7 @@ sub read_info_ref { # c39ae07f393806ccf406ef966e9a15afc43cc36a refs/tags/v2.6.11^{} open my $fd, "$projectroot/$project/info/refs" or return; while (my $line = <$fd>) { - chomp($line); + chomp $line; if ($line =~ m/^([0-9a-fA-F]{40})\t.*$type\/([^\^]+)/) { if (defined $refs{$1}) { $refs{$1} .= " / $2"; From 0881d2d1303a067a02e3811d43a1aed04a47945e Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sun, 30 Jul 2006 14:58:11 +0200 Subject: [PATCH 013/160] gitweb: Cleanup - chomp @lines in consistent style Use 'my @lines = map { chomp; $_ } <$fd>;' form to read all lines of git command output into array without trailing newlines. It has advantage over 'chomp (my (@lines) = <$fd>);' in that it does not modify array. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index e7ae65adfc..98505551cd 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -1064,7 +1064,7 @@ sub git_summary { "\n"; open my $fd, "-|", $GIT, "rev-list", "--max-count=17", git_read_head($project) or die_error(undef, "Open git-rev-list failed."); - my (@revlist) = map { chomp; $_ } <$fd>; + my @revlist = map { chomp; $_ } <$fd>; close $fd; print "
\n" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog"), -class => "title"}, "shortlog") . @@ -1709,7 +1709,7 @@ sub git_tree { $/ = "\0"; open my $fd, "-|", $GIT, "ls-tree", '-z', $hash or die_error(undef, "Open git-ls-tree failed."); - chomp (my (@entries) = <$fd>); + my @entries = map { chomp; $_ } <$fd>; close $fd or die_error(undef, "Reading tree failed."); $/ = "\n"; @@ -1791,7 +1791,7 @@ sub git_rss { # http://www.notestips.com/80256B3A007F2692/1/NAMO5P9UPQ open my $fd, "-|", $GIT, "rev-list", "--max-count=150", git_read_head($project) or die_error(undef, "Open git-rev-list failed."); - my (@revlist) = map { chomp; $_ } <$fd>; + my @revlist = map { chomp; $_ } <$fd>; close $fd or die_error(undef, "Reading rev-list failed."); print $cgi->header(-type => 'text/xml', -charset => 'utf-8'); print "\n". @@ -1900,7 +1900,7 @@ sub git_log { my $limit = sprintf("--max-count=%i", (100 * ($page+1))); open my $fd, "-|", $GIT, "rev-list", $limit, $hash or die_error(undef, "Open git-rev-list failed."); - my (@revlist) = map { chomp; $_ } <$fd>; + my @revlist = map { chomp; $_ } <$fd>; close $fd; if ($hash ne $head || $page) { @@ -1983,14 +1983,13 @@ sub git_commit { my %ad = date_str($co{'author_epoch'}, $co{'author_tz'}); my %cd = date_str($co{'committer_epoch'}, $co{'committer_tz'}); - my @difftree; my $parent = $co{'parent'}; if (!defined $parent) { $parent = "--root"; } open my $fd, "-|", $GIT, "diff-tree", '-r', '-M', $parent, $hash or die_error(undef, "Open git-diff-tree failed."); - @difftree = map { chomp; $_ } <$fd>; + my @difftree = map { chomp; $_ } <$fd>; close $fd or die_error(undef, "Reading git-diff-tree failed."); # non-textual hash id's can be cached @@ -2237,7 +2236,7 @@ sub git_commitdiff { } open my $fd, "-|", $GIT, "diff-tree", '-r', $hash_parent, $hash or die_error(undef, "Open git-diff-tree failed."); - my (@difftree) = map { chomp; $_ } <$fd>; + my @difftree = map { chomp; $_ } <$fd>; close $fd or die_error(undef, "Reading diff-tree failed."); # non-textual hash id's can be cached @@ -2328,14 +2327,14 @@ sub git_commitdiff_plain { mkdir($git_temp, 0700); open my $fd, "-|", $GIT, "diff-tree", '-r', $hash_parent, $hash or die_error(undef, "Open git-diff-tree failed."); - my (@difftree) = map { chomp; $_ } <$fd>; + my @difftree = map { chomp; $_ } <$fd>; close $fd or die_error(undef, "Reading diff-tree failed."); # try to figure out the next tag after this commit my $tagname; my $refs = read_info_ref("tags"); open $fd, "-|", $GIT, "rev-list", "HEAD"; - chomp (my (@commits) = <$fd>); + my @commits = map { chomp; $_ } <$fd>; close $fd; foreach my $commit (@commits) { if (defined $refs->{$commit}) { @@ -2622,7 +2621,7 @@ sub git_shortlog { my $limit = sprintf("--max-count=%i", (100 * ($page+1))); open my $fd, "-|", $GIT, "rev-list", $limit, $hash or die_error(undef, "Open git-rev-list failed."); - my (@revlist) = map { chomp; $_ } <$fd>; + my @revlist = map { chomp; $_ } <$fd>; close $fd; if ($hash ne $head || $page) { From b18f9bf462cd37bc19368cb7d5c539e019d8fd67 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sun, 30 Jul 2006 14:59:57 +0200 Subject: [PATCH 014/160] gitweb: Add git_page_nav for later use Adds git_page_nav subroutine to factor out the generation of the navigation bar. Based on Sven Verdoolaege code Message-Id: <20050618113121.GA13122@pc117b.liacs.nl> http://marc.theaimsgroup.com/?l=git&m=111909432415478&w=2 I tried for the refactored navbar generate the same result. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index 98505551cd..d0d3f3efb1 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -385,6 +385,40 @@ sub die_error { exit; } +sub git_page_nav { + my ($current, $suppress, $head, $treehead, $treebase, $extra) = @_; + $extra = '' if !defined $extra; # pager or formats + + my @navs = qw(summary shortlog log commit commitdiff tree); + if ($suppress) { + @navs = grep { $_ ne $suppress } @navs; + } + + my %arg = map { $_, ''} @navs; + if (defined $head) { + for (qw(commit commitdiff)) { + $arg{$_} = ";h=$head"; + } + if ($current =~ m/^(tree | log | shortlog | commit | commitdiff | search)$/x) { + for (qw(shortlog log)) { + $arg{$_} = ";h=$head"; + } + } + } + $arg{tree} .= ";h=$treehead" if defined $treehead; + $arg{tree} .= ";hb=$treebase" if defined $treebase; + + print "
\n" . + (join " | ", + map { $_ eq $current + ? $_ + : $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$_$arg{$_}")}, "$_") + } + @navs); + print "
$extra
\n" . + "
\n"; +} + sub git_get_type { my $hash = shift; From 0d83ddc40f356aa0b5618a6571f5146818ec2b41 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sun, 30 Jul 2006 15:01:07 +0200 Subject: [PATCH 015/160] gitweb: Navbar refactoring - use git_page_nav to generate navigation bar Use git_page_nav subroutine to generate navigation bar. Additional navigation (either formats or pager/pagination) is put into variables. Corrects error in git_search where hash parameter was added to "summary" link instead of to "log" link. Might differ from previous version by additional "
" in navigation bar. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 235 +++++++++++++--------------------------------- 1 file changed, 66 insertions(+), 169 deletions(-) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index d0d3f3efb1..2b35763eef 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -1081,15 +1081,7 @@ sub git_summary { my $refs = read_info_ref(); git_header_html(); - print "
\n" . - "summary". - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog")}, "shortlog") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log")}, "log") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$head")}, "commit") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$head")}, "commitdiff") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree")}, "tree") . - "

\n" . - "
\n"; + git_page_nav('summary','', $head); print "
 
\n"; print "\n" . "\n" . @@ -1251,15 +1243,7 @@ sub git_print_page_path { sub git_tag { my $head = git_read_head($project); git_header_html(); - print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary")}, "summary") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog")}, "shortlog") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log")}, "log") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$head")}, "commit") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$head")}, "commitdiff") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;hb=$head")}, "tree") . "
\n" . - "
\n" . - "
\n"; + git_page_nav('','', $head,undef,$head); my %tag = git_read_tag($hash); print "
\n" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash"), -class => "title"}, esc_html($tag{'name'})) . "\n" . @@ -1307,19 +1291,13 @@ sub git_blame2 { open ($fd, "-|", $GIT, "blame", '-l', $file_name, $hash_base) or die_error(undef, "Open git-blame failed."); git_header_html(); - print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary")}, "summary") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog")}, "shortlog") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log")}, "log") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base")}, "commit") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$hash_base")}, "commitdiff") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$co{'tree'};hb=$hash_base")}, "tree") . "
\n"; - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$hash;hb=$hash_base;f=$file_name")}, "blob") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;f=$file_name")}, "head") . "
\n"; - print "
\n". - "
" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base"), -class => "title"}, esc_html($co{'title'})) . - "
\n"; + my $formats_nav = + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$hash;hb=$hash_base;f=$file_name")}, "blob") . + " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;f=$file_name")}, "head"); + git_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); + print "
" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base"), -class => "title"}, esc_html($co{'title'})) . + "
\n"; git_print_page_path($file_name, $ftype); my @rev_color = (qw(light dark)); my $num_colors = scalar(@rev_color); @@ -1369,19 +1347,13 @@ sub git_blame { open ($fd, "-|", $GIT, "annotate", '-l', '-t', '-r', $file_name, $hash_base) or die_error(undef, "Open git-annotate failed."); git_header_html(); - print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary")}, "summary") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog")}, "shortlog") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log")}, "log") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base")}, "commit") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$hash_base")}, "commitdiff") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$co{'tree'};hb=$hash_base")}, "tree") . "
\n"; - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$hash;hb=$hash_base;f=$file_name")}, "blob") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;f=$file_name")}, "head") . "
\n"; - print "
\n". - "
" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base"), -class => "title"}, esc_html($co{'title'})) . - "
\n"; + my $formats_nav = + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$hash;hb=$hash_base;f=$file_name")}, "blob") . + " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;f=$file_name")}, "head"); + git_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); + print "
" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base"), -class => "title"}, esc_html($co{'title'})) . + "
\n"; git_print_page_path($file_name); print "
\n"; print <\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary")}, "summary") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog")}, "shortlog") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log")}, "log") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$head")}, "commit") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$head")}, "commitdiff") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;hb=$head")}, "tree") . "
\n" . - "
\n" . - "
\n"; + git_page_nav('','', $head,undef,$head); my $taglist = git_read_refs("refs/tags"); print "
\n" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary"), -class => "title"}, " ") . @@ -1515,15 +1479,7 @@ sub git_tags { sub git_heads { my $head = git_read_head($project); git_header_html(); - print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary")}, "summary") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog")}, "shortlog") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log")}, "log") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$head")}, "commit") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$head")}, "commitdiff") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;hb=$head")}, "tree") . "
\n" . - "
\n" . - "
\n"; + git_page_nav('','', $head,undef,$head); my $taglist = git_read_refs("refs/heads"); print "
\n" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary"), -class => "title"}, " ") . @@ -1684,25 +1640,20 @@ sub git_blob { return git_blob_plain($mimetype); } git_header_html(); + my $formats_nav = ''; if (defined $hash_base && (my %co = git_read_commit($hash_base))) { - print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary")}, "summary") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog")}, "shortlog") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log")}, "log") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base")}, "commit") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$hash_base")}, "commitdiff") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$co{'tree'};hb=$hash_base")}, "tree") . "
\n"; if (defined $file_name) { if ($have_blame) { - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;h=$hash;hb=$hash_base;f=$file_name")}, "blame") . " | "; + $formats_nav .= $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;h=$hash;hb=$hash_base;f=$file_name")}, "blame") . " | "; } - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;h=$hash;f=$file_name")}, "plain") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;hb=HEAD;f=$file_name")}, "head") . "
\n"; + $formats_nav .= + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;h=$hash;f=$file_name")}, "plain") . + " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;hb=HEAD;f=$file_name")}, "head"); } else { - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;h=$hash")}, "plain") . "
\n"; + $formats_nav .= $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;h=$hash")}, "plain"); } - print "
\n". - "
" . + git_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); + print "
" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base"), -class => "title"}, esc_html($co{'title'})) . "
\n"; } else { @@ -1757,15 +1708,7 @@ sub git_tree { my $base = ""; if (defined $hash_base && (my %co = git_read_commit($hash_base))) { $base_key = ";hb=$hash_base"; - print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary")}, "summary") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog;h=$hash_base")}, "shortlog") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log;h=$hash_base")}, "log") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base")}, "commit") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$hash_base")}, "commitdiff") . - " | tree" . - "

\n" . - "
\n"; + git_page_nav('tree','', $hash_base); print "
\n" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base"), -class => "title"}, esc_html($co{'title'}) . $ref) . "\n" . "
\n"; @@ -1922,14 +1865,6 @@ sub git_log { $page = 0; } my $refs = read_info_ref(); - git_header_html(); - print "
\n"; - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary")}, "summary") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog;h=$hash")}, "shortlog") . - " | log" . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash")}, "commit") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$hash")}, "commitdiff") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$hash;hb=$hash")}, "tree") . "
\n"; my $limit = sprintf("--max-count=%i", (100 * ($page+1))); open my $fd, "-|", $GIT, "rev-list", $limit, $hash @@ -1937,25 +1872,28 @@ sub git_log { my @revlist = map { chomp; $_ } <$fd>; close $fd; + my $paging_nav = ''; if ($hash ne $head || $page) { - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log")}, "HEAD"); + $paging_nav .= $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log")}, "HEAD"); } else { - print "HEAD"; + $paging_nav .= "HEAD"; } if ($page > 0) { - print " ⋅ " . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log;h=$hash;pg=" . ($page-1)), -accesskey => "p", -title => "Alt-p"}, "prev"); + $paging_nav .= " ⋅ " . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log;h=$hash;pg=" . ($page-1)), -accesskey => "p", -title => "Alt-p"}, "prev"); } else { - print " ⋅ prev"; + $paging_nav .= " ⋅ prev"; } if ($#revlist >= (100 * ($page+1)-1)) { - print " ⋅ " . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log;h=$hash;pg=" . ($page+1)), -accesskey => "n", -title => "Alt-n"}, "next"); + $paging_nav .= " ⋅ " . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log;h=$hash;pg=" . ($page+1)), -accesskey => "n", -title => "Alt-n"}, "next"); } else { - print " ⋅ next"; + $paging_nav .= " ⋅ next"; } - print "
\n" . - "
\n"; + + git_header_html(); + git_page_nav('log','', $hash,undef,undef, $paging_nav); + if (!@revlist) { print "
\n" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary"), -class => "title"}, " ") . @@ -2037,21 +1975,14 @@ sub git_commit { $ref = " " . esc_html($refs->{$co{'id'}}) . ""; } git_header_html(undef, $expires); - print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary")}, "summary") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog;h=$hash")}, "shortlog") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log;h=$hash")}, "log") . - " | commit"; - if (defined $co{'parent'}) { - print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$hash")}, "commitdiff"); - } - print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$co{'tree'};hb=$hash")}, "tree") . "\n" . - "
\n"; + my $formats_nav = ''; if (defined $file_name && defined $co{'parent'}) { my $parent = $co{'parent'}; - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;hb=$parent;f=$file_name")}, "blame") . "\n"; + $formats_nav .= $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;hb=$parent;f=$file_name")}, "blame"); } - print "
\n"; + git_page_nav('commit', defined $co{'parent'} ? '' : 'commitdiff', + $hash, $co{'tree'}, $hash, + $formats_nav); if (defined $co{'parent'}) { print "
\n" . @@ -2223,16 +2154,9 @@ sub git_blobdiff { mkdir($git_temp, 0700); git_header_html(); if (defined $hash_base && (my %co = git_read_commit($hash_base))) { - print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary")}, "summary") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog")}, "shortlog") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log")}, "log") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base")}, "commit") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$hash_base")}, "commitdiff") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$co{'tree'};hb=$hash_base")}, "tree") . - "
\n"; - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blobdiff_plain;h=$hash;hp=$hash_parent")}, "plain") . - "
\n"; + my $formats_nav = + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blobdiff_plain;h=$hash;hp=$hash_parent")}, "plain"); + git_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); print "
\n" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base"), -class => "title"}, esc_html($co{'title'})) . "\n" . "
\n"; @@ -2284,15 +2208,9 @@ sub git_commitdiff { $ref = " " . esc_html($refs->{$co{'id'}}) . ""; } git_header_html(undef, $expires); - print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary")}, "summary") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog;h=$hash")}, "shortlog") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log;h=$hash")}, "log") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash")}, "commit") . - " | commitdiff" . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$co{'tree'};hb=$hash")}, "tree") . "
\n"; - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff_plain;h=$hash;hp=$hash_parent")}, "plain") . "\n" . - "
\n"; + my $formats_nav = + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff_plain;h=$hash;hp=$hash_parent")}, "plain"); + git_page_nav('commitdiff','', $hash,$co{'tree'},$hash, $formats_nav); print "
\n" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash"), -class => "title"}, esc_html($co{'title'}) . $ref) . "\n" . "
\n"; @@ -2424,15 +2342,7 @@ sub git_history { } my $refs = read_info_ref(); git_header_html(); - print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary")}, "summary") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog")}, "shortlog") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log")}, "log") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base")}, "commit") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$hash_base")}, "commitdiff") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$co{'tree'};hb=$hash_base")}, "tree") . - "

\n" . - "
\n"; + git_page_nav('','', $hash_base,$co{'tree'},$hash_base); print "
\n" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base"), -class => "title"}, esc_html($co{'title'})) . "\n" . "
\n"; @@ -2515,15 +2425,7 @@ sub git_search { $pickaxe_search = 1; } git_header_html(); - print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary;h=$hash")}, "summary") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog")}, "shortlog") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log;h=$hash")}, "log") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash")}, "commit") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$hash")}, "commitdiff") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$co{'tree'};hb=$hash")}, "tree") . - "

\n" . - "
\n"; + git_page_nav('','', $hash,$co{'tree'},$hash); print "
\n" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash"), -class => "title"}, esc_html($co{'title'})) . "\n" . @@ -2643,14 +2545,6 @@ sub git_shortlog { $page = 0; } my $refs = read_info_ref(); - git_header_html(); - print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary")}, "summary") . - " | shortlog" . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log;h=$hash")}, "log") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash")}, "commit") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$hash")}, "commitdiff") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$hash;hb=$hash")}, "tree") . "
\n"; my $limit = sprintf("--max-count=%i", (100 * ($page+1))); open my $fd, "-|", $GIT, "rev-list", $limit, $hash @@ -2658,25 +2552,28 @@ sub git_shortlog { my @revlist = map { chomp; $_ } <$fd>; close $fd; + my $paging_nav = ''; if ($hash ne $head || $page) { - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog")}, "HEAD"); + $paging_nav .= $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog")}, "HEAD"); } else { - print "HEAD"; + $paging_nav .= "HEAD"; } if ($page > 0) { - print " ⋅ " . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog;h=$hash;pg=" . ($page-1)), -accesskey => "p", -title => "Alt-p"}, "prev"); + $paging_nav .= " ⋅ " . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog;h=$hash;pg=" . ($page-1)), -accesskey => "p", -title => "Alt-p"}, "prev"); } else { - print " ⋅ prev"; + $paging_nav .= " ⋅ prev"; } if ($#revlist >= (100 * ($page+1)-1)) { - print " ⋅ " . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog;h=$hash;pg=" . ($page+1)), -accesskey => "n", -title => "Alt-n"}, "next"); + $paging_nav .= " ⋅ " . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog;h=$hash;pg=" . ($page+1)), -accesskey => "n", -title => "Alt-n"}, "next"); } else { - print " ⋅ next"; + $paging_nav .= " ⋅ next"; } - print "
\n" . - "
\n"; + + git_header_html(); + git_page_nav('shortlog','', $hash,$hash,$hash, $paging_nav); + print "
\n" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary"), -class => "title"}, " ") . "
\n"; From 3dc1383290f9db3371a13ae8009ce4fcd5ffc93a Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sun, 30 Jul 2006 15:02:27 +0200 Subject: [PATCH 016/160] gitweb: Replace form-feed character by ^L From 2be5cab10486cba804ccae063e93b146288054fe Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sun, 30 Jul 2006 13:11:56 +0200 Subject: [PATCH] Replace FORM FEED (FF) character (014, 12, 0xc) by it's textual representation '^L'. This character is used for example in GNU GPL 'COPYING' file. With this patch "blob" output for COPYING passes XHTML validation. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 1 + 1 file changed, 1 insertion(+) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index 2b35763eef..79275f38d3 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -250,6 +250,7 @@ sub esc_html { my $str = shift; $str = decode("utf8", $str, Encode::FB_DEFAULT); $str = escapeHTML($str); + $str =~ s/\014/^L/g; # escape FORM FEED (FF) character (e.g. in COPYING file) return $str; } From 7d91010df4d8c3d6f38734dc37cf7013a490670e Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sun, 30 Jul 2006 17:47:22 +0200 Subject: [PATCH 017/160] gitweb: Show project descriptions with utf-8 characters in project list correctly Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index 79275f38d3..673db1f639 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -958,7 +958,7 @@ sub git_project_list { } $alternate ^= 1; print "
\n" . - "\n" . + "\n" . "\n"; print "\n" . "\n"; } else { @@ -1638,7 +1637,6 @@ sub git_heads { git_header_div('summary', $project); my $taglist = git_read_refs("refs/heads"); - my $alternate = 0; if (defined @$taglist) { git_heads_body($taglist, $head); } From d636ad9743783c728469a9b644c23c0415fe1a7b Mon Sep 17 00:00:00 2001 From: Luben Tuikov Date: Fri, 4 Aug 2006 15:11:47 -0700 Subject: [PATCH 080/160] gitweb: bugfix: git_commit and git_commitdiff parents In git_commit() the hash base of $from_id is $parent, not $hash: - If status is "D", then action blob for $from_id wants $parent, not $hash. History needs $parent too. - If status is "R", then action blob for $from_id wants $parent, not $hash. Similarly in git_commitdiff() the hash base of $from_id is $hash_parent, not $hash. Signed-off-by: Luben Tuikov Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index eabece78c2..6a92316677 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -2015,11 +2015,11 @@ sub git_commit { "\n"; } elsif ($status eq "D") { print "\n" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$parent;f=$file"), -class => "list"}, esc_html($file)) . "\n" . "\n" . "\n" } elsif ($status eq "M" || $status eq "T") { my $mode_chnge = ""; @@ -2061,7 +2061,7 @@ sub git_commit { print "\n" . "\n" . "\n"; } else { @@ -1282,24 +1282,24 @@ sub git_project_list { die_error(undef, "Unknown order parameter"); } - my @list = git_read_projects(); + my @list = git_get_projects_list(); my @projects; if (!@list) { die_error(undef, "No projects found"); } foreach my $pr (@list) { - my $head = git_read_head($pr->{'path'}); + my $head = git_get_head_hash($pr->{'path'}); if (!defined $head) { next; } $ENV{'GIT_DIR'} = "$projectroot/$pr->{'path'}"; - my %co = git_read_commit($head); + my %co = parse_commit($head); if (!%co) { next; } $pr->{'commit'} = \%co; if (!defined $pr->{'descr'}) { - my $descr = git_read_description($pr->{'path'}) || ""; + my $descr = git_get_project_description($pr->{'path'}) || ""; $pr->{'descr'} = chop_str($descr, 25, 5); } if (!defined $pr->{'owner'}) { @@ -1383,10 +1383,10 @@ sub git_project_list { } sub git_summary { - my $descr = git_read_description($project) || "none"; - my $head = git_read_head($project); - my %co = git_read_commit($head); - my %cd = date_str($co{'committer_epoch'}, $co{'committer_tz'}); + my $descr = git_get_project_description($project) || "none"; + my $head = git_get_head_hash($project); + my %co = parse_commit($head); + my %cd = parse_date($co{'committer_epoch'}, $co{'committer_tz'}); my $owner; if (-f $projects_list) { @@ -1407,9 +1407,9 @@ sub git_summary { $owner = get_file_owner("$projectroot/$project"); } - my $refs = read_info_ref(); + my $refs = git_get_references(); git_header_html(); - git_page_nav('summary','', $head); + git_print_page_nav('summary','', $head); print "
 
\n"; print "
description" . esc_html($descr) . "
" . $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=summary"), -class => "list"}, esc_html($pr->{'path'})) . "$pr->{'descr'}" . esc_html($pr->{'descr'}) . "" . chop_str($pr->{'owner'}, 15) . "{'commit'}{'age'}) . "\">" . $pr->{'commit'}{'age_string'} . "" . From 898a893fc9bd6510022e6248af39ca4f521e40d6 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sun, 30 Jul 2006 16:14:43 +0200 Subject: [PATCH 018/160] gitweb: Add "\n" after
in git_page_nav Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index 673db1f639..03002f04f3 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -416,7 +416,7 @@ sub git_page_nav { : $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$_$arg{$_}")}, "$_") } @navs); - print "
$extra
\n" . + print "
\n$extra
\n" . "\n"; } From 43ffc06d98e944670b71869ba7126003597a2fa0 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sun, 30 Jul 2006 17:49:00 +0200 Subject: [PATCH 019/160] gitweb: Pager refactoring - use git_get_paging_nav for pagination Add git_get_paging_nav subroutine which returns string with pager (paging nav) for shortlog and log actions. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 68 ++++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 36 deletions(-) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index 03002f04f3..8e5e4c83c5 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -420,6 +420,36 @@ sub git_page_nav { "\n"; } +sub git_get_paging_nav { + my ($project, $action, $hash, $head, $page, $nrevs) = @_; + my $paging_nav; + + + if ($hash ne $head || $page) { + $paging_nav .= $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$action")}, "HEAD"); + } else { + $paging_nav .= "HEAD"; + } + + if ($page > 0) { + $paging_nav .= " ⋅ " . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$action;h=$hash;pg=" . ($page-1)), + -accesskey => "p", -title => "Alt-p"}, "prev"); + } else { + $paging_nav .= " ⋅ prev"; + } + + if ($nrevs >= (100 * ($page+1)-1)) { + $paging_nav .= " ⋅ " . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$action;h=$hash;pg=" . ($page+1)), + -accesskey => "n", -title => "Alt-n"}, "next"); + } else { + $paging_nav .= " ⋅ next"; + } + + return $paging_nav; +} + sub git_get_type { my $hash = shift; @@ -1873,24 +1903,7 @@ sub git_log { my @revlist = map { chomp; $_ } <$fd>; close $fd; - my $paging_nav = ''; - if ($hash ne $head || $page) { - $paging_nav .= $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log")}, "HEAD"); - } else { - $paging_nav .= "HEAD"; - } - if ($page > 0) { - $paging_nav .= " ⋅ " . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log;h=$hash;pg=" . ($page-1)), -accesskey => "p", -title => "Alt-p"}, "prev"); - } else { - $paging_nav .= " ⋅ prev"; - } - if ($#revlist >= (100 * ($page+1)-1)) { - $paging_nav .= " ⋅ " . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log;h=$hash;pg=" . ($page+1)), -accesskey => "n", -title => "Alt-n"}, "next"); - } else { - $paging_nav .= " ⋅ next"; - } + my $paging_nav = git_get_paging_nav($project, 'log', $hash, $head, $page, $#revlist); git_header_html(); git_page_nav('log','', $hash,undef,undef, $paging_nav); @@ -2553,24 +2566,7 @@ sub git_shortlog { my @revlist = map { chomp; $_ } <$fd>; close $fd; - my $paging_nav = ''; - if ($hash ne $head || $page) { - $paging_nav .= $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog")}, "HEAD"); - } else { - $paging_nav .= "HEAD"; - } - if ($page > 0) { - $paging_nav .= " ⋅ " . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog;h=$hash;pg=" . ($page-1)), -accesskey => "p", -title => "Alt-p"}, "prev"); - } else { - $paging_nav .= " ⋅ prev"; - } - if ($#revlist >= (100 * ($page+1)-1)) { - $paging_nav .= " ⋅ " . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog;h=$hash;pg=" . ($page+1)), -accesskey => "n", -title => "Alt-n"}, "next"); - } else { - $paging_nav .= " ⋅ next"; - } + my $paging_nav = git_get_paging_nav($project, 'shortlog', $hash, $head, $page, $#revlist); git_header_html(); git_page_nav('shortlog','', $hash,$hash,$hash, $paging_nav); From 6855f42ecd8cfb77ec7494ac9eea9b1ef2d634a0 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sun, 30 Jul 2006 20:31:00 +0200 Subject: [PATCH 020/160] gitweb: Remove $project from git_get_paging_nav arguments Remove $project from arguments passed to git_get_paging_nav subroutine: it did not depend only on arguments, using $my_uri global variable (and now $project global variable). Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index 8e5e4c83c5..3134b9ce56 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -421,7 +421,7 @@ sub git_page_nav { } sub git_get_paging_nav { - my ($project, $action, $hash, $head, $page, $nrevs) = @_; + my ($action, $hash, $head, $page, $nrevs) = @_; my $paging_nav; @@ -1903,7 +1903,7 @@ sub git_log { my @revlist = map { chomp; $_ } <$fd>; close $fd; - my $paging_nav = git_get_paging_nav($project, 'log', $hash, $head, $page, $#revlist); + my $paging_nav = git_get_paging_nav('log', $hash, $head, $page, $#revlist); git_header_html(); git_page_nav('log','', $hash,undef,undef, $paging_nav); @@ -2566,7 +2566,7 @@ sub git_shortlog { my @revlist = map { chomp; $_ } <$fd>; close $fd; - my $paging_nav = git_get_paging_nav($project, 'shortlog', $hash, $head, $page, $#revlist); + my $paging_nav = git_get_paging_nav('shortlog', $hash, $head, $page, $#revlist); git_header_html(); git_page_nav('shortlog','', $hash,$hash,$hash, $paging_nav); From 27fb8c40c6b634c67f5b5fb3b354a207cc10b343 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sun, 30 Jul 2006 20:32:01 +0200 Subject: [PATCH 021/160] gitweb: Headers refactoring - use git_header_div for header divs Add git_header_div subroutine which prints "header" divs, now with class "header" (class "title" is taken, and has set CSS style, changing appereance and maing layout wrong), and use it thorough gitweb.cgi. Change header linking to project summary from empty (  as a contents of link) to having $project as contents/name of link. Sometimes a little reordering. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 100 +++++++++++++++++++--------------------------- 1 file changed, 40 insertions(+), 60 deletions(-) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index 3134b9ce56..1012869048 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -420,6 +420,19 @@ sub git_page_nav { "\n"; } +sub git_header_div { + my ($action, $title, $hash, $hash_base) = @_; + my $rest = ''; + + $rest .= ";h=$hash" if $hash; + $rest .= ";hb=$hash_base" if $hash_base; + + print "
\n" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$action$rest"), + -class => "title"}, $title ? $title : $action) . "\n" . + "
\n"; +} + sub git_get_paging_nav { my ($action, $hash, $head, $page, $nrevs) = @_; my $paging_nav; @@ -1123,9 +1136,7 @@ sub git_summary { or die_error(undef, "Open git-rev-list failed."); my @revlist = map { chomp; $_ } <$fd>; close $fd; - print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog"), -class => "title"}, "shortlog") . - "
\n"; + git_header_div('shortlog'); my $i = 16; print "\n"; my $alternate = 0; @@ -1169,9 +1180,7 @@ sub git_summary { my $taglist = git_read_refs("refs/tags"); if (defined @$taglist) { - print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tags"), -class => "title"}, "tags") . - "
\n"; + git_header_div('tags'); my $i = 16; print "
\n"; my $alternate = 0; @@ -1221,9 +1230,7 @@ sub git_summary { my $headlist = git_read_refs("refs/heads"); if (defined @$headlist) { - print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=heads"), -class => "title"}, "heads") . - "
\n"; + git_header_div('heads'); my $i = 16; print "
\n"; my $alternate = 0; @@ -1276,9 +1283,7 @@ sub git_tag { git_header_html(); git_page_nav('','', $head,undef,$head); my %tag = git_read_tag($hash); - print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash"), -class => "title"}, esc_html($tag{'name'})) . "\n" . - "
\n"; + git_header_div('commit', esc_html($tag{'name'}), $hash); print "
\n" . "
\n" . "\n" . @@ -1326,9 +1331,7 @@ sub git_blame2 { $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$hash;hb=$hash_base;f=$file_name")}, "blob") . " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;f=$file_name")}, "head"); git_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); - print "
" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base"), -class => "title"}, esc_html($co{'title'})) . - "
\n"; + git_header_div('commit', esc_html($co{'title'}), $hash_base); git_print_page_path($file_name, $ftype); my @rev_color = (qw(light dark)); my $num_colors = scalar(@rev_color); @@ -1382,9 +1385,7 @@ sub git_blame { $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$hash;hb=$hash_base;f=$file_name")}, "blob") . " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;f=$file_name")}, "head"); git_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); - print "
" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base"), -class => "title"}, esc_html($co{'title'})) . - "
\n"; + git_header_div('commit', esc_html($co{'title'}), $hash_base); git_print_page_path($file_name); print "
\n"; print <\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary"), -class => "title"}, " ") . - "
\n"; + git_header_div('summary', $project); print "
\n"; + + my $taglist = git_read_refs("refs/tags"); my $alternate = 0; if (defined @$taglist) { foreach my $entry (@$taglist) { @@ -1511,11 +1511,10 @@ sub git_heads { my $head = git_read_head($project); git_header_html(); git_page_nav('','', $head,undef,$head); - my $taglist = git_read_refs("refs/heads"); - print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary"), -class => "title"}, " ") . - "
\n"; + hit_header_div('summary', $project); print "
\n"; + + my $taglist = git_read_refs("refs/heads"); my $alternate = 0; if (defined @$taglist) { foreach my $entry (@$taglist) { @@ -1684,9 +1683,7 @@ sub git_blob { $formats_nav .= $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;h=$hash")}, "plain"); } git_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); - print "
" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base"), -class => "title"}, esc_html($co{'title'})) . - "
\n"; + git_header_div('commit', esc_html($co{'title'}), $hash_base); } else { print "
\n" . "

\n" . @@ -1740,9 +1737,7 @@ sub git_tree { if (defined $hash_base && (my %co = git_read_commit($hash_base))) { $base_key = ";hb=$hash_base"; git_page_nav('tree','', $hash_base); - print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base"), -class => "title"}, esc_html($co{'title'}) . $ref) . "\n" . - "
\n"; + git_header_div('commit', esc_html($co{'title'}) . $ref, $hash_base); } else { print "
\n"; print "

\n"; @@ -1909,10 +1904,9 @@ sub git_log { git_page_nav('log','', $hash,undef,undef, $paging_nav); if (!@revlist) { - print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary"), -class => "title"}, " ") . - "
\n"; my %co = git_read_commit($hash); + + git_header_div('summary', $project); print "
Last change $co{'age_string'}.

\n"; } for (my $i = ($page * 100); $i <= $#revlist; $i++) { @@ -1924,10 +1918,10 @@ sub git_log { my %co = git_read_commit($commit); next if !%co; my %ad = date_str($co{'author_epoch'}); - print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit"), -class => "title"}, - "$co{'age_string'}" . esc_html($co{'title'}) . $ref) . "\n"; - print "
\n"; + git_header_div('commit', + "$co{'age_string'}" . + esc_html($co{'title'}) . $ref, + $commit); print "
\n" . "
\n" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit")}, "commit") . @@ -1999,13 +1993,9 @@ sub git_commit { $formats_nav); if (defined $co{'parent'}) { - print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$hash"), -class => "title"}, esc_html($co{'title'}) . $ref) . "\n" . - "
\n"; + git_header_div('commitdiff', esc_html($co{'title'}) . $ref, $hash); } else { - print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$co{'tree'};hb=$hash"), -class => "title"}, esc_html($co{'title'})) . "\n" . - "
\n"; + git_header_div('tree', esc_html($co{'title'}), $co{'tree'}, $hash); } print "
\n" . "
\n"; @@ -2171,9 +2161,7 @@ sub git_blobdiff { my $formats_nav = $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blobdiff_plain;h=$hash;hp=$hash_parent")}, "plain"); git_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); - print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base"), -class => "title"}, esc_html($co{'title'})) . "\n" . - "
\n"; + git_header_div('commit', esc_html($co{'title'}), $hash_base); } else { print "
\n" . "

\n" . @@ -2225,9 +2213,7 @@ sub git_commitdiff { my $formats_nav = $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff_plain;h=$hash;hp=$hash_parent")}, "plain"); git_page_nav('commitdiff','', $hash,$co{'tree'},$hash, $formats_nav); - print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash"), -class => "title"}, esc_html($co{'title'}) . $ref) . "\n" . - "
\n"; + git_header_div('commit', esc_html($co{'title'}) . $ref, $hash); print "
\n"; my $comment = $co{'comment'}; my $empty = 0; @@ -2357,9 +2343,7 @@ sub git_history { my $refs = read_info_ref(); git_header_html(); git_page_nav('','', $hash_base,$co{'tree'},$hash_base); - print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base"), -class => "title"}, esc_html($co{'title'})) . "\n" . - "
\n"; + git_header_div('commit', esc_html($co{'title'}), $hash_base); if (!defined $hash && defined $file_name) { $hash = git_get_hash_by_path($hash_base, $file_name); } @@ -2440,10 +2424,8 @@ sub git_search { } git_header_html(); git_page_nav('','', $hash,$co{'tree'},$hash); + git_header_div('commit', esc_html($co{'title'}), $hash); - print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash"), -class => "title"}, esc_html($co{'title'})) . "\n" . - "
\n"; print "
\n"; my $alternate = 0; if ($commit_search) { @@ -2570,10 +2552,8 @@ sub git_shortlog { git_header_html(); git_page_nav('shortlog','', $hash,$hash,$hash, $paging_nav); + git_header_div('summary', $project); - print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary"), -class => "title"}, " ") . - "
\n"; print "
\n"; my $alternate = 0; for (my $i = ($page * 100); $i <= $#revlist; $i++) { From 7ca84b506281495b9ec43801d08b7209b08be92d Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sun, 30 Jul 2006 22:36:04 +0200 Subject: [PATCH 022/160] gitweb: Remove characters entities entirely when shortening string Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 1 + 1 file changed, 1 insertion(+) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index 1012869048..1ff29bc291 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -776,6 +776,7 @@ sub chop_str { my $tail = $2; if (length($tail) > 4) { $tail = " ..."; + $body =~ s/&[^;]$//; # remove chopped character entities } return "$body$tail"; } From 594e212bc849039a204deef1d16c2eddcc451532 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Mon, 31 Jul 2006 02:21:52 +0200 Subject: [PATCH 023/160] gitweb: Ref refactoring - use git_get_referencing for marking tagged/head commits Use git_get_referencing to get HTML code for markers showing which refs (tags and heads) point to current commit. It would be much easier to change format of markers in one or two places than thorough the gitweb.cgi file. Added comment about read_info_ref subroutine: for $type == "" (empty argument) it saves only last path part of ref name e.g. from 'refs/heads/jn/gitweb' it would leave only 'gitweb'. Some reordering. Added $ref in one place. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 53 ++++++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index 1ff29bc291..2f1731870d 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -1024,6 +1024,8 @@ sub read_info_ref { open my $fd, "$projectroot/$project/info/refs" or return; while (my $line = <$fd>) { chomp $line; + # attention: for $type == "" it saves only last path part of ref name + # e.g. from 'refs/heads/jn/gitweb' it would leave only 'gitweb' if ($line =~ m/^([0-9a-fA-F]{40})\t.*$type\/([^\^]+)/) { if (defined $refs{$1}) { $refs{$1} .= " / $2"; @@ -1036,6 +1038,16 @@ sub read_info_ref { return \%refs; } +sub git_get_referencing { + my ($refs, $id) = @_; + + if (defined $refs->{$id}) { + return ' ' . esc_html($refs->{$id}) . ''; + } else { + return ""; + } +} + sub git_read_refs { my $ref_dir = shift; my @reflist; @@ -1151,10 +1163,7 @@ sub git_summary { } $alternate ^= 1; if ($i-- > 0) { - my $ref = ""; - if (defined $refs->{$commit}) { - $ref = " " . esc_html($refs->{$commit}) . ""; - } + my $ref = git_get_referencing($refs, $commit); print "\n" . "\n" . "
$co{'age_string'}" . esc_html(chop_str($co{'author_name'}, 10)) . ""; @@ -1728,10 +1737,7 @@ sub git_tree { $/ = "\n"; my $refs = read_info_ref(); - my $ref = ""; - if (defined $refs->{$hash_base}) { - $ref = " " . esc_html($refs->{$hash_base}) . ""; - } + my $ref = git_get_referencing($refs, $hash_base); git_header_html(); my $base_key = ""; my $base = ""; @@ -1912,10 +1918,7 @@ sub git_log { } for (my $i = ($page * 100); $i <= $#revlist; $i++) { my $commit = $revlist[$i]; - my $ref = ""; - if (defined $refs->{$commit}) { - $ref = " " . esc_html($refs->{$commit}) . ""; - } + my $ref = git_get_referencing($refs, $commit); my %co = git_read_commit($commit); next if !%co; my %ad = date_str($co{'author_epoch'}); @@ -1979,16 +1982,13 @@ sub git_commit { $expires = "+1d"; } my $refs = read_info_ref(); - my $ref = ""; - if (defined $refs->{$co{'id'}}) { - $ref = " " . esc_html($refs->{$co{'id'}}) . ""; - } - git_header_html(undef, $expires); + my $ref = git_get_referencing($refs, $co{'id'}); my $formats_nav = ''; if (defined $file_name && defined $co{'parent'}) { my $parent = $co{'parent'}; $formats_nav .= $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;hb=$parent;f=$file_name")}, "blame"); } + git_header_html(undef, $expires); git_page_nav('commit', defined $co{'parent'} ? '' : 'commitdiff', $hash, $co{'tree'}, $hash, $formats_nav); @@ -1996,7 +1996,7 @@ sub git_commit { if (defined $co{'parent'}) { git_header_div('commitdiff', esc_html($co{'title'}) . $ref, $hash); } else { - git_header_div('tree', esc_html($co{'title'}), $co{'tree'}, $hash); + git_header_div('tree', esc_html($co{'title'}) . $ref, $co{'tree'}, $hash); } print "
\n" . "\n"; @@ -2206,13 +2206,10 @@ sub git_commitdiff { $expires = "+1d"; } my $refs = read_info_ref(); - my $ref = ""; - if (defined $refs->{$co{'id'}}) { - $ref = " " . esc_html($refs->{$co{'id'}}) . ""; - } - git_header_html(undef, $expires); + my $ref = git_get_referencing($refs, $co{'id'}); my $formats_nav = $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff_plain;h=$hash;hp=$hash_parent")}, "plain"); + git_header_html(undef, $expires); git_page_nav('commitdiff','', $hash,$co{'tree'},$hash, $formats_nav); git_header_div('commit', esc_html($co{'title'}) . $ref, $hash); print "
\n"; @@ -2364,10 +2361,7 @@ sub git_history { if (!%co) { next; } - my $ref = ""; - if (defined $refs->{$commit}) { - $ref = " " . esc_html($refs->{$commit}) . ""; - } + my $ref = git_get_referencing($refs, $commit); if ($alternate) { print "
\n"; } else { @@ -2559,10 +2553,7 @@ sub git_shortlog { my $alternate = 0; for (my $i = ($page * 100); $i <= $#revlist; $i++) { my $commit = $revlist[$i]; - my $ref = ""; - if (defined $refs->{$commit}) { - $ref = " " . esc_html($refs->{$commit}) . ""; - } + my $ref = git_get_referencing($refs, $commit); my %co = git_read_commit($commit); my %ad = date_str($co{'author_epoch'}); if ($alternate) { From 9f5dcb8168d5ea9f0169e11f017ecd9710d85797 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Mon, 31 Jul 2006 11:22:13 +0200 Subject: [PATCH 024/160] gitweb: Refactor generation of shortlog, tags and heads body Add git_shortlog_body, git_tags_body and git_heads_body to generate table with shortlog, tags and heads respectively in git_summary and git_shortlog, git_tags, git_heads respectively. Better support for lightweight tags in git_read_refs; currently only lightweight tag pointing to tag object is not resolved fully. Shortlog, tags and heads body tables have proper class now (we could use id instead of class). Add support for showing full comment on mouseover to tags list when comment is shortened, similar to how full title of commit was/is shown on mouseover when title was shortened. Changed layout of tags table to better show lightweight tags. Add showing which branch (head) is current branch (current head), using "current_head" class (we could use id instead). Corrected "" and hit_header_div instead of git_header_div. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 383 +++++++++++++++++++++------------------------- gitweb/gitweb.css | 10 +- 2 files changed, 184 insertions(+), 209 deletions(-) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index 2f1731870d..c741e739d0 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -1102,6 +1102,10 @@ sub git_read_refs { $ref_item{'refid'} = $ref_id; $ref_item{'epoch'} = $co{'committer_epoch'}; $ref_item{'age'} = $co{'age_string'}; + } else { + $ref_item{'reftype'} = $type; + $ref_item{'name'} = $ref_file; + $ref_item{'refid'} = $ref_id; } push @reflist, \%ref_item; @@ -1111,6 +1115,156 @@ sub git_read_refs { return \@reflist; } +sub git_shortlog_body { + # uses global variable $project + my ($revlist, $from, $to, $refs, $extra) = @_; + $from = 0 unless defined $from; + $to = $#{$revlist} if (!defined $to || $#{$revlist} < $to); + + print "
\n"; + my $alternate = 0; + for (my $i = $from; $i <= $to; $i++) { + my $commit = $revlist->[$i]; + #my $ref = defined $refs ? git_get_referencing($refs, $commit) : ''; + my $ref = git_get_referencing($refs, $commit); + my %co = git_read_commit($commit); + my %ad = date_str($co{'author_epoch'}); + if ($alternate) { + print "\n"; + } else { + print "\n"; + } + $alternate ^= 1; + # git_summary() used print "\n" . + print "\n" . + "\n" . + "\n" . + "\n" . + "\n"; + } + if (defined $extra) { + print "\n" . + "\n" . + "\n"; + } + print "
$co{'age_string'}$co{'age_string_date'}" . esc_html(chop_str($co{'author_name'}, 10)) . ""; + if (length($co{'title_short'}) < length($co{'title'})) { + print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit"), + -class => "list", -title => "$co{'title'}"}, + "" . esc_html($co{'title_short'}) . "$ref"); + } else { + print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit"), + -class => "list"}, + "" . esc_html($co{'title'}) . "$ref"); + } + print "" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit")}, "commit") . " | " . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$commit")}, "commitdiff") . + "
$extra
\n"; +} + +sub git_tags_body { + # uses global variable $project + my ($taglist, $from, $to, $extra) = @_; + $from = 0 unless defined $from; + $to = $#{$taglist} if (!defined $to || $#{$taglist} < $to); + + print "\n"; + my $alternate = 0; + for (my $i = $from; $i <= $to; $i++) { + my $entry = $taglist->[$i]; + my %tag = %$entry; + my $comment_lines = $tag{'comment'}; + my $comment = shift @$comment_lines; + my $comment_short; + if (defined $comment) { + $comment_short = chop_str($comment, 30, 5); + } + if ($alternate) { + print "\n"; + } else { + print "\n"; + } + $alternate ^= 1; + print "\n" . + "\n" . + "\n" . + "\n" . + "\n" . + ""; + } + if (defined $extra) { + print "\n" . + "\n" . + "\n"; + } + print "
$tag{'age'}" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$tag{'reftype'};h=$tag{'refid'}"), + -class => "list"}, "" . esc_html($tag{'name'}) . "") . + ""; + if (defined $comment) { + if (length($comment_short) < length($comment)) { + print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}"), + -class => "list", -title => $comment}, $comment_short); + } else { + print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}"), + -class => "list"}, $comment); + } + } + print ""; + if ($tag{'type'} eq "tag") { + print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}")}, "tag"); + } else { + print " "; + } + print "" . " | " . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$tag{'reftype'};h=$tag{'refid'}")}, $tag{'reftype'}); + if ($tag{'reftype'} eq "commit") { + print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog;h=$tag{'name'}")}, "shortlog") . + " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log;h=$tag{'refid'}")}, "log"); + } elsif ($tag{'reftype'} eq "blob") { + print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;h=$tag{'refid'}")}, "raw"); + } + print "
$extra
\n"; +} + +sub git_heads_body { + # uses global variable $project + my ($taglist, $head, $from, $to, $extra) = @_; + $from = 0 unless defined $from; + $to = $#{$taglist} if (!defined $to || $#{$taglist} < $to); + + print "\n"; + my $alternate = 0; + for (my $i = $from; $i <= $to; $i++) { + my $entry = $taglist->[$i]; + my %tag = %$entry; + my $curr = $tag{'id'} eq $head; + if ($alternate) { + print "\n"; + } else { + print "\n"; + } + $alternate ^= 1; + print "\n" . + ($tag{'id'} eq $head ? "\n" . + "\n" . + ""; + } + if (defined $extra) { + print "\n" . + "\n" . + "\n"; + } + print "
$tag{'age'}" : "") . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog;h=$tag{'name'}"), + -class => "list"}, "" . esc_html($tag{'name'}) . "") . + "" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog;h=$tag{'name'}")}, "shortlog") . " | " . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log;h=$tag{'name'}")}, "log") . + "
$extra
\n"; +} + sub git_summary { my $descr = git_read_description($project) || "none"; my $head = git_read_head($project); @@ -1139,138 +1293,36 @@ sub git_summary { my $refs = read_info_ref(); git_header_html(); git_page_nav('summary','', $head); + print "
 
\n"; print "\n" . "\n" . "\n" . "\n" . "
description" . esc_html($descr) . "
owner$owner
last change$cd{'rfc2822'}
\n"; + open my $fd, "-|", $GIT, "rev-list", "--max-count=17", git_read_head($project) or die_error(undef, "Open git-rev-list failed."); my @revlist = map { chomp; $_ } <$fd>; close $fd; git_header_div('shortlog'); - my $i = 16; - print "\n"; - my $alternate = 0; - foreach my $commit (@revlist) { - my %co = git_read_commit($commit); - my %ad = date_str($co{'author_epoch'}); - if ($alternate) { - print "\n"; - } else { - print "\n"; - } - $alternate ^= 1; - if ($i-- > 0) { - my $ref = git_get_referencing($refs, $commit); - print "\n" . - "\n" . - "\n" . - "\n" . - ""; - } else { - print "\n" . - ""; - last; - } - } - print ""; + git_shortlog_body(\@revlist, 0, 15, $refs, + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog")}, "...")); my $taglist = git_read_refs("refs/tags"); if (defined @$taglist) { git_header_div('tags'); - my $i = 16; - print "
$co{'age_string'}" . esc_html(chop_str($co{'author_name'}, 10)) . ""; - if (length($co{'title_short'}) < length($co{'title'})) { - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit"), -class => "list", -title => "$co{'title'}"}, - "" . esc_html($co{'title_short'}) . "$ref"); - } else { - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit"), -class => "list"}, - "" . esc_html($co{'title'}) . "$ref"); - } - print "" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit")}, "commit") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$commit")}, "commitdiff") . - "
" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog")}, "...") . "
\n"; - my $alternate = 0; - foreach my $entry (@$taglist) { - my %tag = %$entry; - my $comment_lines = $tag{'comment'}; - my $comment = shift @$comment_lines; - if (defined($comment)) { - $comment = chop_str($comment, 30, 5); - } - if ($alternate) { - print "\n"; - } else { - print "\n"; - } - $alternate ^= 1; - if ($i-- > 0) { - print "\n" . - "\n" . - "\n" . - "\n" . - ""; - } else { - print "\n" . - ""; - last; - } - } - print ""; + git_tags_body($taglist, 0, 15, + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tags")}, "...")); } my $headlist = git_read_refs("refs/heads"); if (defined @$headlist) { git_header_div('heads'); - my $i = 16; - print "
$tag{'age'}" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$tag{'reftype'};h=$tag{'refid'}"), -class => "list"}, - "" . esc_html($tag{'name'}) . "") . - ""; - if (defined($comment)) { - print $cgi->a({-class => "list", -href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}")}, esc_html($comment)); - } - print ""; - if ($tag{'type'} eq "tag") { - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}")}, "tag") . " | "; - } - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$tag{'reftype'};h=$tag{'refid'}")}, $tag{'reftype'}); - if ($tag{'reftype'} eq "commit") { - print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog;h=$tag{'name'}")}, "shortlog") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log;h=$tag{'refid'}")}, "log"); - } - print "
" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tags")}, "...") . "
\n"; - my $alternate = 0; - foreach my $entry (@$headlist) { - my %tag = %$entry; - if ($alternate) { - print "\n"; - } else { - print "\n"; - } - $alternate ^= 1; - if ($i-- > 0) { - print "\n" . - "\n" . - "\n" . - ""; - } else { - print "\n" . - ""; - last; - } - } - print ""; + git_heads_body($taglist, $head, 0, 15, + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=heads")}, "...")); } + git_footer_html(); } @@ -1472,48 +1524,11 @@ sub git_tags { git_header_html(); git_page_nav('','', $head,undef,$head); git_header_div('summary', $project); - print "
$tag{'age'}" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog;h=$tag{'name'}"), -class => "list"}, - "" . esc_html($tag{'name'}) . "") . - "" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog;h=$tag{'name'}")}, "shortlog") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log;h=$tag{'name'}")}, "log") . - "
" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=heads")}, "...") . "
\n"; my $taglist = git_read_refs("refs/tags"); - my $alternate = 0; if (defined @$taglist) { - foreach my $entry (@$taglist) { - my %tag = %$entry; - my $comment_lines = $tag{'comment'}; - my $comment = shift @$comment_lines; - if (defined($comment)) { - $comment = chop_str($comment, 30, 5); - } - if ($alternate) { - print "\n"; - } else { - print "\n"; - } - $alternate ^= 1; - print "\n" . - "\n" . - "\n" . - "\n" . - ""; - } + git_tags_body($taglist); } - print ""; git_footer_html(); } @@ -1521,32 +1536,13 @@ sub git_heads { my $head = git_read_head($project); git_header_html(); git_page_nav('','', $head,undef,$head); - hit_header_div('summary', $project); - print "
$tag{'age'}" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$tag{'reftype'};h=$tag{'refid'}"), -class => "list"}, - "" . esc_html($tag{'name'}) . "") . - ""; - if (defined($comment)) { - print $cgi->a({-class => "list", -href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}")}, $comment); - } - print ""; - if ($tag{'type'} eq "tag") { - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}")}, "tag") . " | "; - } - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$tag{'reftype'};h=$tag{'refid'}")}, $tag{'reftype'}); - if ($tag{'reftype'} eq "commit") { - print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog;h=$tag{'name'}")}, "shortlog") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log;h=$tag{'refid'}")}, "log"); - } - print "
\n"; + git_header_div('summary', $project); my $taglist = git_read_refs("refs/heads"); my $alternate = 0; if (defined @$taglist) { - foreach my $entry (@$taglist) { - my %tag = %$entry; - if ($alternate) { - print "\n"; - } else { - print "\n"; - } - $alternate ^= 1; - print "\n" . - "\n" . - "\n" . - ""; - } + git_heads_body($taglist, $head); } - print ""; git_footer_html(); } @@ -2544,48 +2540,19 @@ sub git_shortlog { close $fd; my $paging_nav = git_get_paging_nav('shortlog', $hash, $head, $page, $#revlist); + my $next_link = ''; + if ($#revlist >= (100 * ($page+1)-1)) { + $next_link = + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog;h=$hash;pg=" . ($page+1)), + -title => "Alt-n"}, "next"); + } + git_header_html(); git_page_nav('shortlog','', $hash,$hash,$hash, $paging_nav); git_header_div('summary', $project); - print "
$tag{'age'}" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog;h=$tag{'name'}"), -class => "list"}, "" . esc_html($tag{'name'}) . "") . - "" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog;h=$tag{'name'}")}, "shortlog") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log;h=$tag{'name'}")}, "log") . - "
\n"; - my $alternate = 0; - for (my $i = ($page * 100); $i <= $#revlist; $i++) { - my $commit = $revlist[$i]; - my $ref = git_get_referencing($refs, $commit); - my %co = git_read_commit($commit); - my %ad = date_str($co{'author_epoch'}); - if ($alternate) { - print "\n"; - } else { - print "\n"; - } - $alternate ^= 1; - print "\n" . - "\n" . - "\n" . - "\n" . - ""; - } - if ($#revlist >= (100 * ($page+1)-1)) { - print "\n" . - "\n" . - "\n"; - } - print ""; + git_shortlog_body(\@revlist, ($page * 100), $#revlist, $refs, $next_link); + git_footer_html(); } diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css index fffdb13d09..460e728718 100644 --- a/gitweb/gitweb.css +++ b/gitweb/gitweb.css @@ -181,12 +181,16 @@ td { vertical-align: top; } -td.link { +td.link, td.selflink { padding: 2px 5px; font-family: sans-serif; font-size: 10px; } +td.selflink { + padding-right: 0px; +} + td.sha1 { font-family: monospace; } @@ -196,6 +200,10 @@ td.error { background-color: yellow; } +td.current_head { + text-decoration: underline; +} + table.diff_tree span.file_status.new { color: #008000; } From 822c185907f27c02ce7791985ea9241e37041d5f Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Mon, 31 Jul 2006 18:33:37 +0200 Subject: [PATCH 025/160] gitweb: do not quote path for list version of open "-|" Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index c741e739d0..73d14ffb10 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -2347,7 +2347,7 @@ sub git_history { git_print_page_path($file_name, $ftype); open my $fd, "-|", - $GIT, "rev-list", "--full-history", $hash_base, "--", "\'$file_name\'"; + $GIT, "rev-list", "--full-history", $hash_base, "--", $file_name; print "
$co{'age_string_date'}" . esc_html(chop_str($co{'author_name'}, 10)) . ""; - if (length($co{'title_short'}) < length($co{'title'})) { - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit"), -class => "list", -title => "$co{'title'}"}, - "" . esc_html($co{'title_short'}) . "$ref"); - } else { - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit"), -class => "list"}, - "" . esc_html($co{'title_short'}) . "$ref"); - } - print "" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit")}, "commit") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$commit")}, "commitdiff") . - "
" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog;h=$hash;pg=" . ($page+1)), -title => "Alt-n"}, "next") . - "
\n"; my $alternate = 0; while (my $line = <$fd>) { From 0349b4650969c9c59c58d99c95be3677f5bb2d15 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Mon, 31 Jul 2006 20:58:00 +0200 Subject: [PATCH 026/160] gitweb: Remove characters entities entirely when shortening string -- correction Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index 73d14ffb10..0953b8cd56 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -776,7 +776,7 @@ sub chop_str { my $tail = $2; if (length($tail) > 4) { $tail = " ..."; - $body =~ s/&[^;]$//; # remove chopped character entities + $body =~ s/&[^;]*$//; # remove chopped character entities } return "$body$tail"; } From 717b831178a6c0e86ed5e7cd61002bd9ec0c2a95 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Mon, 31 Jul 2006 21:22:15 +0200 Subject: [PATCH 027/160] gitweb: Reordering code and dividing it into categories Reorder gitweb code around, divide it into sections (categories) and add some comments. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 1774 +++++++++++++++++++++++---------------------- 1 file changed, 919 insertions(+), 855 deletions(-) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index 0953b8cd56..16c368155b 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -160,21 +160,7 @@ if (defined $searchtext) { $searchtext = quotemeta $searchtext; } -sub validate_input { - my $input = shift; - - if ($input =~ m/^[0-9a-fA-F]{40}$/) { - return $input; - } - if ($input =~ m/(^|\/)(|\.|\.\.)($|\/)/) { - return undef; - } - if ($input =~ m/[^a-zA-Z0-9_\x80-\xff\ \t\.\/\-\+\#\~\%]/) { - return undef; - } - return $input; -} - +# dispatch if (!defined $action || $action eq "summary") { git_summary(); exit; @@ -235,6 +221,24 @@ if (!defined $action || $action eq "summary") { exit; } +## ====================================================================== +## validation, quoting/unquoting and escaping + +sub validate_input { + my $input = shift; + + if ($input =~ m/^[0-9a-fA-F]{40}$/) { + return $input; + } + if ($input =~ m/(^|\/)(|\.|\.\.)($|\/)/) { + return undef; + } + if ($input =~ m/[^a-zA-Z0-9_\x80-\xff\ \t\.\/\-\+\#\~\%]/) { + return undef; + } + return $input; +} + # quote unsafe chars, but keep the slash, even when it's not # correct, but quoted slashes look too horrible in bookmarks sub esc_param { @@ -264,6 +268,29 @@ sub unquote { return $str; } +## ---------------------------------------------------------------------- +## HTML aware string manipulation + +sub chop_str { + my $str = shift; + my $len = shift; + my $add_len = shift || 10; + + # allow only $len chars, but don't cut a word if it would fit in $add_len + # if it doesn't fit, cut it if it's still longer than the dots we would add + $str =~ m/^(.{0,$len}[^ \/\-_:\.@]{0,$add_len})(.*)/; + my $body = $1; + my $tail = $2; + if (length($tail) > 4) { + $tail = " ..."; + $body =~ s/&[^;]*$//; # remove chopped character entities + } + return "$body$tail"; +} + +## ---------------------------------------------------------------------- +## functions returning short strings + # CSS class for given age value (in seconds) sub age_class { my $age = shift; @@ -277,6 +304,576 @@ sub age_class { } } +# convert age in seconds to "nn units ago" string +sub age_string { + my $age = shift; + my $age_str; + + if ($age > 60*60*24*365*2) { + $age_str = (int $age/60/60/24/365); + $age_str .= " years ago"; + } elsif ($age > 60*60*24*(365/12)*2) { + $age_str = int $age/60/60/24/(365/12); + $age_str .= " months ago"; + } elsif ($age > 60*60*24*7*2) { + $age_str = int $age/60/60/24/7; + $age_str .= " weeks ago"; + } elsif ($age > 60*60*24*2) { + $age_str = int $age/60/60/24; + $age_str .= " days ago"; + } elsif ($age > 60*60*2) { + $age_str = int $age/60/60; + $age_str .= " hours ago"; + } elsif ($age > 60*2) { + $age_str = int $age/60; + $age_str .= " min ago"; + } elsif ($age > 2) { + $age_str = int $age; + $age_str .= " sec ago"; + } else { + $age_str .= " right now"; + } + return $age_str; +} + +# convert file mode in octal to symbolic file mode string +sub mode_str { + my $mode = oct shift; + + if (S_ISDIR($mode & S_IFMT)) { + return 'drwxr-xr-x'; + } elsif (S_ISLNK($mode)) { + return 'lrwxrwxrwx'; + } elsif (S_ISREG($mode)) { + # git cares only about the executable bit + if ($mode & S_IXUSR) { + return '-rwxr-xr-x'; + } else { + return '-rw-r--r--'; + }; + } else { + return '----------'; + } +} + +# convert file mode in octal to file type string +sub file_type { + my $mode = oct shift; + + if (S_ISDIR($mode & S_IFMT)) { + return "directory"; + } elsif (S_ISLNK($mode)) { + return "symlink"; + } elsif (S_ISREG($mode)) { + return "file"; + } else { + return "unknown"; + } +} + +## ---------------------------------------------------------------------- +## functions returning short HTML fragments, or transforming HTML fragments +## which don't beling to other sections + +# format line of commit message or tag comment +sub format_log_line_html { + my $line = shift; + + $line = esc_html($line); + $line =~ s/ / /g; + if ($line =~ m/([0-9a-fA-F]{40})/) { + my $hash_text = $1; + if (git_get_type($hash_text) eq "commit") { + my $link = $cgi->a({-class => "text", -href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_text")}, $hash_text); + $line =~ s/$hash_text/$link/; + } + } + return $line; +} + +# format marker of refs pointing to given object +sub git_get_referencing { + my ($refs, $id) = @_; + + if (defined $refs->{$id}) { + return ' ' . esc_html($refs->{$id}) . ''; + } else { + return ""; + } +} + +## ---------------------------------------------------------------------- +## git utility subroutines, invoking git commands + +# get HEAD ref of given project as hash +sub git_read_head { + my $project = shift; + my $oENV = $ENV{'GIT_DIR'}; + my $retval = undef; + $ENV{'GIT_DIR'} = "$projectroot/$project"; + if (open my $fd, "-|", $GIT, "rev-parse", "--verify", "HEAD") { + my $head = <$fd>; + close $fd; + if (defined $head && $head =~ /^([0-9a-fA-F]{40})$/) { + $retval = $1; + } + } + if (defined $oENV) { + $ENV{'GIT_DIR'} = $oENV; + } + return $retval; +} + +# get type of given object +sub git_get_type { + my $hash = shift; + + open my $fd, "-|", $GIT, "cat-file", '-t', $hash or return; + my $type = <$fd>; + close $fd or return; + chomp $type; + return $type; +} + +sub git_get_project_config { + my $key = shift; + + return unless ($key); + $key =~ s/^gitweb\.//; + return if ($key =~ m/\W/); + + my $val = qx($GIT repo-config --get gitweb.$key); + return ($val); +} + +sub git_get_project_config_bool { + my $val = git_get_project_config (@_); + if ($val and $val =~ m/true|yes|on/) { + return (1); + } + return; # implicit false +} + +# get hash of given path at given ref +sub git_get_hash_by_path { + my $base = shift; + my $path = shift || return undef; + + my $tree = $base; + + open my $fd, "-|", $GIT, "ls-tree", $base, "--", $path + or die_error(undef, "Open git-ls-tree failed."); + my $line = <$fd>; + close $fd or return undef; + + #'100644 blob 0fa3f3a66fb6a137f6ec2c19351ed4d807070ffa panic.c' + $line =~ m/^([0-9]+) (.+) ([0-9a-fA-F]{40})\t(.+)$/; + return $3; +} + +## ...................................................................... +## git utility functions, directly accessing git repository + +# assumes that PATH is not symref +sub git_read_hash { + my $path = shift; + + open my $fd, "$projectroot/$path" or return undef; + my $head = <$fd>; + close $fd; + chomp $head; + if ($head =~ m/^[0-9a-fA-F]{40}$/) { + return $head; + } +} + +sub git_read_description { + my $path = shift; + + open my $fd, "$projectroot/$path/description" or return undef; + my $descr = <$fd>; + close $fd; + chomp $descr; + return $descr; +} + +sub git_read_projects { + my @list; + + if (-d $projects_list) { + # search in directory + my $dir = $projects_list; + opendir my ($dh), $dir or return undef; + while (my $dir = readdir($dh)) { + if (-e "$projectroot/$dir/HEAD") { + my $pr = { + path => $dir, + }; + push @list, $pr + } + } + closedir($dh); + } elsif (-f $projects_list) { + # read from file(url-encoded): + # 'git%2Fgit.git Linus+Torvalds' + # 'libs%2Fklibc%2Fklibc.git H.+Peter+Anvin' + # 'linux%2Fhotplug%2Fudev.git Greg+Kroah-Hartman' + open my ($fd), $projects_list or return undef; + while (my $line = <$fd>) { + chomp $line; + my ($path, $owner) = split ' ', $line; + $path = unescape($path); + $owner = unescape($owner); + if (!defined $path) { + next; + } + if (-e "$projectroot/$path/HEAD") { + my $pr = { + path => $path, + owner => decode("utf8", $owner, Encode::FB_DEFAULT), + }; + push @list, $pr + } + } + close $fd; + } + @list = sort {$a->{'path'} cmp $b->{'path'}} @list; + return @list; +} + +sub read_info_ref { + my $type = shift || ""; + my %refs; + # 5dc01c595e6c6ec9ccda4f6f69c131c0dd945f8c refs/tags/v2.6.11 + # c39ae07f393806ccf406ef966e9a15afc43cc36a refs/tags/v2.6.11^{} + open my $fd, "$projectroot/$project/info/refs" or return; + while (my $line = <$fd>) { + chomp $line; + # attention: for $type == "" it saves only last path part of ref name + # e.g. from 'refs/heads/jn/gitweb' it would leave only 'gitweb' + if ($line =~ m/^([0-9a-fA-F]{40})\t.*$type\/([^\^]+)/) { + if (defined $refs{$1}) { + $refs{$1} .= " / $2"; + } else { + $refs{$1} = $2; + } + } + } + close $fd or return; + return \%refs; +} + +## ---------------------------------------------------------------------- +## parse to hash functions + +sub date_str { + my $epoch = shift; + my $tz = shift || "-0000"; + + my %date; + my @months = ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"); + my @days = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"); + my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday) = gmtime($epoch); + $date{'hour'} = $hour; + $date{'minute'} = $min; + $date{'mday'} = $mday; + $date{'day'} = $days[$wday]; + $date{'month'} = $months[$mon]; + $date{'rfc2822'} = sprintf "%s, %d %s %4d %02d:%02d:%02d +0000", $days[$wday], $mday, $months[$mon], 1900+$year, $hour ,$min, $sec; + $date{'mday-time'} = sprintf "%d %s %02d:%02d", $mday, $months[$mon], $hour ,$min; + + $tz =~ m/^([+\-][0-9][0-9])([0-9][0-9])$/; + my $local = $epoch + ((int $1 + ($2/60)) * 3600); + ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday) = gmtime($local); + $date{'hour_local'} = $hour; + $date{'minute_local'} = $min; + $date{'tz_local'} = $tz; + return %date; +} + +sub git_read_tag { + my $tag_id = shift; + my %tag; + my @comment; + + open my $fd, "-|", $GIT, "cat-file", "tag", $tag_id or return; + $tag{'id'} = $tag_id; + while (my $line = <$fd>) { + chomp $line; + if ($line =~ m/^object ([0-9a-fA-F]{40})$/) { + $tag{'object'} = $1; + } elsif ($line =~ m/^type (.+)$/) { + $tag{'type'} = $1; + } elsif ($line =~ m/^tag (.+)$/) { + $tag{'name'} = $1; + } elsif ($line =~ m/^tagger (.*) ([0-9]+) (.*)$/) { + $tag{'author'} = $1; + $tag{'epoch'} = $2; + $tag{'tz'} = $3; + } elsif ($line =~ m/--BEGIN/) { + push @comment, $line; + last; + } elsif ($line eq "") { + last; + } + } + push @comment, <$fd>; + $tag{'comment'} = \@comment; + close $fd or return; + if (!defined $tag{'name'}) { + return + }; + return %tag +} + +sub git_read_commit { + my $commit_id = shift; + my $commit_text = shift; + + my @commit_lines; + my %co; + + if (defined $commit_text) { + @commit_lines = @$commit_text; + } else { + $/ = "\0"; + open my $fd, "-|", $GIT, "rev-list", "--header", "--parents", "--max-count=1", $commit_id or return; + @commit_lines = split '\n', <$fd>; + close $fd or return; + $/ = "\n"; + pop @commit_lines; + } + my $header = shift @commit_lines; + if (!($header =~ m/^[0-9a-fA-F]{40}/)) { + return; + } + ($co{'id'}, my @parents) = split ' ', $header; + $co{'parents'} = \@parents; + $co{'parent'} = $parents[0]; + while (my $line = shift @commit_lines) { + last if $line eq "\n"; + if ($line =~ m/^tree ([0-9a-fA-F]{40})$/) { + $co{'tree'} = $1; + } elsif ($line =~ m/^author (.*) ([0-9]+) (.*)$/) { + $co{'author'} = $1; + $co{'author_epoch'} = $2; + $co{'author_tz'} = $3; + if ($co{'author'} =~ m/^([^<]+) 50) { + $title =~ s/^Automatic //; + $title =~ s/^merge (of|with) /Merge ... /i; + if (length($title) > 50) { + $title =~ s/(http|rsync):\/\///; + } + if (length($title) > 50) { + $title =~ s/(master|www|rsync)\.//; + } + if (length($title) > 50) { + $title =~ s/kernel.org:?//; + } + if (length($title) > 50) { + $title =~ s/\/pub\/scm//; + } + } + $co{'title_short'} = chop_str($title, 50, 5); + last; + } + } + # remove added spaces + foreach my $line (@commit_lines) { + $line =~ s/^ //; + } + $co{'comment'} = \@commit_lines; + + my $age = time - $co{'committer_epoch'}; + $co{'age'} = $age; + $co{'age_string'} = age_string($age); + my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday) = gmtime($co{'committer_epoch'}); + if ($age > 60*60*24*7*2) { + $co{'age_string_date'} = sprintf "%4i-%02u-%02i", 1900 + $year, $mon+1, $mday; + $co{'age_string_age'} = $co{'age_string'}; + } else { + $co{'age_string_date'} = $co{'age_string'}; + $co{'age_string_age'} = sprintf "%4i-%02u-%02i", 1900 + $year, $mon+1, $mday; + } + return %co; +} + +## ...................................................................... +## parse to array of hashes functions + +sub git_read_refs { + my $ref_dir = shift; + my @reflist; + + my @refs; + opendir my $dh, "$projectroot/$project/$ref_dir"; + while (my $dir = readdir($dh)) { + if ($dir =~ m/^\./) { + next; + } + if (-d "$projectroot/$project/$ref_dir/$dir") { + opendir my $dh2, "$projectroot/$project/$ref_dir/$dir"; + my @subdirs = grep !m/^\./, readdir $dh2; + closedir($dh2); + foreach my $subdir (@subdirs) { + push @refs, "$dir/$subdir" + } + next; + } + push @refs, $dir; + } + closedir($dh); + foreach my $ref_file (@refs) { + my $ref_id = git_read_hash("$project/$ref_dir/$ref_file"); + my $type = git_get_type($ref_id) || next; + my %ref_item; + my %co; + $ref_item{'type'} = $type; + $ref_item{'id'} = $ref_id; + $ref_item{'epoch'} = 0; + $ref_item{'age'} = "unknown"; + if ($type eq "tag") { + my %tag = git_read_tag($ref_id); + $ref_item{'comment'} = $tag{'comment'}; + if ($tag{'type'} eq "commit") { + %co = git_read_commit($tag{'object'}); + $ref_item{'epoch'} = $co{'committer_epoch'}; + $ref_item{'age'} = $co{'age_string'}; + } elsif (defined($tag{'epoch'})) { + my $age = time - $tag{'epoch'}; + $ref_item{'epoch'} = $tag{'epoch'}; + $ref_item{'age'} = age_string($age); + } + $ref_item{'reftype'} = $tag{'type'}; + $ref_item{'name'} = $tag{'name'}; + $ref_item{'refid'} = $tag{'object'}; + } elsif ($type eq "commit"){ + %co = git_read_commit($ref_id); + $ref_item{'reftype'} = "commit"; + $ref_item{'name'} = $ref_file; + $ref_item{'title'} = $co{'title'}; + $ref_item{'refid'} = $ref_id; + $ref_item{'epoch'} = $co{'committer_epoch'}; + $ref_item{'age'} = $co{'age_string'}; + } else { + $ref_item{'reftype'} = $type; + $ref_item{'name'} = $ref_file; + $ref_item{'refid'} = $ref_id; + } + + push @reflist, \%ref_item; + } + # sort tags by age + @reflist = sort {$b->{'epoch'} <=> $a->{'epoch'}} @reflist; + return \@reflist; +} + +## ---------------------------------------------------------------------- +## filesystem-related functions + +sub get_file_owner { + my $path = shift; + + my ($dev, $ino, $mode, $nlink, $st_uid, $st_gid, $rdev, $size) = stat($path); + my ($name, $passwd, $uid, $gid, $quota, $comment, $gcos, $dir, $shell) = getpwuid($st_uid); + if (!defined $gcos) { + return undef; + } + my $owner = $gcos; + $owner =~ s/[,;].*$//; + return decode("utf8", $owner, Encode::FB_DEFAULT); +} + +## ...................................................................... +## mimetype related functions + +sub mimetype_guess_file { + my $filename = shift; + my $mimemap = shift; + -r $mimemap or return undef; + + my %mimemap; + open(MIME, $mimemap) or return undef; + while () { + my ($mime, $exts) = split(/\t+/); + my @exts = split(/\s+/, $exts); + foreach my $ext (@exts) { + $mimemap{$ext} = $mime; + } + } + close(MIME); + + $filename =~ /\.(.*?)$/; + return $mimemap{$1}; +} + +sub mimetype_guess { + my $filename = shift; + my $mime; + $filename =~ /\./ or return undef; + + if ($mimetypes_file) { + my $file = $mimetypes_file; + #$file =~ m#^/# or $file = "$projectroot/$path/$file"; + $mime = mimetype_guess_file($filename, $file); + } + $mime ||= mimetype_guess_file($filename, '/etc/mime.types'); + return $mime; +} + +sub git_blob_plain_mimetype { + my $fd = shift; + my $filename = shift; + + if ($filename) { + my $mime = mimetype_guess($filename); + $mime and return $mime; + } + + # just in case + return $default_blob_plain_mimetype unless $fd; + + if (-T $fd) { + return 'text/plain' . + ($default_text_plain_charset ? '; charset='.$default_text_plain_charset : ''); + } elsif (! $filename) { + return 'application/octet-stream'; + } elsif ($filename =~ m/\.png$/i) { + return 'image/png'; + } elsif ($filename =~ m/\.gif$/i) { + return 'image/gif'; + } elsif ($filename =~ m/\.jpe?g$/i) { + return 'image/jpeg'; + } else { + return 'application/octet-stream'; + } +} + +## ====================================================================== +## functions printing HTML: header, footer, error page + sub git_header_html { my $status = shift || "200 OK"; my $expires = shift; @@ -386,6 +983,9 @@ sub die_error { exit; } +## ---------------------------------------------------------------------- +## functions printing or outputting HTML: navigation + sub git_page_nav { my ($current, $suppress, $head, $treehead, $treebase, $extra) = @_; $extra = '' if !defined $extra; # pager or formats @@ -420,19 +1020,6 @@ sub git_page_nav { "\n"; } -sub git_header_div { - my ($action, $title, $hash, $hash_base) = @_; - my $rest = ''; - - $rest .= ";h=$hash" if $hash; - $rest .= ";hb=$hash_base" if $hash_base; - - print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$action$rest"), - -class => "title"}, $title ? $title : $action) . "\n" . - "
\n"; -} - sub git_get_paging_nav { my ($action, $hash, $head, $page, $nrevs) = @_; my $paging_nav; @@ -463,657 +1050,38 @@ sub git_get_paging_nav { return $paging_nav; } -sub git_get_type { - my $hash = shift; +## ...................................................................... +## functions printing or outputting HTML: div - open my $fd, "-|", $GIT, "cat-file", '-t', $hash or return; - my $type = <$fd>; - close $fd or return; - chomp $type; - return $type; +sub git_header_div { + my ($action, $title, $hash, $hash_base) = @_; + my $rest = ''; + + $rest .= ";h=$hash" if $hash; + $rest .= ";hb=$hash_base" if $hash_base; + + print "
\n" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$action$rest"), + -class => "title"}, $title ? $title : $action) . "\n" . + "
\n"; } -sub git_read_head { - my $project = shift; - my $oENV = $ENV{'GIT_DIR'}; - my $retval = undef; - $ENV{'GIT_DIR'} = "$projectroot/$project"; - if (open my $fd, "-|", $GIT, "rev-parse", "--verify", "HEAD") { - my $head = <$fd>; - close $fd; - if (defined $head && $head =~ /^([0-9a-fA-F]{40})$/) { - $retval = $1; - } - } - if (defined $oENV) { - $ENV{'GIT_DIR'} = $oENV; - } - return $retval; -} +sub git_print_page_path { + my $name = shift; + my $type = shift; -sub git_read_hash { - my $path = shift; - - open my $fd, "$projectroot/$path" or return undef; - my $head = <$fd>; - close $fd; - chomp $head; - if ($head =~ m/^[0-9a-fA-F]{40}$/) { - return $head; - } -} - -sub git_read_description { - my $path = shift; - - open my $fd, "$projectroot/$path/description" or return undef; - my $descr = <$fd>; - close $fd; - chomp $descr; - return $descr; -} - -sub git_read_tag { - my $tag_id = shift; - my %tag; - my @comment; - - open my $fd, "-|", $GIT, "cat-file", "tag", $tag_id or return; - $tag{'id'} = $tag_id; - while (my $line = <$fd>) { - chomp $line; - if ($line =~ m/^object ([0-9a-fA-F]{40})$/) { - $tag{'object'} = $1; - } elsif ($line =~ m/^type (.+)$/) { - $tag{'type'} = $1; - } elsif ($line =~ m/^tag (.+)$/) { - $tag{'name'} = $1; - } elsif ($line =~ m/^tagger (.*) ([0-9]+) (.*)$/) { - $tag{'author'} = $1; - $tag{'epoch'} = $2; - $tag{'tz'} = $3; - } elsif ($line =~ m/--BEGIN/) { - push @comment, $line; - last; - } elsif ($line eq "") { - last; - } - } - push @comment, <$fd>; - $tag{'comment'} = \@comment; - close $fd or return; - if (!defined $tag{'name'}) { - return - }; - return %tag -} - -sub age_string { - my $age = shift; - my $age_str; - - if ($age > 60*60*24*365*2) { - $age_str = (int $age/60/60/24/365); - $age_str .= " years ago"; - } elsif ($age > 60*60*24*(365/12)*2) { - $age_str = int $age/60/60/24/(365/12); - $age_str .= " months ago"; - } elsif ($age > 60*60*24*7*2) { - $age_str = int $age/60/60/24/7; - $age_str .= " weeks ago"; - } elsif ($age > 60*60*24*2) { - $age_str = int $age/60/60/24; - $age_str .= " days ago"; - } elsif ($age > 60*60*2) { - $age_str = int $age/60/60; - $age_str .= " hours ago"; - } elsif ($age > 60*2) { - $age_str = int $age/60; - $age_str .= " min ago"; - } elsif ($age > 2) { - $age_str = int $age; - $age_str .= " sec ago"; + if (!defined $name) { + print "
/
\n"; + } elsif ($type =~ "blob") { + print "
" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;f=$file_name")}, esc_html($name)) . "
\n"; } else { - $age_str .= " right now"; - } - return $age_str; -} - -sub git_read_commit { - my $commit_id = shift; - my $commit_text = shift; - - my @commit_lines; - my %co; - - if (defined $commit_text) { - @commit_lines = @$commit_text; - } else { - $/ = "\0"; - open my $fd, "-|", $GIT, "rev-list", "--header", "--parents", "--max-count=1", $commit_id or return; - @commit_lines = split '\n', <$fd>; - close $fd or return; - $/ = "\n"; - pop @commit_lines; - } - my $header = shift @commit_lines; - if (!($header =~ m/^[0-9a-fA-F]{40}/)) { - return; - } - ($co{'id'}, my @parents) = split ' ', $header; - $co{'parents'} = \@parents; - $co{'parent'} = $parents[0]; - while (my $line = shift @commit_lines) { - last if $line eq "\n"; - if ($line =~ m/^tree ([0-9a-fA-F]{40})$/) { - $co{'tree'} = $1; - } elsif ($line =~ m/^author (.*) ([0-9]+) (.*)$/) { - $co{'author'} = $1; - $co{'author_epoch'} = $2; - $co{'author_tz'} = $3; - if ($co{'author'} =~ m/^([^<]+) 50) { - $title =~ s/^Automatic //; - $title =~ s/^merge (of|with) /Merge ... /i; - if (length($title) > 50) { - $title =~ s/(http|rsync):\/\///; - } - if (length($title) > 50) { - $title =~ s/(master|www|rsync)\.//; - } - if (length($title) > 50) { - $title =~ s/kernel.org:?//; - } - if (length($title) > 50) { - $title =~ s/\/pub\/scm//; - } - } - $co{'title_short'} = chop_str($title, 50, 5); - last; - } - } - # remove added spaces - foreach my $line (@commit_lines) { - $line =~ s/^ //; - } - $co{'comment'} = \@commit_lines; - - my $age = time - $co{'committer_epoch'}; - $co{'age'} = $age; - $co{'age_string'} = age_string($age); - my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday) = gmtime($co{'committer_epoch'}); - if ($age > 60*60*24*7*2) { - $co{'age_string_date'} = sprintf "%4i-%02u-%02i", 1900 + $year, $mon+1, $mday; - $co{'age_string_age'} = $co{'age_string'}; - } else { - $co{'age_string_date'} = $co{'age_string'}; - $co{'age_string_age'} = sprintf "%4i-%02u-%02i", 1900 + $year, $mon+1, $mday; - } - return %co; -} - -sub git_diff_print { - my $from = shift; - my $from_name = shift; - my $to = shift; - my $to_name = shift; - my $format = shift || "html"; - - my $from_tmp = "/dev/null"; - my $to_tmp = "/dev/null"; - my $pid = $$; - - # create tmp from-file - if (defined $from) { - $from_tmp = "$git_temp/gitweb_" . $$ . "_from"; - open my $fd2, "> $from_tmp"; - open my $fd, "-|", $GIT, "cat-file", "blob", $from; - my @file = <$fd>; - print $fd2 @file; - close $fd2; - close $fd; - } - - # create tmp to-file - if (defined $to) { - $to_tmp = "$git_temp/gitweb_" . $$ . "_to"; - open my $fd2, "> $to_tmp"; - open my $fd, "-|", $GIT, "cat-file", "blob", $to; - my @file = <$fd>; - print $fd2 @file; - close $fd2; - close $fd; - } - - open my $fd, "-|", "/usr/bin/diff -u -p -L \'$from_name\' -L \'$to_name\' $from_tmp $to_tmp"; - if ($format eq "plain") { - undef $/; - print <$fd>; - $/ = "\n"; - } else { - while (my $line = <$fd>) { - chomp $line; - my $char = substr($line, 0, 1); - my $diff_class = ""; - if ($char eq '+') { - $diff_class = " add"; - } elsif ($char eq "-") { - $diff_class = " rem"; - } elsif ($char eq "@") { - $diff_class = " chunk_header"; - } elsif ($char eq "\\") { - # skip errors - next; - } - while ((my $pos = index($line, "\t")) != -1) { - if (my $count = (8 - (($pos-1) % 8))) { - my $spaces = ' ' x $count; - $line =~ s/\t/$spaces/; - } - } - print "
" . esc_html($line) . "
\n"; - } - } - close $fd; - - if (defined $from) { - unlink($from_tmp); - } - if (defined $to) { - unlink($to_tmp); + print "
" . esc_html($name) . "
\n"; } } -sub mode_str { - my $mode = oct shift; - - if (S_ISDIR($mode & S_IFMT)) { - return 'drwxr-xr-x'; - } elsif (S_ISLNK($mode)) { - return 'lrwxrwxrwx'; - } elsif (S_ISREG($mode)) { - # git cares only about the executable bit - if ($mode & S_IXUSR) { - return '-rwxr-xr-x'; - } else { - return '-rw-r--r--'; - }; - } else { - return '----------'; - } -} - -sub chop_str { - my $str = shift; - my $len = shift; - my $add_len = shift || 10; - - # allow only $len chars, but don't cut a word if it would fit in $add_len - # if it doesn't fit, cut it if it's still longer than the dots we would add - $str =~ m/^(.{0,$len}[^ \/\-_:\.@]{0,$add_len})(.*)/; - my $body = $1; - my $tail = $2; - if (length($tail) > 4) { - $tail = " ..."; - $body =~ s/&[^;]*$//; # remove chopped character entities - } - return "$body$tail"; -} - -sub file_type { - my $mode = oct shift; - - if (S_ISDIR($mode & S_IFMT)) { - return "directory"; - } elsif (S_ISLNK($mode)) { - return "symlink"; - } elsif (S_ISREG($mode)) { - return "file"; - } else { - return "unknown"; - } -} - -sub format_log_line_html { - my $line = shift; - - $line = esc_html($line); - $line =~ s/ / /g; - if ($line =~ m/([0-9a-fA-F]{40})/) { - my $hash_text = $1; - if (git_get_type($hash_text) eq "commit") { - my $link = $cgi->a({-class => "text", -href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_text")}, $hash_text); - $line =~ s/$hash_text/$link/; - } - } - return $line; -} - -sub date_str { - my $epoch = shift; - my $tz = shift || "-0000"; - - my %date; - my @months = ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"); - my @days = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"); - my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday) = gmtime($epoch); - $date{'hour'} = $hour; - $date{'minute'} = $min; - $date{'mday'} = $mday; - $date{'day'} = $days[$wday]; - $date{'month'} = $months[$mon]; - $date{'rfc2822'} = sprintf "%s, %d %s %4d %02d:%02d:%02d +0000", $days[$wday], $mday, $months[$mon], 1900+$year, $hour ,$min, $sec; - $date{'mday-time'} = sprintf "%d %s %02d:%02d", $mday, $months[$mon], $hour ,$min; - - $tz =~ m/^([+\-][0-9][0-9])([0-9][0-9])$/; - my $local = $epoch + ((int $1 + ($2/60)) * 3600); - ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday) = gmtime($local); - $date{'hour_local'} = $hour; - $date{'minute_local'} = $min; - $date{'tz_local'} = $tz; - return %date; -} - -# git-logo (cached in browser for one day) -sub git_logo { - binmode STDOUT, ':raw'; - print $cgi->header(-type => 'image/png', -expires => '+1d'); - # cat git-logo.png | hexdump -e '16/1 " %02x" "\n"' | sed 's/ /\\x/g' - print "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52" . - "\x00\x00\x00\x48\x00\x00\x00\x1b\x04\x03\x00\x00\x00\x2d\xd9\xd4" . - "\x2d\x00\x00\x00\x18\x50\x4c\x54\x45\xff\xff\xff\x60\x60\x5d\xb0" . - "\xaf\xaa\x00\x80\x00\xce\xcd\xc7\xc0\x00\x00\xe8\xe8\xe6\xf7\xf7" . - "\xf6\x95\x0c\xa7\x47\x00\x00\x00\x73\x49\x44\x41\x54\x28\xcf\x63" . - "\x48\x67\x20\x04\x4a\x5c\x18\x0a\x08\x2a\x62\x53\x61\x20\x02\x08" . - "\x0d\x69\x45\xac\xa1\xa1\x01\x30\x0c\x93\x60\x36\x26\x52\x91\xb1" . - "\x01\x11\xd6\xe1\x55\x64\x6c\x6c\xcc\x6c\x6c\x0c\xa2\x0c\x70\x2a" . - "\x62\x06\x2a\xc1\x62\x1d\xb3\x01\x02\x53\xa4\x08\xe8\x00\x03\x18" . - "\x26\x56\x11\xd4\xe1\x20\x97\x1b\xe0\xb4\x0e\x35\x24\x71\x29\x82" . - "\x99\x30\xb8\x93\x0a\x11\xb9\x45\x88\xc1\x8d\xa0\xa2\x44\x21\x06" . - "\x27\x41\x82\x40\x85\xc1\x45\x89\x20\x70\x01\x00\xa4\x3d\x21\xc5" . - "\x12\x1c\x9a\xfe\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82"; -} - -sub get_file_owner { - my $path = shift; - - my ($dev, $ino, $mode, $nlink, $st_uid, $st_gid, $rdev, $size) = stat($path); - my ($name, $passwd, $uid, $gid, $quota, $comment, $gcos, $dir, $shell) = getpwuid($st_uid); - if (!defined $gcos) { - return undef; - } - my $owner = $gcos; - $owner =~ s/[,;].*$//; - return decode("utf8", $owner, Encode::FB_DEFAULT); -} - -sub git_read_projects { - my @list; - - if (-d $projects_list) { - # search in directory - my $dir = $projects_list; - opendir my ($dh), $dir or return undef; - while (my $dir = readdir($dh)) { - if (-e "$projectroot/$dir/HEAD") { - my $pr = { - path => $dir, - }; - push @list, $pr - } - } - closedir($dh); - } elsif (-f $projects_list) { - # read from file(url-encoded): - # 'git%2Fgit.git Linus+Torvalds' - # 'libs%2Fklibc%2Fklibc.git H.+Peter+Anvin' - # 'linux%2Fhotplug%2Fudev.git Greg+Kroah-Hartman' - open my ($fd), $projects_list or return undef; - while (my $line = <$fd>) { - chomp $line; - my ($path, $owner) = split ' ', $line; - $path = unescape($path); - $owner = unescape($owner); - if (!defined $path) { - next; - } - if (-e "$projectroot/$path/HEAD") { - my $pr = { - path => $path, - owner => decode("utf8", $owner, Encode::FB_DEFAULT), - }; - push @list, $pr - } - } - close $fd; - } - @list = sort {$a->{'path'} cmp $b->{'path'}} @list; - return @list; -} - -sub git_get_project_config { - my $key = shift; - - return unless ($key); - $key =~ s/^gitweb\.//; - return if ($key =~ m/\W/); - - my $val = qx($GIT repo-config --get gitweb.$key); - return ($val); -} - -sub git_get_project_config_bool { - my $val = git_get_project_config (@_); - if ($val and $val =~ m/true|yes|on/) { - return (1); - } - return; # implicit false -} - -sub git_project_list { - my @list = git_read_projects(); - my @projects; - if (!@list) { - die_error(undef, "No project found."); - } - foreach my $pr (@list) { - my $head = git_read_head($pr->{'path'}); - if (!defined $head) { - next; - } - $ENV{'GIT_DIR'} = "$projectroot/$pr->{'path'}"; - my %co = git_read_commit($head); - if (!%co) { - next; - } - $pr->{'commit'} = \%co; - if (!defined $pr->{'descr'}) { - my $descr = git_read_description($pr->{'path'}) || ""; - $pr->{'descr'} = chop_str($descr, 25, 5); - } - if (!defined $pr->{'owner'}) { - $pr->{'owner'} = get_file_owner("$projectroot/$pr->{'path'}") || ""; - } - push @projects, $pr; - } - git_header_html(); - if (-f $home_text) { - print "
\n"; - open (my $fd, $home_text); - print <$fd>; - close $fd; - print "
\n"; - } - print "
\n" . - "\n"; - if (!defined($order) || (defined($order) && ($order eq "project"))) { - @projects = sort {$a->{'path'} cmp $b->{'path'}} @projects; - print "\n"; - } else { - print "\n"; - } - if (defined($order) && ($order eq "descr")) { - @projects = sort {$a->{'descr'} cmp $b->{'descr'}} @projects; - print "\n"; - } else { - print "\n"; - } - if (defined($order) && ($order eq "owner")) { - @projects = sort {$a->{'owner'} cmp $b->{'owner'}} @projects; - print "\n"; - } else { - print "\n"; - } - if (defined($order) && ($order eq "age")) { - @projects = sort {$a->{'commit'}{'age'} <=> $b->{'commit'}{'age'}} @projects; - print "\n"; - } else { - print "\n"; - } - print "\n" . - "\n"; - my $alternate = 0; - foreach my $pr (@projects) { - if ($alternate) { - print "\n"; - } else { - print "\n"; - } - $alternate ^= 1; - print "\n" . - "\n" . - "\n"; - print "\n" . - "\n" . - "\n"; - } - print "
Project" . $cgi->a({-class => "header", -href => "$my_uri?" . esc_param("o=project")}, "Project") . "Description" . $cgi->a({-class => "header", -href => "$my_uri?" . esc_param("o=descr")}, "Description") . "Owner" . $cgi->a({-class => "header", -href => "$my_uri?" . esc_param("o=owner")}, "Owner") . "Last Change" . $cgi->a({-class => "header", -href => "$my_uri?" . esc_param("o=age")}, "Last Change") . "
" . $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=summary"), -class => "list"}, esc_html($pr->{'path'})) . "" . esc_html($pr->{'descr'}) . "" . chop_str($pr->{'owner'}, 15) . "{'commit'}{'age'}) . "\">" . $pr->{'commit'}{'age_string'} . "" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=summary")}, "summary") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=shortlog")}, "shortlog") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=log")}, "log") . - "
\n"; - git_footer_html(); -} - -sub read_info_ref { - my $type = shift || ""; - my %refs; - # 5dc01c595e6c6ec9ccda4f6f69c131c0dd945f8c refs/tags/v2.6.11 - # c39ae07f393806ccf406ef966e9a15afc43cc36a refs/tags/v2.6.11^{} - open my $fd, "$projectroot/$project/info/refs" or return; - while (my $line = <$fd>) { - chomp $line; - # attention: for $type == "" it saves only last path part of ref name - # e.g. from 'refs/heads/jn/gitweb' it would leave only 'gitweb' - if ($line =~ m/^([0-9a-fA-F]{40})\t.*$type\/([^\^]+)/) { - if (defined $refs{$1}) { - $refs{$1} .= " / $2"; - } else { - $refs{$1} = $2; - } - } - } - close $fd or return; - return \%refs; -} - -sub git_get_referencing { - my ($refs, $id) = @_; - - if (defined $refs->{$id}) { - return ' ' . esc_html($refs->{$id}) . ''; - } else { - return ""; - } -} - -sub git_read_refs { - my $ref_dir = shift; - my @reflist; - - my @refs; - opendir my $dh, "$projectroot/$project/$ref_dir"; - while (my $dir = readdir($dh)) { - if ($dir =~ m/^\./) { - next; - } - if (-d "$projectroot/$project/$ref_dir/$dir") { - opendir my $dh2, "$projectroot/$project/$ref_dir/$dir"; - my @subdirs = grep !m/^\./, readdir $dh2; - closedir($dh2); - foreach my $subdir (@subdirs) { - push @refs, "$dir/$subdir" - } - next; - } - push @refs, $dir; - } - closedir($dh); - foreach my $ref_file (@refs) { - my $ref_id = git_read_hash("$project/$ref_dir/$ref_file"); - my $type = git_get_type($ref_id) || next; - my %ref_item; - my %co; - $ref_item{'type'} = $type; - $ref_item{'id'} = $ref_id; - $ref_item{'epoch'} = 0; - $ref_item{'age'} = "unknown"; - if ($type eq "tag") { - my %tag = git_read_tag($ref_id); - $ref_item{'comment'} = $tag{'comment'}; - if ($tag{'type'} eq "commit") { - %co = git_read_commit($tag{'object'}); - $ref_item{'epoch'} = $co{'committer_epoch'}; - $ref_item{'age'} = $co{'age_string'}; - } elsif (defined($tag{'epoch'})) { - my $age = time - $tag{'epoch'}; - $ref_item{'epoch'} = $tag{'epoch'}; - $ref_item{'age'} = age_string($age); - } - $ref_item{'reftype'} = $tag{'type'}; - $ref_item{'name'} = $tag{'name'}; - $ref_item{'refid'} = $tag{'object'}; - } elsif ($type eq "commit"){ - %co = git_read_commit($ref_id); - $ref_item{'reftype'} = "commit"; - $ref_item{'name'} = $ref_file; - $ref_item{'title'} = $co{'title'}; - $ref_item{'refid'} = $ref_id; - $ref_item{'epoch'} = $co{'committer_epoch'}; - $ref_item{'age'} = $co{'age_string'}; - } else { - $ref_item{'reftype'} = $type; - $ref_item{'name'} = $ref_file; - $ref_item{'refid'} = $ref_id; - } - - push @reflist, \%ref_item; - } - # sort tags by age - @reflist = sort {$b->{'epoch'} <=> $a->{'epoch'}} @reflist; - return \@reflist; -} +## ...................................................................... +## functions printing large fragments of HTML sub git_shortlog_body { # uses global variable $project @@ -1265,6 +1233,191 @@ sub git_heads_body { print "
\n"; } +## ---------------------------------------------------------------------- +## functions printing large fragments, format as one of arguments + +sub git_diff_print { + my $from = shift; + my $from_name = shift; + my $to = shift; + my $to_name = shift; + my $format = shift || "html"; + + my $from_tmp = "/dev/null"; + my $to_tmp = "/dev/null"; + my $pid = $$; + + # create tmp from-file + if (defined $from) { + $from_tmp = "$git_temp/gitweb_" . $$ . "_from"; + open my $fd2, "> $from_tmp"; + open my $fd, "-|", $GIT, "cat-file", "blob", $from; + my @file = <$fd>; + print $fd2 @file; + close $fd2; + close $fd; + } + + # create tmp to-file + if (defined $to) { + $to_tmp = "$git_temp/gitweb_" . $$ . "_to"; + open my $fd2, "> $to_tmp"; + open my $fd, "-|", $GIT, "cat-file", "blob", $to; + my @file = <$fd>; + print $fd2 @file; + close $fd2; + close $fd; + } + + open my $fd, "-|", "/usr/bin/diff -u -p -L \'$from_name\' -L \'$to_name\' $from_tmp $to_tmp"; + if ($format eq "plain") { + undef $/; + print <$fd>; + $/ = "\n"; + } else { + while (my $line = <$fd>) { + chomp $line; + my $char = substr($line, 0, 1); + my $diff_class = ""; + if ($char eq '+') { + $diff_class = " add"; + } elsif ($char eq "-") { + $diff_class = " rem"; + } elsif ($char eq "@") { + $diff_class = " chunk_header"; + } elsif ($char eq "\\") { + # skip errors + next; + } + while ((my $pos = index($line, "\t")) != -1) { + if (my $count = (8 - (($pos-1) % 8))) { + my $spaces = ' ' x $count; + $line =~ s/\t/$spaces/; + } + } + print "
" . esc_html($line) . "
\n"; + } + } + close $fd; + + if (defined $from) { + unlink($from_tmp); + } + if (defined $to) { + unlink($to_tmp); + } +} + + +## ====================================================================== +## ====================================================================== +## actions + +# git-logo (cached in browser for one day) +sub git_logo { + binmode STDOUT, ':raw'; + print $cgi->header(-type => 'image/png', -expires => '+1d'); + # cat git-logo.png | hexdump -e '16/1 " %02x" "\n"' | sed 's/ /\\x/g' + print "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52" . + "\x00\x00\x00\x48\x00\x00\x00\x1b\x04\x03\x00\x00\x00\x2d\xd9\xd4" . + "\x2d\x00\x00\x00\x18\x50\x4c\x54\x45\xff\xff\xff\x60\x60\x5d\xb0" . + "\xaf\xaa\x00\x80\x00\xce\xcd\xc7\xc0\x00\x00\xe8\xe8\xe6\xf7\xf7" . + "\xf6\x95\x0c\xa7\x47\x00\x00\x00\x73\x49\x44\x41\x54\x28\xcf\x63" . + "\x48\x67\x20\x04\x4a\x5c\x18\x0a\x08\x2a\x62\x53\x61\x20\x02\x08" . + "\x0d\x69\x45\xac\xa1\xa1\x01\x30\x0c\x93\x60\x36\x26\x52\x91\xb1" . + "\x01\x11\xd6\xe1\x55\x64\x6c\x6c\xcc\x6c\x6c\x0c\xa2\x0c\x70\x2a" . + "\x62\x06\x2a\xc1\x62\x1d\xb3\x01\x02\x53\xa4\x08\xe8\x00\x03\x18" . + "\x26\x56\x11\xd4\xe1\x20\x97\x1b\xe0\xb4\x0e\x35\x24\x71\x29\x82" . + "\x99\x30\xb8\x93\x0a\x11\xb9\x45\x88\xc1\x8d\xa0\xa2\x44\x21\x06" . + "\x27\x41\x82\x40\x85\xc1\x45\x89\x20\x70\x01\x00\xa4\x3d\x21\xc5" . + "\x12\x1c\x9a\xfe\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82"; +} + +sub git_project_list { + my @list = git_read_projects(); + my @projects; + if (!@list) { + die_error(undef, "No project found."); + } + foreach my $pr (@list) { + my $head = git_read_head($pr->{'path'}); + if (!defined $head) { + next; + } + $ENV{'GIT_DIR'} = "$projectroot/$pr->{'path'}"; + my %co = git_read_commit($head); + if (!%co) { + next; + } + $pr->{'commit'} = \%co; + if (!defined $pr->{'descr'}) { + my $descr = git_read_description($pr->{'path'}) || ""; + $pr->{'descr'} = chop_str($descr, 25, 5); + } + if (!defined $pr->{'owner'}) { + $pr->{'owner'} = get_file_owner("$projectroot/$pr->{'path'}") || ""; + } + push @projects, $pr; + } + git_header_html(); + if (-f $home_text) { + print "
\n"; + open (my $fd, $home_text); + print <$fd>; + close $fd; + print "
\n"; + } + print "\n" . + "\n"; + if (!defined($order) || (defined($order) && ($order eq "project"))) { + @projects = sort {$a->{'path'} cmp $b->{'path'}} @projects; + print "\n"; + } else { + print "\n"; + } + if (defined($order) && ($order eq "descr")) { + @projects = sort {$a->{'descr'} cmp $b->{'descr'}} @projects; + print "\n"; + } else { + print "\n"; + } + if (defined($order) && ($order eq "owner")) { + @projects = sort {$a->{'owner'} cmp $b->{'owner'}} @projects; + print "\n"; + } else { + print "\n"; + } + if (defined($order) && ($order eq "age")) { + @projects = sort {$a->{'commit'}{'age'} <=> $b->{'commit'}{'age'}} @projects; + print "\n"; + } else { + print "\n"; + } + print "\n" . + "\n"; + my $alternate = 0; + foreach my $pr (@projects) { + if ($alternate) { + print "\n"; + } else { + print "\n"; + } + $alternate ^= 1; + print "\n" . + "\n" . + "\n"; + print "\n" . + "\n" . + "\n"; + } + print "
Project" . $cgi->a({-class => "header", -href => "$my_uri?" . esc_param("o=project")}, "Project") . "Description" . $cgi->a({-class => "header", -href => "$my_uri?" . esc_param("o=descr")}, "Description") . "Owner" . $cgi->a({-class => "header", -href => "$my_uri?" . esc_param("o=owner")}, "Owner") . "Last Change" . $cgi->a({-class => "header", -href => "$my_uri?" . esc_param("o=age")}, "Last Change") . "
" . $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=summary"), -class => "list"}, esc_html($pr->{'path'})) . "" . esc_html($pr->{'descr'}) . "" . chop_str($pr->{'owner'}, 15) . "{'commit'}{'age'}) . "\">" . $pr->{'commit'}{'age_string'} . "" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=summary")}, "summary") . + " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=shortlog")}, "shortlog") . + " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=log")}, "log") . + "
\n"; + git_footer_html(); +} + sub git_summary { my $descr = git_read_description($project) || "none"; my $head = git_read_head($project); @@ -1326,20 +1479,6 @@ sub git_summary { git_footer_html(); } -sub git_print_page_path { - my $name = shift; - my $type = shift; - - if (!defined $name) { - print "
/
\n"; - } elsif ($type =~ "blob") { - print "
" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;f=$file_name")}, esc_html($name)) . "
\n"; - } else { - print "
" . esc_html($name) . "
\n"; - } -} - sub git_tag { my $head = git_read_head($project); git_header_html(); @@ -1546,84 +1685,6 @@ sub git_heads { git_footer_html(); } -sub git_get_hash_by_path { - my $base = shift; - my $path = shift || return undef; - - my $tree = $base; - - open my $fd, "-|", $GIT, "ls-tree", $base, "--", $path - or die_error(undef, "Open git-ls-tree failed."); - my $line = <$fd>; - close $fd or return undef; - - #'100644 blob 0fa3f3a66fb6a137f6ec2c19351ed4d807070ffa panic.c' - $line =~ m/^([0-9]+) (.+) ([0-9a-fA-F]{40})\t(.+)$/; - return $3; -} - -sub mimetype_guess_file { - my $filename = shift; - my $mimemap = shift; - -r $mimemap or return undef; - - my %mimemap; - open(MIME, $mimemap) or return undef; - while () { - my ($mime, $exts) = split(/\t+/); - my @exts = split(/\s+/, $exts); - foreach my $ext (@exts) { - $mimemap{$ext} = $mime; - } - } - close(MIME); - - $filename =~ /\.(.*?)$/; - return $mimemap{$1}; -} - -sub mimetype_guess { - my $filename = shift; - my $mime; - $filename =~ /\./ or return undef; - - if ($mimetypes_file) { - my $file = $mimetypes_file; - #$file =~ m#^/# or $file = "$projectroot/$path/$file"; - $mime = mimetype_guess_file($filename, $file); - } - $mime ||= mimetype_guess_file($filename, '/etc/mime.types'); - return $mime; -} - -sub git_blob_plain_mimetype { - my $fd = shift; - my $filename = shift; - - if ($filename) { - my $mime = mimetype_guess($filename); - $mime and return $mime; - } - - # just in case - return $default_blob_plain_mimetype unless $fd; - - if (-T $fd) { - return 'text/plain' . - ($default_text_plain_charset ? '; charset='.$default_text_plain_charset : ''); - } elsif (! $filename) { - return 'application/octet-stream'; - } elsif ($filename =~ m/\.png$/i) { - return 'image/png'; - } elsif ($filename =~ m/\.gif$/i) { - return 'image/gif'; - } elsif ($filename =~ m/\.jpe?g$/i) { - return 'image/jpeg'; - } else { - return 'application/octet-stream'; - } -} - sub git_blob_plain { if (!defined $hash) { if (defined $file_name) { @@ -1793,98 +1854,6 @@ sub git_tree { git_footer_html(); } -sub git_rss { - # http://www.notestips.com/80256B3A007F2692/1/NAMO5P9UPQ - open my $fd, "-|", $GIT, "rev-list", "--max-count=150", git_read_head($project) - or die_error(undef, "Open git-rev-list failed."); - my @revlist = map { chomp; $_ } <$fd>; - close $fd or die_error(undef, "Reading rev-list failed."); - print $cgi->header(-type => 'text/xml', -charset => 'utf-8'); - print "\n". - "\n"; - print "\n"; - print "$project\n". - "" . esc_html("$my_url?p=$project;a=summary") . "\n". - "$project log\n". - "en\n"; - - for (my $i = 0; $i <= $#revlist; $i++) { - my $commit = $revlist[$i]; - my %co = git_read_commit($commit); - # we read 150, we always show 30 and the ones more recent than 48 hours - if (($i >= 20) && ((time - $co{'committer_epoch'}) > 48*60*60)) { - last; - } - my %cd = date_str($co{'committer_epoch'}); - open $fd, "-|", $GIT, "diff-tree", '-r', $co{'parent'}, $co{'id'} or next; - my @difftree = map { chomp; $_ } <$fd>; - close $fd or next; - print "\n" . - "" . - sprintf("%d %s %02d:%02d", $cd{'mday'}, $cd{'month'}, $cd{'hour'}, $cd{'minute'}) . " - " . esc_html($co{'title'}) . - "\n" . - "" . esc_html($co{'author'}) . "\n" . - "$cd{'rfc2822'}\n" . - "" . esc_html("$my_url?p=$project;a=commit;h=$commit") . "\n" . - "" . esc_html("$my_url?p=$project;a=commit;h=$commit") . "\n" . - "" . esc_html($co{'title'}) . "\n" . - "" . - "\n"; - } - print "
\n"; - foreach my $line (@difftree) { - if (!($line =~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)([0-9]{0,3})\t(.*)$/)) { - next; - } - my $file = validate_input(unquote($7)); - $file = decode("utf8", $file, Encode::FB_DEFAULT); - print "$file
\n"; - } - print "]]>\n" . - "
\n" . - "
\n"; - } - print "
"; -} - -sub git_opml { - my @list = git_read_projects(); - - print $cgi->header(-type => 'text/xml', -charset => 'utf-8'); - print "\n". - "\n". - "". - " $site_name Git OPML Export\n". - "\n". - "\n". - "\n"; - - foreach my $pr (@list) { - my %proj = %$pr; - my $head = git_read_head($proj{'path'}); - if (!defined $head) { - next; - } - $ENV{'GIT_DIR'} = "$projectroot/$proj{'path'}"; - my %co = git_read_commit($head); - if (!%co) { - next; - } - - my $path = esc_html(chop_str($proj{'path'}, 25, 5)); - my $rss = "$my_url?p=$proj{'path'};a=rss"; - my $html = "$my_url?p=$proj{'path'};a=summary"; - print "\n"; - } - print "\n". - "\n". - "\n"; -} - sub git_log { my $head = git_read_head($project); if (!defined $hash) { @@ -2556,3 +2525,98 @@ sub git_shortlog { git_footer_html(); } + +## ...................................................................... +## feeds (RSS, OPML) + +sub git_rss { + # http://www.notestips.com/80256B3A007F2692/1/NAMO5P9UPQ + open my $fd, "-|", $GIT, "rev-list", "--max-count=150", git_read_head($project) + or die_error(undef, "Open git-rev-list failed."); + my @revlist = map { chomp; $_ } <$fd>; + close $fd or die_error(undef, "Reading rev-list failed."); + print $cgi->header(-type => 'text/xml', -charset => 'utf-8'); + print "\n". + "\n"; + print "\n"; + print "$project\n". + "" . esc_html("$my_url?p=$project;a=summary") . "\n". + "$project log\n". + "en\n"; + + for (my $i = 0; $i <= $#revlist; $i++) { + my $commit = $revlist[$i]; + my %co = git_read_commit($commit); + # we read 150, we always show 30 and the ones more recent than 48 hours + if (($i >= 20) && ((time - $co{'committer_epoch'}) > 48*60*60)) { + last; + } + my %cd = date_str($co{'committer_epoch'}); + open $fd, "-|", $GIT, "diff-tree", '-r', $co{'parent'}, $co{'id'} or next; + my @difftree = map { chomp; $_ } <$fd>; + close $fd or next; + print "\n" . + "" . + sprintf("%d %s %02d:%02d", $cd{'mday'}, $cd{'month'}, $cd{'hour'}, $cd{'minute'}) . " - " . esc_html($co{'title'}) . + "\n" . + "" . esc_html($co{'author'}) . "\n" . + "$cd{'rfc2822'}\n" . + "" . esc_html("$my_url?p=$project;a=commit;h=$commit") . "\n" . + "" . esc_html("$my_url?p=$project;a=commit;h=$commit") . "\n" . + "" . esc_html($co{'title'}) . "\n" . + "" . + "\n"; + } + print "
\n"; + foreach my $line (@difftree) { + if (!($line =~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)([0-9]{0,3})\t(.*)$/)) { + next; + } + my $file = validate_input(unquote($7)); + $file = decode("utf8", $file, Encode::FB_DEFAULT); + print "$file
\n"; + } + print "]]>\n" . + "
\n" . + "
\n"; + } + print "
"; +} + +sub git_opml { + my @list = git_read_projects(); + + print $cgi->header(-type => 'text/xml', -charset => 'utf-8'); + print "\n". + "\n". + "". + " $site_name Git OPML Export\n". + "\n". + "\n". + "\n"; + + foreach my $pr (@list) { + my %proj = %$pr; + my $head = git_read_head($proj{'path'}); + if (!defined $head) { + next; + } + $ENV{'GIT_DIR'} = "$projectroot/$proj{'path'}"; + my %co = git_read_commit($head); + if (!%co) { + next; + } + + my $path = esc_html(chop_str($proj{'path'}, 25, 5)); + my $rss = "$my_url?p=$proj{'path'};a=rss"; + my $html = "$my_url?p=$proj{'path'};a=summary"; + print "\n"; + } + print "\n". + "\n". + "\n"; +} From c27d205aaefb654c12a4ab9e0b4fae1882c0fc70 Mon Sep 17 00:00:00 2001 From: Matthias Lederhofer Date: Mon, 31 Jul 2006 15:27:00 +0200 Subject: [PATCH 028/160] pager: environment variable GIT_PAGER to override PAGER Signed-off-by: Matthias Lederhofer Signed-off-by: Junio C Hamano --- Documentation/git.txt | 3 +++ pager.c | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Documentation/git.txt b/Documentation/git.txt index 7310a2b8b8..d24388368e 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -627,6 +627,9 @@ git Diffs other ~~~~~ +'GIT_PAGER':: + This environment variable overrides `$PAGER`. + 'GIT_TRACE':: If this variable is set git will print `trace:` messages on stderr telling about alias expansion, built-in command diff --git a/pager.c b/pager.c index 280f57f796..dcb398da8e 100644 --- a/pager.c +++ b/pager.c @@ -15,10 +15,12 @@ void setup_pager(void) { pid_t pid; int fd[2]; - const char *pager = getenv("PAGER"); + const char *pager = getenv("GIT_PAGER"); if (!isatty(1)) return; + if (!pager) + pager = getenv("PAGER"); if (!pager) pager = "less"; else if (!*pager || !strcmp(pager, "cat")) From 8e85cdc4efd15fa70dfbbfebaf3ef9a758c2772c Mon Sep 17 00:00:00 2001 From: Matthias Lederhofer Date: Mon, 31 Jul 2006 23:46:25 +0200 Subject: [PATCH 029/160] gitweb: use a hash to lookup the sub for an action Signed-off-by: Matthias Lederhofer Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 81 +++++++++++++++-------------------------------- 1 file changed, 25 insertions(+), 56 deletions(-) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index 16c368155b..4e79390aff 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -161,65 +161,34 @@ if (defined $searchtext) { } # dispatch -if (!defined $action || $action eq "summary") { - git_summary(); - exit; -} elsif ($action eq "heads") { - git_heads(); - exit; -} elsif ($action eq "tags") { - git_tags(); - exit; -} elsif ($action eq "blob") { - git_blob(); - exit; -} elsif ($action eq "blob_plain") { - git_blob_plain(); - exit; -} elsif ($action eq "tree") { - git_tree(); - exit; -} elsif ($action eq "rss") { - git_rss(); - exit; -} elsif ($action eq "commit") { - git_commit(); - exit; -} elsif ($action eq "log") { - git_log(); - exit; -} elsif ($action eq "blobdiff") { - git_blobdiff(); - exit; -} elsif ($action eq "blobdiff_plain") { - git_blobdiff_plain(); - exit; -} elsif ($action eq "commitdiff") { - git_commitdiff(); - exit; -} elsif ($action eq "commitdiff_plain") { - git_commitdiff_plain(); - exit; -} elsif ($action eq "history") { - git_history(); - exit; -} elsif ($action eq "search") { - git_search(); - exit; -} elsif ($action eq "shortlog") { - git_shortlog(); - exit; -} elsif ($action eq "tag") { - git_tag(); - exit; -} elsif ($action eq "blame") { - git_blame2(); - exit; -} else { +my %actions = ( + "blame" => \&git_blame2, + "blobdiff" => \&git_blobdiff, + "blobdiff_plain" => \&git_blobdiff_plain, + "blob" => \&git_blob, + "blob_plain" => \&git_blob_plain, + "commitdiff" => \&git_commitdiff, + "commitdiff_plain" => \&git_commitdiff_plain, + "commit" => \&git_commit, + "heads" => \&git_heads, + "history" => \&git_history, + "log" => \&git_log, + "rss" => \&git_rss, + "search" => \&git_search, + "shortlog" => \&git_shortlog, + "summary" => \&git_summary, + "tag" => \&git_tag, + "tags" => \&git_tags, + "tree" => \&git_tree, +); + +$action = 'summary' if (!defined($action)); +if (!defined($actions{$action})) { undef $action; die_error(undef, "Unknown action."); - exit; } +$actions{$action}->(); +exit; ## ====================================================================== ## validation, quoting/unquoting and escaping From 7a13b999a5aa6de236c7b16139c765eb9e5cb3c4 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 31 Jul 2006 19:18:34 -0700 Subject: [PATCH 030/160] gitweb: There can be more than two levels of subdirectories Earlier code to read .git/refs/{tags,heads} hierarchy had a hardcoded up-to-two-level assumption. Lift it by using File::Find. Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index 4e79390aff..9569af09b5 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -14,6 +14,7 @@ use CGI::Util qw(unescape); use CGI::Carp qw(fatalsToBrowser); use Encode; use Fcntl ':mode'; +use File::Find qw(); binmode STDOUT, ':utf8'; our $cgi = new CGI; @@ -697,23 +698,14 @@ sub git_read_refs { my @reflist; my @refs; - opendir my $dh, "$projectroot/$project/$ref_dir"; - while (my $dir = readdir($dh)) { - if ($dir =~ m/^\./) { - next; + my $pfxlen = length("$projectroot/$project/$ref_dir"); + File::Find::find(sub { + return if (/^\./); + if (-f $_) { + push @refs, substr($File::Find::name, $pfxlen + 1); } - if (-d "$projectroot/$project/$ref_dir/$dir") { - opendir my $dh2, "$projectroot/$project/$ref_dir/$dir"; - my @subdirs = grep !m/^\./, readdir $dh2; - closedir($dh2); - foreach my $subdir (@subdirs) { - push @refs, "$dir/$subdir" - } - next; - } - push @refs, $dir; - } - closedir($dh); + }, "$projectroot/$project/$ref_dir"); + foreach my $ref_file (@refs) { my $ref_id = git_read_hash("$project/$ref_dir/$ref_file"); my $type = git_get_type($ref_id) || next; From b77aeb249a0ebdb8daa85ba58bbecde537f84025 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 31 Jul 2006 19:12:18 -0700 Subject: [PATCH 031/160] gitweb: an obvious cut and paste error. Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index 9569af09b5..902b96a914 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -1433,7 +1433,7 @@ sub git_summary { my $headlist = git_read_refs("refs/heads"); if (defined @$headlist) { git_header_div('heads'); - git_heads_body($taglist, $head, 0, 15, + git_heads_body($headlist, $head, 0, 15, $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=heads")}, "...")); } From 46b059d718777ab146b8089afd3d2fcdd6000154 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 31 Jul 2006 19:24:37 -0700 Subject: [PATCH 032/160] gitweb: fix use of uninitialized value. Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index 902b96a914..f65b5d5ce2 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -779,9 +779,11 @@ sub mimetype_guess_file { open(MIME, $mimemap) or return undef; while () { my ($mime, $exts) = split(/\t+/); - my @exts = split(/\s+/, $exts); - foreach my $ext (@exts) { - $mimemap{$ext} = $mime; + if (defined $exts) { + my @exts = split(/\s+/, $exts); + foreach my $ext (@exts) { + $mimemap{$ext} = $mime; + } } } close(MIME); From 498934a7e5410b815a9089c1b5205271d73e0f11 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 31 Jul 2006 19:36:50 -0700 Subject: [PATCH 033/160] gitweb: when showing history of a tree, show tree link not blob Otherwise clicking on that erroneous blob link would produce nonsense. Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index f65b5d5ce2..3cd4ce2a01 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -2303,7 +2303,7 @@ sub git_history { "
" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit")}, "commit") . " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$commit")}, "commitdiff") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;hb=$commit;f=$file_name")}, "blob"); + " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$ftype;hb=$commit;f=$file_name")}, $ftype); my $blob = git_get_hash_by_path($hash_base, $file_name); my $blob_parent = git_get_hash_by_path($commit, $file_name); if (defined $blob && defined $blob_parent && $blob ne $blob_parent) { From 5d1acf4da0d22d73c6b5d70887003d8fa7642ecc Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 31 Jul 2006 21:00:16 -0700 Subject: [PATCH 034/160] gitweb: avoid undefined value warning in print_page_path The function unconditionally tried to match $type but some callers did not pass it. Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index 3cd4ce2a01..9dc300d450 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -1035,7 +1035,7 @@ sub git_print_page_path { if (!defined $name) { print "
/
\n"; - } elsif ($type =~ "blob") { + } elsif (defined $type && $type eq 'blob') { print "
" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;f=$file_name")}, esc_html($name)) . "
\n"; } else { @@ -1550,7 +1550,7 @@ sub git_blame { " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;f=$file_name")}, "head"); git_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); git_header_div('commit', esc_html($co{'title'}), $hash_base); - git_print_page_path($file_name); + git_print_page_path($file_name, 'blob'); print "
\n"; print < @@ -1773,7 +1773,7 @@ sub git_tree { if (defined $file_name) { $base = esc_html("$file_name/"); } - git_print_page_path($file_name); + git_print_page_path($file_name, 'tree'); print "
\n"; print "\n"; my $alternate = 0; From 6326b60cfd9c953e64ddab9659587afeedccd95b Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Tue, 1 Aug 2006 02:59:12 +0200 Subject: [PATCH 035/160] gitweb: Refactoring git_project_list Slightly reworking git_project_list, including moving setting $order, as it is used only in this action. Mostly reindent. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 57 +++++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index 9dc300d450..9448b72798 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -81,14 +81,6 @@ if (defined $action) { } } -our $order = $cgi->param('o'); -if (defined $order) { - if ($order =~ m/[^0-9a-zA-Z_]/) { - undef $order; - die_error(undef, "Invalid order parameter."); - } -} - our $project = ($cgi->param('p') || $ENV{'PATH_INFO'}); if (defined $project) { $project =~ s|^/||; $project =~ s|/$||; @@ -1297,10 +1289,15 @@ sub git_logo { } sub git_project_list { + my $order = $cgi->param('o'); + if (defined $order && $order !~ m/project|descr|owner|age/) { + die_error(undef, "Invalid order parameter '$order'."); + } + my @list = git_read_projects(); my @projects; if (!@list) { - die_error(undef, "No project found."); + die_error(undef, "No projects found."); } foreach my $pr (@list) { my $head = git_read_head($pr->{'path'}); @@ -1322,6 +1319,7 @@ sub git_project_list { } push @projects, $pr; } + git_header_html(); if (-f $home_text) { print "
\n"; @@ -1332,29 +1330,42 @@ sub git_project_list { } print "
\n" . "\n"; - if (!defined($order) || (defined($order) && ($order eq "project"))) { + $order ||= "project"; + if ($order eq "project") { @projects = sort {$a->{'path'} cmp $b->{'path'}} @projects; print "\n"; } else { - print "\n"; + print "\n"; } - if (defined($order) && ($order eq "descr")) { + if ($order eq "descr") { @projects = sort {$a->{'descr'} cmp $b->{'descr'}} @projects; print "\n"; } else { - print "\n"; + print "\n"; } - if (defined($order) && ($order eq "owner")) { + if ($order eq "owner") { @projects = sort {$a->{'owner'} cmp $b->{'owner'}} @projects; print "\n"; } else { - print "\n"; + print "\n"; } - if (defined($order) && ($order eq "age")) { + if ($order eq "age") { @projects = sort {$a->{'commit'}{'age'} <=> $b->{'commit'}{'age'}} @projects; print "\n"; } else { - print "\n"; + print "\n"; } print "\n" . "\n"; @@ -1366,14 +1377,16 @@ sub git_project_list { print "\n"; } $alternate ^= 1; - print "\n" . + print "\n" . "\n" . "\n"; - print "\n" . + print "\n" . "\n" . "\n"; } From 5d043a3d856bd40d8b34b8836a561e438d23573b Mon Sep 17 00:00:00 2001 From: Martin Waitz Date: Tue, 1 Aug 2006 21:34:08 +0200 Subject: [PATCH 036/160] gitweb: fill in gitweb configuration by Makefile Generate gitweb/gitweb.cgi to reduce the need to patch gitweb.cgi by the end user. The GIT installation directory is already known by the Makefile, and can be inserted directly into gitweb. All other gitweb configuration parameters can now be specified by providing GITWEB_* variables while building GIT. These are described in gitweb/README. Signed-off-by: Martin Waitz Signed-off-by: Junio C Hamano --- Makefile | 25 +++++++++++++++++++++++-- gitweb/README | 17 +++++++++++++++++ gitweb/{gitweb.cgi => gitweb.perl} | 15 +++++++-------- 3 files changed, 47 insertions(+), 10 deletions(-) rename gitweb/{gitweb.cgi => gitweb.perl} (99%) diff --git a/Makefile b/Makefile index 15864e23bd..fb2b28868a 100644 --- a/Makefile +++ b/Makefile @@ -116,6 +116,13 @@ template_dir = $(prefix)/share/git-core/templates/ GIT_PYTHON_DIR = $(prefix)/share/git-core/python # DESTDIR= +# default configuration for gitweb +GITWEB_SITENAME = +GITWEB_PROJECTROOT = /pub/git +GITWEB_LIST = +GITWEB_HOMETEXT = indextext.html +GITWEB_CSS = gitweb.css + export prefix bindir gitexecdir template_dir GIT_PYTHON_DIR CC = gcc @@ -514,7 +521,7 @@ LIB_OBJS += $(COMPAT_OBJS) export prefix TAR INSTALL DESTDIR SHELL_PATH template_dir ### Build rules -all: $(ALL_PROGRAMS) $(BUILT_INS) git$X gitk +all: $(ALL_PROGRAMS) $(BUILT_INS) git$X gitk gitweb/gitweb.cgi all: $(MAKE) -C templates @@ -572,6 +579,20 @@ git-status: git-commit cp $< $@+ mv $@+ $@ +gitweb/gitweb.cgi: gitweb/gitweb.perl + rm -f $@ $@+ + sed -e '1s|#!.*perl|#!$(PERL_PATH_SQ)|' \ + -e 's|@@GIT_VERSION@@|$(GIT_VERSION)|g' \ + -e 's|@@GIT_BINDIR@@|$(bindir)|g' \ + -e 's|@@GITWEB_SITENAME@@|$(GITWEB_SITENAME)|g' \ + -e 's|@@GITWEB_PROJECTROOT@@|$(GITWEB_PROJECTROOT)|g' \ + -e 's|@@GITWEB_LIST@@|$(GITWEB_LIST)|g' \ + -e 's|@@GITWEB_HOMETEXT@@|$(GITWEB_HOMETEXT)|g' \ + -e 's|@@GITWEB_CSS@@|$(GITWEB_CSS)|g' \ + $< >$@+ + chmod +x $@+ + mv $@+ $@ + git-instaweb: git-instaweb.sh gitweb/gitweb.cgi gitweb/gitweb.css rm -f $@ $@+ sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ @@ -582,7 +603,7 @@ git-instaweb: git-instaweb.sh gitweb/gitweb.cgi gitweb/gitweb.css -e '/@@GITWEB_CGI@@/d' \ -e '/@@GITWEB_CSS@@/r gitweb/gitweb.css' \ -e '/@@GITWEB_CSS@@/d' \ - $@.sh | sed "s|/usr/bin/git|$(bindir)/git|" > $@+ + $@.sh > $@+ chmod +x $@+ mv $@+ $@ diff --git a/gitweb/README b/gitweb/README index 8d672762ea..ed939e2fb5 100644 --- a/gitweb/README +++ b/gitweb/README @@ -5,5 +5,22 @@ The one working on: From the git version 1.4.0 gitweb is bundled with git. + +How to configure gitweb for your local system: + +You can specify the following configuration variables when building GIT: + * GITWEB_SITENAME + Shown in the title of all generated pages, defaults to the servers name. + * GITWEB_PROJECTROOT + The root directory for all projects shown by gitweb. + * GITWEB_LIST + points to a directory to scan for projects (defaults to project root) + or to a file for explicit listing of projects. + * GITWEB_HOMETEXT + points to an .html file which is included on the gitweb project + overview page. + * GITWEB_CSS + Points to the location where you put gitweb.css on your web server. + Any comment/question/concern to: Kay Sievers diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.perl similarity index 99% rename from gitweb/gitweb.cgi rename to gitweb/gitweb.perl index 9448b72798..6e4261d5f2 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.perl @@ -18,18 +18,18 @@ use File::Find qw(); binmode STDOUT, ':utf8'; our $cgi = new CGI; -our $version = "267"; +our $version = "@@GIT_VERSION@@"; our $my_url = $cgi->url(); our $my_uri = $cgi->url(-absolute => 1); our $rss_link = ""; # core git executable to use # this can just be "git" if your webserver has a sensible PATH -our $GIT = "/usr/bin/git"; +our $GIT = "@@GIT_BINDIR@@/git"; # absolute fs-path which will be prepended to the project path #our $projectroot = "/pub/scm"; -our $projectroot = "/home/kay/public_html/pub/scm"; +our $projectroot = "@@GITWEB_PROJECTROOT@@"; # version of the core git binary our $git_version = qx($GIT --version) =~ m/git version (.*)$/ ? $1 : "unknown"; @@ -45,17 +45,16 @@ our $home_link = $my_uri; # name of your site or organization to appear in page titles # replace this with something more descriptive for clearer bookmarks -our $site_name = $ENV{'SERVER_NAME'} || "Untitled"; +our $site_name = "@@GITWEB_SITENAME@@" || $ENV{'SERVER_NAME'} || "Untitled"; # html text to include at home page -our $home_text = "indextext.html"; +our $home_text = "@@GITWEB_HOMETEXT@@"; # URI of default stylesheet -our $stylesheet = "gitweb.css"; +our $stylesheet = "@@GITWEB_CSS@@"; # source of projects list -#our $projects_list = $projectroot; -our $projects_list = "index/index.aux"; +our $projects_list = "@@GITWEB_LIST@@" || "$projectroot"; # default blob_plain mimetype and default charset for text/plain blob our $default_blob_plain_mimetype = 'text/plain'; From 281f2f6b45bf62e5bc81a6b457f1f7d26c426ea3 Mon Sep 17 00:00:00 2001 From: Martin Waitz Date: Mon, 31 Jul 2006 00:38:39 +0200 Subject: [PATCH 037/160] gitweb: use out-of-line GIT logo. Use the normal web server instead of the CGI to provide the git logo, just like the gitweb.css. Signed-off-by: Martin Waitz Signed-off-by: Junio C Hamano --- Makefile | 2 ++ gitweb/README | 2 ++ gitweb/git-logo.png | Bin 0 -> 208 bytes gitweb/gitweb.perl | 29 ++++------------------------- 4 files changed, 8 insertions(+), 25 deletions(-) create mode 100644 gitweb/git-logo.png diff --git a/Makefile b/Makefile index fb2b28868a..ac5db1ef4c 100644 --- a/Makefile +++ b/Makefile @@ -122,6 +122,7 @@ GITWEB_PROJECTROOT = /pub/git GITWEB_LIST = GITWEB_HOMETEXT = indextext.html GITWEB_CSS = gitweb.css +GITWEB_LOGO = git-logo.png export prefix bindir gitexecdir template_dir GIT_PYTHON_DIR @@ -589,6 +590,7 @@ gitweb/gitweb.cgi: gitweb/gitweb.perl -e 's|@@GITWEB_LIST@@|$(GITWEB_LIST)|g' \ -e 's|@@GITWEB_HOMETEXT@@|$(GITWEB_HOMETEXT)|g' \ -e 's|@@GITWEB_CSS@@|$(GITWEB_CSS)|g' \ + -e 's|@@GITWEB_LOGO@@|$(GITWEB_LOGO)|g' \ $< >$@+ chmod +x $@+ mv $@+ $@ diff --git a/gitweb/README b/gitweb/README index ed939e2fb5..1b2180c731 100644 --- a/gitweb/README +++ b/gitweb/README @@ -21,6 +21,8 @@ You can specify the following configuration variables when building GIT: overview page. * GITWEB_CSS Points to the location where you put gitweb.css on your web server. + * GITWEB_LOGO + Points to the location where you put git-logo.png on your web server. Any comment/question/concern to: Kay Sievers diff --git a/gitweb/git-logo.png b/gitweb/git-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..16ae8d5382de5ffe63b54139245143513a87446e GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^9zZP3!VDyJZ(h*_QW60^A+G=b|4&GW-LQTYLj%LP zv&RoGFuZv2?ECj`Q+bxV1Jx9Jx;TbtoKN;hS77mqk>KLcN(xR?VB+A-bX~J>A)^7$ zJXDx2{a_29 zsY;<{(@cXMleq+Ux^^7wU9iYSkxkvP$)WY2Yo|g1Bf}C~#iK$pv;G0CXYh3Ob6Mw< G&;$VMfkjjR literal 0 HcmV?d00001 diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 6e4261d5f2..1db1414a0a 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -52,6 +52,8 @@ our $home_text = "@@GITWEB_HOMETEXT@@"; # URI of default stylesheet our $stylesheet = "@@GITWEB_CSS@@"; +# URI of GIT logo +our $logo = "@@GITWEB_LOGO@@"; # source of projects list our $projects_list = "@@GITWEB_LIST@@" || "$projectroot"; @@ -71,10 +73,7 @@ if (defined $action) { undef $action; die_error(undef, "Invalid action parameter."); } - if ($action eq "git-logo.png") { - git_logo(); - exit; - } elsif ($action eq "opml") { + if ($action eq "opml") { git_opml(); exit; } @@ -873,7 +872,7 @@ $rss_link EOF print "
\n" . "" . - "\"git\"" . + "\"git\"" . "\n"; print $cgi->a({-href => esc_param($home_link)}, "projects") . " / "; if (defined $project) { @@ -1267,26 +1266,6 @@ sub git_diff_print { ## ====================================================================== ## actions -# git-logo (cached in browser for one day) -sub git_logo { - binmode STDOUT, ':raw'; - print $cgi->header(-type => 'image/png', -expires => '+1d'); - # cat git-logo.png | hexdump -e '16/1 " %02x" "\n"' | sed 's/ /\\x/g' - print "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52" . - "\x00\x00\x00\x48\x00\x00\x00\x1b\x04\x03\x00\x00\x00\x2d\xd9\xd4" . - "\x2d\x00\x00\x00\x18\x50\x4c\x54\x45\xff\xff\xff\x60\x60\x5d\xb0" . - "\xaf\xaa\x00\x80\x00\xce\xcd\xc7\xc0\x00\x00\xe8\xe8\xe6\xf7\xf7" . - "\xf6\x95\x0c\xa7\x47\x00\x00\x00\x73\x49\x44\x41\x54\x28\xcf\x63" . - "\x48\x67\x20\x04\x4a\x5c\x18\x0a\x08\x2a\x62\x53\x61\x20\x02\x08" . - "\x0d\x69\x45\xac\xa1\xa1\x01\x30\x0c\x93\x60\x36\x26\x52\x91\xb1" . - "\x01\x11\xd6\xe1\x55\x64\x6c\x6c\xcc\x6c\x6c\x0c\xa2\x0c\x70\x2a" . - "\x62\x06\x2a\xc1\x62\x1d\xb3\x01\x02\x53\xa4\x08\xe8\x00\x03\x18" . - "\x26\x56\x11\xd4\xe1\x20\x97\x1b\xe0\xb4\x0e\x35\x24\x71\x29\x82" . - "\x99\x30\xb8\x93\x0a\x11\xb9\x45\x88\xc1\x8d\xa0\xa2\x44\x21\x06" . - "\x27\x41\x82\x40\x85\xc1\x45\x89\x20\x70\x01\x00\xa4\x3d\x21\xc5" . - "\x12\x1c\x9a\xfe\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82"; -} - sub git_project_list { my $order = $cgi->param('o'); if (defined $order && $order !~ m/project|descr|owner|age/) { From ee0d3234b1e4e69819635d4fc9e9c37933c0ea82 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 1 Aug 2006 15:56:28 -0700 Subject: [PATCH 038/160] gitweb/README: do not bug Kay with gitweb questions anymore Signed-off-by: Junio C Hamano --- gitweb/README | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gitweb/README b/gitweb/README index 1b2180c731..b91d42a909 100644 --- a/gitweb/README +++ b/gitweb/README @@ -24,5 +24,9 @@ You can specify the following configuration variables when building GIT: * GITWEB_LOGO Points to the location where you put git-logo.png on your web server. -Any comment/question/concern to: +Originally written by: Kay Sievers + +Any comment/question/concern to: + Git mailing list + From 22987ae0bc354bb2277c068ce15e9887f7cf0626 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 1 Aug 2006 16:23:47 -0700 Subject: [PATCH 039/160] Makefile: gitweb/gitweb.cgi is now generated. Signed-off-by: Junio C Hamano --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index ac5db1ef4c..6624c7501e 100644 --- a/Makefile +++ b/Makefile @@ -804,6 +804,7 @@ clean: rm -rf $(GIT_TARNAME) .doc-tmp-dir rm -f $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz rm -f $(htmldocs).tar.gz $(manpages).tar.gz + rm -f gitweb/gitweb.cgi $(MAKE) -C Documentation/ clean $(MAKE) -C templates clean $(MAKE) -C t/ clean From c8d138a8c004ebce6ef840cfcc7c47227c2d16ba Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 2 Aug 2006 15:23:34 -0400 Subject: [PATCH 040/160] gitweb: optionally read config from GITWEB_CONFIG Configuration will first be taken from variables inside the gitweb.cgi script, which in turn come from the Makefile. Afterwards, the contents of GITWEB_CONFIG are read, overriding the builtin defaults. This should eliminate the need for editing the gitweb script at all. Users should edit the Makefile and/or add a config file. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- Makefile | 2 ++ gitweb/gitweb.perl | 19 ++++++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 6624c7501e..a2b4acaaae 100644 --- a/Makefile +++ b/Makefile @@ -117,6 +117,7 @@ GIT_PYTHON_DIR = $(prefix)/share/git-core/python # DESTDIR= # default configuration for gitweb +GITWEB_CONFIG = gitweb_config.perl GITWEB_SITENAME = GITWEB_PROJECTROOT = /pub/git GITWEB_LIST = @@ -585,6 +586,7 @@ gitweb/gitweb.cgi: gitweb/gitweb.perl sed -e '1s|#!.*perl|#!$(PERL_PATH_SQ)|' \ -e 's|@@GIT_VERSION@@|$(GIT_VERSION)|g' \ -e 's|@@GIT_BINDIR@@|$(bindir)|g' \ + -e 's|@@GITWEB_CONFIG@@|$(GITWEB_CONFIG)|g' \ -e 's|@@GITWEB_SITENAME@@|$(GITWEB_SITENAME)|g' \ -e 's|@@GITWEB_PROJECTROOT@@|$(GITWEB_PROJECTROOT)|g' \ -e 's|@@GITWEB_LIST@@|$(GITWEB_LIST)|g' \ diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 1db1414a0a..d5b2de8b3a 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -31,14 +31,8 @@ our $GIT = "@@GIT_BINDIR@@/git"; #our $projectroot = "/pub/scm"; our $projectroot = "@@GITWEB_PROJECTROOT@@"; -# version of the core git binary -our $git_version = qx($GIT --version) =~ m/git version (.*)$/ ? $1 : "unknown"; - # location for temporary files needed for diffs our $git_temp = "/tmp/gitweb"; -if (! -d $git_temp) { - mkdir($git_temp, 0700) || die_error("Couldn't mkdir $git_temp"); -} # target of the home link on top of all pages our $home_link = $my_uri; @@ -56,7 +50,7 @@ our $stylesheet = "@@GITWEB_CSS@@"; our $logo = "@@GITWEB_LOGO@@"; # source of projects list -our $projects_list = "@@GITWEB_LIST@@" || "$projectroot"; +our $projects_list = "@@GITWEB_LIST@@"; # default blob_plain mimetype and default charset for text/plain blob our $default_blob_plain_mimetype = 'text/plain'; @@ -66,6 +60,17 @@ our $default_text_plain_charset = undef; # (relative to the current git repository) our $mimetypes_file = undef; +our $GITWEB_CONFIG = "@@GITWEB_CONFIG@@"; +require $GITWEB_CONFIG if -e $GITWEB_CONFIG; + +# version of the core git binary +our $git_version = qx($GIT --version) =~ m/git version (.*)$/ ? $1 : "unknown"; + +$projects_list ||= $projectroot; +if (! -d $git_temp) { + mkdir($git_temp, 0700) || die_error("Couldn't mkdir $git_temp"); +} + # input validation and dispatch our $action = $cgi->param('a'); if (defined $action) { From bb55f77fcd0748e0faf152a565eef65b2066cfb4 Mon Sep 17 00:00:00 2001 From: Matthias Lederhofer Date: Wed, 2 Aug 2006 22:29:36 +0200 Subject: [PATCH 041/160] gitweb: require $ENV{'GITWEB_CONFIG'} With this patch it is possible to use gitweb.perl for developing by loading the configuration from $GITWEB_CONFIG. This might also be useful for normal usage of gitweb. Example: % cat cfg $GIT = '/usr/bin/git'; $projectroot = '/home/matled/src/git'; $projects_list = '/home/matled/src/git/git/gitweb/list'; % cat run #!/bin/sh export GATEWAY_INTERFACE="CGI/1.1" export HTTP_ACCEPT="*/*" export REQUEST_METHOD="GET" export GITWEB_CONFIG='./cfg' export QUERY_STRING=""$1"" exec ./gitweb.perl % time ./run p=git/.git > /dev/null This makes it easy to check for warnings and do performance tests after changes, you can also pipe this to lynx -dump -force-html /dev/stdin to get more than just html. This also documents the original patch adding require $GITWEB_CONFIG. Signed-off-by: Matthias Lederhofer Signed-off-by: Junio C Hamano --- gitweb/README | 5 +++++ gitweb/gitweb.perl | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/gitweb/README b/gitweb/README index b91d42a909..27c6dac143 100644 --- a/gitweb/README +++ b/gitweb/README @@ -23,6 +23,11 @@ You can specify the following configuration variables when building GIT: Points to the location where you put gitweb.css on your web server. * GITWEB_LOGO Points to the location where you put git-logo.png on your web server. + * GITWEB_CONFIG + This file will be loaded using 'require'. If the environment + $GITWEB_CONFIG is set when gitweb.cgi is executed the file in the + environment variable will be loaded instead of the file + specified when gitweb.cgi was created. Originally written by: Kay Sievers diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index d5b2de8b3a..b5548ec8f1 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -60,7 +60,7 @@ our $default_text_plain_charset = undef; # (relative to the current git repository) our $mimetypes_file = undef; -our $GITWEB_CONFIG = "@@GITWEB_CONFIG@@"; +our $GITWEB_CONFIG = $ENV{'GITWEB_CONFIG'} || "@@GITWEB_CONFIG@@"; require $GITWEB_CONFIG if -e $GITWEB_CONFIG; # version of the core git binary From 06c084d28b150ac1e2ed0c6f3ce7db6ca42dfc67 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 2 Aug 2006 13:50:20 -0700 Subject: [PATCH 042/160] gitweb: do not use @@FOO@@ for replaced tokens This makes it easier to run gitweb/gitweb.perl without token substitution. Using @@ makes Perl emit "unintended interpolation" warnings. Signed-off-by: Junio C Hamano --- Makefile | 18 +++++++++--------- gitweb/gitweb.perl | 18 +++++++++--------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index a2b4acaaae..3816ef7971 100644 --- a/Makefile +++ b/Makefile @@ -584,15 +584,15 @@ git-status: git-commit gitweb/gitweb.cgi: gitweb/gitweb.perl rm -f $@ $@+ sed -e '1s|#!.*perl|#!$(PERL_PATH_SQ)|' \ - -e 's|@@GIT_VERSION@@|$(GIT_VERSION)|g' \ - -e 's|@@GIT_BINDIR@@|$(bindir)|g' \ - -e 's|@@GITWEB_CONFIG@@|$(GITWEB_CONFIG)|g' \ - -e 's|@@GITWEB_SITENAME@@|$(GITWEB_SITENAME)|g' \ - -e 's|@@GITWEB_PROJECTROOT@@|$(GITWEB_PROJECTROOT)|g' \ - -e 's|@@GITWEB_LIST@@|$(GITWEB_LIST)|g' \ - -e 's|@@GITWEB_HOMETEXT@@|$(GITWEB_HOMETEXT)|g' \ - -e 's|@@GITWEB_CSS@@|$(GITWEB_CSS)|g' \ - -e 's|@@GITWEB_LOGO@@|$(GITWEB_LOGO)|g' \ + -e 's|++GIT_VERSION++|$(GIT_VERSION)|g' \ + -e 's|++GIT_BINDIR++|$(bindir)|g' \ + -e 's|++GITWEB_CONFIG++|$(GITWEB_CONFIG)|g' \ + -e 's|++GITWEB_SITENAME++|$(GITWEB_SITENAME)|g' \ + -e 's|++GITWEB_PROJECTROOT++|$(GITWEB_PROJECTROOT)|g' \ + -e 's|++GITWEB_LIST++|$(GITWEB_LIST)|g' \ + -e 's|++GITWEB_HOMETEXT++|$(GITWEB_HOMETEXT)|g' \ + -e 's|++GITWEB_CSS++|$(GITWEB_CSS)|g' \ + -e 's|++GITWEB_LOGO++|$(GITWEB_LOGO)|g' \ $< >$@+ chmod +x $@+ mv $@+ $@ diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index b5548ec8f1..58eb5b190f 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -18,18 +18,18 @@ use File::Find qw(); binmode STDOUT, ':utf8'; our $cgi = new CGI; -our $version = "@@GIT_VERSION@@"; +our $version = "++GIT_VERSION++"; our $my_url = $cgi->url(); our $my_uri = $cgi->url(-absolute => 1); our $rss_link = ""; # core git executable to use # this can just be "git" if your webserver has a sensible PATH -our $GIT = "@@GIT_BINDIR@@/git"; +our $GIT = "++GIT_BINDIR++/git"; # absolute fs-path which will be prepended to the project path #our $projectroot = "/pub/scm"; -our $projectroot = "@@GITWEB_PROJECTROOT@@"; +our $projectroot = "++GITWEB_PROJECTROOT++"; # location for temporary files needed for diffs our $git_temp = "/tmp/gitweb"; @@ -39,18 +39,18 @@ our $home_link = $my_uri; # name of your site or organization to appear in page titles # replace this with something more descriptive for clearer bookmarks -our $site_name = "@@GITWEB_SITENAME@@" || $ENV{'SERVER_NAME'} || "Untitled"; +our $site_name = "++GITWEB_SITENAME++" || $ENV{'SERVER_NAME'} || "Untitled"; # html text to include at home page -our $home_text = "@@GITWEB_HOMETEXT@@"; +our $home_text = "++GITWEB_HOMETEXT++"; # URI of default stylesheet -our $stylesheet = "@@GITWEB_CSS@@"; +our $stylesheet = "++GITWEB_CSS++"; # URI of GIT logo -our $logo = "@@GITWEB_LOGO@@"; +our $logo = "++GITWEB_LOGO++"; # source of projects list -our $projects_list = "@@GITWEB_LIST@@"; +our $projects_list = "++GITWEB_LIST++"; # default blob_plain mimetype and default charset for text/plain blob our $default_blob_plain_mimetype = 'text/plain'; @@ -60,7 +60,7 @@ our $default_text_plain_charset = undef; # (relative to the current git repository) our $mimetypes_file = undef; -our $GITWEB_CONFIG = $ENV{'GITWEB_CONFIG'} || "@@GITWEB_CONFIG@@"; +our $GITWEB_CONFIG = $ENV{'GITWEB_CONFIG'} || "++GITWEB_CONFIG++"; require $GITWEB_CONFIG if -e $GITWEB_CONFIG; # version of the core git binary From 657b062dbab2e17c750050d76de3e76ea28e603e Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Thu, 3 Aug 2006 00:38:11 +0200 Subject: [PATCH 043/160] autoconf: Add support for setting SHELL_PATH and PERL_PATH This patch adds support for setting SHELL_PATH and PERL_PATH to autoconf generated ./configure script via --with-shell=PATH and --with-perl=PATH options. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- configure.ac | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index c1f7751e6f..1669e40e26 100644 --- a/configure.ac +++ b/configure.ac @@ -19,17 +19,47 @@ echo "# ${config_append}. Generated by configure." > "${config_append}" # Append LINE to file ${config_append} AC_DEFUN([GIT_CONF_APPEND_LINE], [echo "$1" >> "${config_append}"])# GIT_CONF_APPEND_LINE +# +# GIT_ARG_SET_PATH(PROGRAM) +# ------------------------- +# Provide --with-PROGRAM=PATH option to set PATH to PROGRAM +AC_DEFUN([GIT_ARG_SET_PATH], +[AC_ARG_WITH([$1], + [AS_HELP_STRING([--with-$1=PATH], + [provide PATH to $1])], + [GIT_CONF_APPEND_PATH($1)],[]) +])# GIT_ARG_SET_PATH +# +# GIT_CONF_APPEND_PATH(PROGRAM) +# ------------------------------ +# Parse --with-PROGRAM=PATH option to set PROGRAM_PATH=PATH +# Used by GIT_ARG_SET_PATH(PROGRAM) +AC_DEFUN([GIT_CONF_APPEND_PATH], +[PROGRAM=m4_toupper($1); \ +if test "$withval" = "no"; then \ + AC_MSG_WARN([You cannot use git without $1]); \ +else \ + if test "$withval" = "yes"; then \ + AC_MSG_WARN([You should provide path for --with-$1=PATH]); \ + else \ + GIT_CONF_APPEND_LINE(${PROGRAM}_PATH=$withval); \ + fi; \ +fi; \ +]) # GIT_CONF_APPEND_PATH ## Checks for programs. AC_MSG_NOTICE([CHECKS for programs]) # +GIT_ARG_SET_PATH(shell) +GIT_ARG_SET_PATH(perl) +# +# Define NO_PYTHON if you want to lose all benefits of the recursive merge. +# Define PYTHON_PATH to provide path to Python. AC_PROG_CC #AC_PROG_INSTALL # needs install-sh or install.sh in sources AC_CHECK_TOOL(AR, ar, :) AC_CHECK_PROGS(TAR, [gtar tar]) -# -# Define NO_PYTHON if you want to lose all benefits of the recursive merge. ## Checks for libraries. @@ -127,6 +157,7 @@ AC_CHECK_FUNC(setenv,[], ## Site configuration ## --with-PACKAGE[=ARG] and --without-PACKAGE +# # Define NO_SVN_TESTS if you want to skip time-consuming SVN interopability # tests. These tests take up a significant amount of the total test time # but are not needed unless you plan to talk to SVN repos. From c4b1b1401cedefe480e32ceccd4ed678f9409e89 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Thu, 3 Aug 2006 00:38:56 +0200 Subject: [PATCH 044/160] autoconf: Move site configuration section earlier in configure.ac Move site configuration section, i.e. --with-PACKAGE[=ARG] and --without-PACKAGE, --enable-FEATURE[=ARG] and --disable-FEATURE options to the beginning of configure.ac file, just after definitions of macros. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- configure.ac | 100 +++++++++++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/configure.ac b/configure.ac index 1669e40e26..cfd1d4a0bd 100644 --- a/configure.ac +++ b/configure.ac @@ -48,6 +48,56 @@ fi; \ ]) # GIT_CONF_APPEND_PATH +## Site configuration +## --with-PACKAGE[=ARG] and --without-PACKAGE +# +# Define NO_SVN_TESTS if you want to skip time-consuming SVN interopability +# tests. These tests take up a significant amount of the total test time +# but are not needed unless you plan to talk to SVN repos. +# +# Define MOZILLA_SHA1 environment variable when running make to make use of +# a bundled SHA1 routine coming from Mozilla. It is GPL'd and should be fast +# on non-x86 architectures (e.g. PowerPC), while the OpenSSL version (default +# choice) has very fast version optimized for i586. +# +# Define PPC_SHA1 environment variable when running make to make use of +# a bundled SHA1 routine optimized for PowerPC. +# +# Define ARM_SHA1 environment variable when running make to make use of +# a bundled SHA1 routine optimized for ARM. +# +# Define NO_OPENSSL environment variable if you do not have OpenSSL. +# This also implies MOZILLA_SHA1. +# +# Define NO_CURL if you do not have curl installed. git-http-pull and +# git-http-push are not built, and you cannot use http:// and https:// +# transports. +# +# Define CURLDIR=/foo/bar if your curl header and library files are in +# /foo/bar/include and /foo/bar/lib directories. +# +# Define NO_EXPAT if you do not have expat installed. git-http-push is +# not built, and you cannot push using http:// and https:// transports. +# +# Define NO_MMAP if you want to avoid mmap. +# +# Define NO_PYTHON if you want to loose all benefits of the recursive merge. +# +## --enable-FEATURE[=ARG] and --disable-FEATURE +# Define COLLISION_CHECK below if you believe that SHA1's +# 1461501637330902918203684832716283019655932542976 hashes do not give you +# sufficient guarantee that no collisions between objects will ever happen. +# +# Define USE_NSEC below if you want git to care about sub-second file mtimes +# and ctimes. Note that you need recent glibc (at least 2.2.4) for this, and +# it will BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely +# randomly break unless your underlying filesystem supports those sub-second +# times (my ext3 doesn't). +# +# Define USE_STDEV below if you want git to care about the underlying device +# change being considered an inode change from the update-cache perspective. + + ## Checks for programs. AC_MSG_NOTICE([CHECKS for programs]) # @@ -155,56 +205,6 @@ AC_CHECK_FUNC(setenv,[], # a missing newline at the end of the file. -## Site configuration -## --with-PACKAGE[=ARG] and --without-PACKAGE -# -# Define NO_SVN_TESTS if you want to skip time-consuming SVN interopability -# tests. These tests take up a significant amount of the total test time -# but are not needed unless you plan to talk to SVN repos. -# -# Define MOZILLA_SHA1 environment variable when running make to make use of -# a bundled SHA1 routine coming from Mozilla. It is GPL'd and should be fast -# on non-x86 architectures (e.g. PowerPC), while the OpenSSL version (default -# choice) has very fast version optimized for i586. -# -# Define PPC_SHA1 environment variable when running make to make use of -# a bundled SHA1 routine optimized for PowerPC. -# -# Define ARM_SHA1 environment variable when running make to make use of -# a bundled SHA1 routine optimized for ARM. -# -# Define NO_OPENSSL environment variable if you do not have OpenSSL. -# This also implies MOZILLA_SHA1. -# -# Define NO_CURL if you do not have curl installed. git-http-pull and -# git-http-push are not built, and you cannot use http:// and https:// -# transports. -# -# Define CURLDIR=/foo/bar if your curl header and library files are in -# /foo/bar/include and /foo/bar/lib directories. -# -# Define NO_EXPAT if you do not have expat installed. git-http-push is -# not built, and you cannot push using http:// and https:// transports. -# -# Define NO_MMAP if you want to avoid mmap. -# -# Define NO_PYTHON if you want to loose all benefits of the recursive merge. -# -## --enable-FEATURE[=ARG] and --disable-FEATURE -# Define COLLISION_CHECK below if you believe that SHA1's -# 1461501637330902918203684832716283019655932542976 hashes do not give you -# sufficient guarantee that no collisions between objects will ever happen. -# -# Define USE_NSEC below if you want git to care about sub-second file mtimes -# and ctimes. Note that you need recent glibc (at least 2.2.4) for this, and -# it will BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely -# randomly break unless your underlying filesystem supports those sub-second -# times (my ext3 doesn't). -# -# Define USE_STDEV below if you want git to care about the underlying device -# change being considered an inode change from the update-cache perspective. - - ## Output files AC_CONFIG_FILES(["${config_file}":"${config_in}":"${config_append}"]) AC_OUTPUT From eb858c56cb9dcced05d61d47c0351b4f8768d379 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Thu, 3 Aug 2006 00:40:40 +0200 Subject: [PATCH 045/160] autoconf: Add support for setting PYTHON_PATH or NO_PYTHON This patch adds support for setting either PYTHON_PATH or NO_PYTHON to autoconf generated ./configure script via --with-python=PATH (sets PYTHON_PATH) or --without-python (sets NO_PYTHON). Autodetect PYTHON_PATH via AC_PATH_PROGS. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- configure.ac | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/configure.ac b/configure.ac index cfd1d4a0bd..0a54b44939 100644 --- a/configure.ac +++ b/configure.ac @@ -103,6 +103,18 @@ AC_MSG_NOTICE([CHECKS for programs]) # GIT_ARG_SET_PATH(shell) GIT_ARG_SET_PATH(perl) +AC_ARG_WITH(python,[AS_HELP_STRING([--with-python=PATH], [provide PATH to python]) +AS_HELP_STRING([--no-python], [don't use python scripts])], + [if test "$withval" = "no"; then \ + NO_PYTHON=YesPlease; \ + elif test "$withval" != "yes"; then \ + PYTHON_PATH=$withval; \ + fi; \ + ]) +AC_SUBST(NO_PYTHON) +AC_SUBST(PYTHON_PATH) + + # # Define NO_PYTHON if you want to lose all benefits of the recursive merge. # Define PYTHON_PATH to provide path to Python. @@ -110,6 +122,16 @@ AC_PROG_CC #AC_PROG_INSTALL # needs install-sh or install.sh in sources AC_CHECK_TOOL(AR, ar, :) AC_CHECK_PROGS(TAR, [gtar tar]) +if test -z "$NO_PYTHON"; then + AC_PATH_PROGS(PYTHON_PATH, [python2.4 python2.3 python2 python]) + if test -n "$PYTHON_PATH"; then + GIT_CONF_APPEND_LINE([PYTHON_PATH=@PYTHON_PATH@]) + else + GIT_CONF_APPEND_LINE([NO_PYTHON=@NO_PYTHON@]) + fi +else + GIT_CONF_APPEND_LINE([NO_PYTHON=@NO_PYTHON@]) +fi ## Checks for libraries. From d6b64ed0f3549f56c4d948dc2c0f12abc52fd6c9 Mon Sep 17 00:00:00 2001 From: Matthias Kestenholz Date: Thu, 3 Aug 2006 17:24:35 +0200 Subject: [PATCH 046/160] Make git-name-rev a builtin Signed-off-by: Matthias Kestenholz Signed-off-by: Junio C Hamano --- Makefile | 7 ++++--- name-rev.c => builtin-name-rev.c | 4 ++-- builtin.h | 1 + git.c | 1 + 4 files changed, 8 insertions(+), 5 deletions(-) rename name-rev.c => builtin-name-rev.c (98%) diff --git a/Makefile b/Makefile index 700c77f564..132c9cf012 100644 --- a/Makefile +++ b/Makefile @@ -185,7 +185,7 @@ PROGRAMS = \ git-unpack-objects$X git-update-server-info$X \ git-upload-pack$X git-verify-pack$X \ git-symbolic-ref$X \ - git-name-rev$X git-pack-redundant$X git-var$X \ + git-pack-redundant$X git-var$X \ git-describe$X git-merge-tree$X git-blame$X git-imap-send$X BUILT_INS = git-log$X git-whatchanged$X git-show$X git-update-ref$X \ @@ -198,7 +198,7 @@ BUILT_INS = git-log$X git-whatchanged$X git-show$X git-update-ref$X \ git-apply$X git-show-branch$X git-diff-files$X git-update-index$X \ git-diff-index$X git-diff-stages$X git-diff-tree$X git-cat-file$X \ git-fmt-merge-msg$X git-prune$X git-mv$X git-prune-packed$X \ - git-repo-config$X + git-repo-config$X git-name-rev$X # what 'all' will build and 'install' will install, in gitexecdir ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS) @@ -255,7 +255,8 @@ BUILTIN_OBJS = \ builtin-diff-index.o builtin-diff-stages.o builtin-diff-tree.o \ builtin-cat-file.o builtin-mailsplit.o builtin-stripspace.o \ builtin-update-ref.o builtin-fmt-merge-msg.o builtin-prune.o \ - builtin-mv.o builtin-prune-packed.o builtin-repo-config.o + builtin-mv.o builtin-prune-packed.o builtin-repo-config.o \ + builtin-name-rev.o GITLIBS = $(LIB_FILE) $(XDIFF_LIB) LIBS = $(GITLIBS) -lz diff --git a/name-rev.c b/builtin-name-rev.c similarity index 98% rename from name-rev.c rename to builtin-name-rev.c index f92f14e32f..571bba4817 100644 --- a/name-rev.c +++ b/builtin-name-rev.c @@ -1,4 +1,5 @@ #include +#include "builtin.h" #include "cache.h" #include "commit.h" #include "tag.h" @@ -126,12 +127,11 @@ static const char* get_rev_name(struct object *o) return buffer; } -int main(int argc, char **argv) +int cmd_name_rev(int argc, const char **argv, const char *prefix) { struct object_array revs = { 0, 0, NULL }; int as_is = 0, all = 0, transform_stdin = 0; - setup_git_directory(); git_config(git_default_config); if (argc < 2) diff --git a/builtin.h b/builtin.h index 26ebcaf213..d1d9dc14f9 100644 --- a/builtin.h +++ b/builtin.h @@ -49,6 +49,7 @@ extern int cmd_update_ref(int argc, const char **argv, const char *prefix); extern int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix); extern int cmd_mv(int argc, const char **argv, const char *prefix); extern int cmd_repo_config(int argc, const char **argv, const char *prefix); +extern int cmd_name_rev(int argc, const char **argv, const char *prefix); extern int cmd_write_tree(int argc, const char **argv, const char *prefix); extern int write_tree(unsigned char *sha1, int missing_ok, const char *prefix); diff --git a/git.c b/git.c index 6e72a893b7..501a7815fc 100644 --- a/git.c +++ b/git.c @@ -265,6 +265,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp) { "mv", cmd_mv, NEEDS_PREFIX }, { "prune-packed", cmd_prune_packed, NEEDS_PREFIX }, { "repo-config", cmd_repo_config }, + { "name-rev", cmd_name_rev, NEEDS_PREFIX }, }; int i; From 5d4a60033543e063bc9d77ca957de0187fb58fb3 Mon Sep 17 00:00:00 2001 From: Matthias Kestenholz Date: Thu, 3 Aug 2006 17:24:36 +0200 Subject: [PATCH 047/160] Make git-pack-objects a builtin Signed-off-by: Matthias Kestenholz Signed-off-by: Junio C Hamano --- Makefile | 6 +++--- pack-objects.c => builtin-pack-objects.c | 4 ++-- builtin.h | 1 + git.c | 1 + 4 files changed, 7 insertions(+), 5 deletions(-) rename pack-objects.c => builtin-pack-objects.c (99%) diff --git a/Makefile b/Makefile index 132c9cf012..4fd62bcf6d 100644 --- a/Makefile +++ b/Makefile @@ -177,7 +177,7 @@ PROGRAMS = \ git-convert-objects$X git-fetch-pack$X git-fsck-objects$X \ git-hash-object$X git-index-pack$X git-local-fetch$X \ git-merge-base$X \ - git-merge-index$X git-mktag$X git-mktree$X git-pack-objects$X git-patch-id$X \ + git-merge-index$X git-mktag$X git-mktree$X git-patch-id$X \ git-peek-remote$X git-receive-pack$X \ git-send-pack$X git-shell$X \ git-show-index$X git-ssh-fetch$X \ @@ -198,7 +198,7 @@ BUILT_INS = git-log$X git-whatchanged$X git-show$X git-update-ref$X \ git-apply$X git-show-branch$X git-diff-files$X git-update-index$X \ git-diff-index$X git-diff-stages$X git-diff-tree$X git-cat-file$X \ git-fmt-merge-msg$X git-prune$X git-mv$X git-prune-packed$X \ - git-repo-config$X git-name-rev$X + git-repo-config$X git-name-rev$X git-pack-objects$X # what 'all' will build and 'install' will install, in gitexecdir ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS) @@ -256,7 +256,7 @@ BUILTIN_OBJS = \ builtin-cat-file.o builtin-mailsplit.o builtin-stripspace.o \ builtin-update-ref.o builtin-fmt-merge-msg.o builtin-prune.o \ builtin-mv.o builtin-prune-packed.o builtin-repo-config.o \ - builtin-name-rev.o + builtin-name-rev.o builtin-pack-objects.o GITLIBS = $(LIB_FILE) $(XDIFF_LIB) LIBS = $(GITLIBS) -lz diff --git a/pack-objects.c b/builtin-pack-objects.c similarity index 99% rename from pack-objects.c rename to builtin-pack-objects.c index 861c7f08ff..2301cd5c0f 100644 --- a/pack-objects.c +++ b/builtin-pack-objects.c @@ -1,3 +1,4 @@ +#include "builtin.h" #include "cache.h" #include "object.h" #include "blob.h" @@ -1226,7 +1227,7 @@ static int git_pack_config(const char *k, const char *v) return git_default_config(k, v); } -int main(int argc, char **argv) +int cmd_pack_objects(int argc, const char **argv, const char *prefix) { SHA_CTX ctx; char line[40 + 1 + PATH_MAX + 2]; @@ -1235,7 +1236,6 @@ int main(int argc, char **argv) int num_preferred_base = 0; int i; - setup_git_directory(); git_config(git_pack_config); progress = isatty(2); diff --git a/builtin.h b/builtin.h index d1d9dc14f9..bc57a04c05 100644 --- a/builtin.h +++ b/builtin.h @@ -50,6 +50,7 @@ extern int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix); extern int cmd_mv(int argc, const char **argv, const char *prefix); extern int cmd_repo_config(int argc, const char **argv, const char *prefix); extern int cmd_name_rev(int argc, const char **argv, const char *prefix); +extern int cmd_pack_objects(int argc, const char **argv, const char *prefix); extern int cmd_write_tree(int argc, const char **argv, const char *prefix); extern int write_tree(unsigned char *sha1, int missing_ok, const char *prefix); diff --git a/git.c b/git.c index 501a7815fc..5d58946f41 100644 --- a/git.c +++ b/git.c @@ -266,6 +266,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp) { "prune-packed", cmd_prune_packed, NEEDS_PREFIX }, { "repo-config", cmd_repo_config }, { "name-rev", cmd_name_rev, NEEDS_PREFIX }, + { "pack-objects", cmd_pack_objects, NEEDS_PREFIX }, }; int i; From 6441363079d85cf17aee21b8925e9745c8abda16 Mon Sep 17 00:00:00 2001 From: Matthias Kestenholz Date: Thu, 3 Aug 2006 17:24:37 +0200 Subject: [PATCH 048/160] Make git-unpack-objects a builtin Signed-off-by: Matthias Kestenholz Signed-off-by: Junio C Hamano --- Makefile | 7 ++++--- unpack-objects.c => builtin-unpack-objects.c | 7 +++---- builtin.h | 1 + git.c | 1 + 4 files changed, 9 insertions(+), 7 deletions(-) rename unpack-objects.c => builtin-unpack-objects.c (98%) diff --git a/Makefile b/Makefile index 4fd62bcf6d..b108a8aa7a 100644 --- a/Makefile +++ b/Makefile @@ -182,7 +182,7 @@ PROGRAMS = \ git-send-pack$X git-shell$X \ git-show-index$X git-ssh-fetch$X \ git-ssh-upload$X git-unpack-file$X \ - git-unpack-objects$X git-update-server-info$X \ + git-update-server-info$X \ git-upload-pack$X git-verify-pack$X \ git-symbolic-ref$X \ git-pack-redundant$X git-var$X \ @@ -198,7 +198,8 @@ BUILT_INS = git-log$X git-whatchanged$X git-show$X git-update-ref$X \ git-apply$X git-show-branch$X git-diff-files$X git-update-index$X \ git-diff-index$X git-diff-stages$X git-diff-tree$X git-cat-file$X \ git-fmt-merge-msg$X git-prune$X git-mv$X git-prune-packed$X \ - git-repo-config$X git-name-rev$X git-pack-objects$X + git-repo-config$X git-name-rev$X git-pack-objects$X \ + git-unpack-objects$X # what 'all' will build and 'install' will install, in gitexecdir ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS) @@ -256,7 +257,7 @@ BUILTIN_OBJS = \ builtin-cat-file.o builtin-mailsplit.o builtin-stripspace.o \ builtin-update-ref.o builtin-fmt-merge-msg.o builtin-prune.o \ builtin-mv.o builtin-prune-packed.o builtin-repo-config.o \ - builtin-name-rev.o builtin-pack-objects.o + builtin-name-rev.o builtin-pack-objects.o builtin-unpack-objects.o GITLIBS = $(LIB_FILE) $(XDIFF_LIB) LIBS = $(GITLIBS) -lz diff --git a/unpack-objects.c b/builtin-unpack-objects.c similarity index 98% rename from unpack-objects.c rename to builtin-unpack-objects.c index 48c1ee7968..09d264d9f2 100644 --- a/unpack-objects.c +++ b/builtin-unpack-objects.c @@ -1,3 +1,4 @@ +#include "builtin.h" #include "cache.h" #include "object.h" #include "delta.h" @@ -112,7 +113,7 @@ static void write_object(void *buf, unsigned long size, const char *type) } static int resolve_delta(const char *type, - void *base, unsigned long base_size, + void *base, unsigned long base_size, void *delta, unsigned long delta_size) { void *result; @@ -260,13 +261,11 @@ static void unpack_all(void) die("unresolved deltas left after unpacking"); } -int main(int argc, char **argv) +int cmd_unpack_objects(int argc, const char **argv, const char *prefix) { int i; unsigned char sha1[20]; - setup_git_directory(); - quiet = !isatty(2); for (i = 1 ; i < argc; i++) { diff --git a/builtin.h b/builtin.h index bc57a04c05..af73c3c19e 100644 --- a/builtin.h +++ b/builtin.h @@ -51,6 +51,7 @@ extern int cmd_mv(int argc, const char **argv, const char *prefix); extern int cmd_repo_config(int argc, const char **argv, const char *prefix); extern int cmd_name_rev(int argc, const char **argv, const char *prefix); extern int cmd_pack_objects(int argc, const char **argv, const char *prefix); +extern int cmd_unpack_objects(int argc, const char **argv, const char *prefix); extern int cmd_write_tree(int argc, const char **argv, const char *prefix); extern int write_tree(unsigned char *sha1, int missing_ok, const char *prefix); diff --git a/git.c b/git.c index 5d58946f41..7c3a7f8fd1 100644 --- a/git.c +++ b/git.c @@ -267,6 +267,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp) { "repo-config", cmd_repo_config }, { "name-rev", cmd_name_rev, NEEDS_PREFIX }, { "pack-objects", cmd_pack_objects, NEEDS_PREFIX }, + { "unpack-objects", cmd_unpack_objects, NEEDS_PREFIX }, }; int i; From 640ce1052bbd6a8f1dd4d58beaa521d7592a0f02 Mon Sep 17 00:00:00 2001 From: Matthias Kestenholz Date: Thu, 3 Aug 2006 17:24:38 +0200 Subject: [PATCH 049/160] Make git-symbolic-ref a builtin Signed-off-by: Matthias Kestenholz Signed-off-by: Junio C Hamano --- Makefile | 6 +++--- symbolic-ref.c => builtin-symbolic-ref.c | 4 ++-- builtin.h | 1 + git.c | 1 + 4 files changed, 7 insertions(+), 5 deletions(-) rename symbolic-ref.c => builtin-symbolic-ref.c (88%) diff --git a/Makefile b/Makefile index b108a8aa7a..db59e00ede 100644 --- a/Makefile +++ b/Makefile @@ -184,7 +184,6 @@ PROGRAMS = \ git-ssh-upload$X git-unpack-file$X \ git-update-server-info$X \ git-upload-pack$X git-verify-pack$X \ - git-symbolic-ref$X \ git-pack-redundant$X git-var$X \ git-describe$X git-merge-tree$X git-blame$X git-imap-send$X @@ -199,7 +198,7 @@ BUILT_INS = git-log$X git-whatchanged$X git-show$X git-update-ref$X \ git-diff-index$X git-diff-stages$X git-diff-tree$X git-cat-file$X \ git-fmt-merge-msg$X git-prune$X git-mv$X git-prune-packed$X \ git-repo-config$X git-name-rev$X git-pack-objects$X \ - git-unpack-objects$X + git-unpack-objects$X git-symbolic-ref$X # what 'all' will build and 'install' will install, in gitexecdir ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS) @@ -257,7 +256,8 @@ BUILTIN_OBJS = \ builtin-cat-file.o builtin-mailsplit.o builtin-stripspace.o \ builtin-update-ref.o builtin-fmt-merge-msg.o builtin-prune.o \ builtin-mv.o builtin-prune-packed.o builtin-repo-config.o \ - builtin-name-rev.o builtin-pack-objects.o builtin-unpack-objects.o + builtin-name-rev.o builtin-pack-objects.o builtin-unpack-objects.o \ + builtin-symbolic-ref.o GITLIBS = $(LIB_FILE) $(XDIFF_LIB) LIBS = $(GITLIBS) -lz diff --git a/symbolic-ref.c b/builtin-symbolic-ref.c similarity index 88% rename from symbolic-ref.c rename to builtin-symbolic-ref.c index 193c87c174..b4ec6f28ed 100644 --- a/symbolic-ref.c +++ b/builtin-symbolic-ref.c @@ -1,3 +1,4 @@ +#include "builtin.h" #include "cache.h" static const char git_symbolic_ref_usage[] = @@ -17,9 +18,8 @@ static void check_symref(const char *HEAD) die("No such ref: %s", HEAD); } -int main(int argc, const char **argv) +int cmd_symbolic_ref(int argc, const char **argv, const char *prefix) { - setup_git_directory(); git_config(git_default_config); switch (argc) { case 2: diff --git a/builtin.h b/builtin.h index af73c3c19e..b767245c75 100644 --- a/builtin.h +++ b/builtin.h @@ -52,6 +52,7 @@ extern int cmd_repo_config(int argc, const char **argv, const char *prefix); extern int cmd_name_rev(int argc, const char **argv, const char *prefix); extern int cmd_pack_objects(int argc, const char **argv, const char *prefix); extern int cmd_unpack_objects(int argc, const char **argv, const char *prefix); +extern int cmd_symbolic_ref(int argc, const char **argv, const char *prefix); extern int cmd_write_tree(int argc, const char **argv, const char *prefix); extern int write_tree(unsigned char *sha1, int missing_ok, const char *prefix); diff --git a/git.c b/git.c index 7c3a7f8fd1..e40e85935c 100644 --- a/git.c +++ b/git.c @@ -268,6 +268,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp) { "name-rev", cmd_name_rev, NEEDS_PREFIX }, { "pack-objects", cmd_pack_objects, NEEDS_PREFIX }, { "unpack-objects", cmd_unpack_objects, NEEDS_PREFIX }, + { "symbolic-ref", cmd_symbolic_ref, NEEDS_PREFIX }, }; int i; From e414156ab6e7869b29622ee3439e3c91361f5b0e Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 4 Aug 2006 01:23:19 -0700 Subject: [PATCH 050/160] Make git-checkout-index a builtin Signed-off-by: Junio C Hamano --- Makefile | 6 +++-- checkout-index.c => builtin-checkout-index.c | 26 +++++++++----------- builtin.h | 1 + git.c | 1 + 4 files changed, 18 insertions(+), 16 deletions(-) rename checkout-index.c => builtin-checkout-index.c (92%) diff --git a/Makefile b/Makefile index db59e00ede..1a3605b123 100644 --- a/Makefile +++ b/Makefile @@ -173,7 +173,6 @@ SIMPLE_PROGRAMS = \ # ... and all the rest that could be moved out of bindir to gitexecdir PROGRAMS = \ - git-checkout-index$X \ git-convert-objects$X git-fetch-pack$X git-fsck-objects$X \ git-hash-object$X git-index-pack$X git-local-fetch$X \ git-merge-base$X \ @@ -187,7 +186,9 @@ PROGRAMS = \ git-pack-redundant$X git-var$X \ git-describe$X git-merge-tree$X git-blame$X git-imap-send$X -BUILT_INS = git-log$X git-whatchanged$X git-show$X git-update-ref$X \ +BUILT_INS = \ + git-checkout-index$X \ + git-log$X git-whatchanged$X git-show$X git-update-ref$X \ git-count-objects$X git-diff$X git-push$X git-mailsplit$X \ git-grep$X git-add$X git-rm$X git-rev-list$X git-stripspace$X \ git-check-ref-format$X git-rev-parse$X git-mailinfo$X \ @@ -245,6 +246,7 @@ LIB_OBJS = \ alloc.o merge-file.o path-list.o $(DIFF_OBJS) BUILTIN_OBJS = \ + builtin-checkout-index.o \ builtin-log.o builtin-help.o builtin-count.o builtin-diff.o builtin-push.o \ builtin-grep.o builtin-add.o builtin-rev-list.o builtin-check-ref-format.o \ builtin-rm.o builtin-init-db.o builtin-rev-parse.o \ diff --git a/checkout-index.c b/builtin-checkout-index.c similarity index 92% rename from checkout-index.c rename to builtin-checkout-index.c index 61152f34b7..29ea6fdc62 100644 --- a/checkout-index.c +++ b/builtin-checkout-index.c @@ -42,8 +42,6 @@ #include "cache-tree.h" #define CHECKOUT_ALL 4 -static const char *prefix; -static int prefix_length; static int line_termination = '\n'; static int checkout_stage; /* default to checkout stage0 */ static int to_tempfile; @@ -51,7 +49,7 @@ static char topath[4][MAXPATHLEN+1]; static struct checkout state; -static void write_tempfile_record (const char *name) +static void write_tempfile_record(const char *name, int prefix_length) { int i; @@ -77,7 +75,7 @@ static void write_tempfile_record (const char *name) } } -static int checkout_file(const char *name) +static int checkout_file(const char *name, int prefix_length) { int namelen = strlen(name); int pos = cache_name_pos(name, namelen); @@ -106,7 +104,7 @@ static int checkout_file(const char *name) if (did_checkout) { if (to_tempfile) - write_tempfile_record(name); + write_tempfile_record(name, prefix_length); return errs > 0 ? -1 : 0; } @@ -124,7 +122,7 @@ static int checkout_file(const char *name) return -1; } -static int checkout_all(void) +static int checkout_all(const char *prefix, int prefix_length) { int i, errs = 0; struct cache_entry* last_ce = NULL; @@ -141,7 +139,7 @@ static int checkout_all(void) if (last_ce && to_tempfile) { if (ce_namelen(last_ce) != ce_namelen(ce) || memcmp(last_ce->name, ce->name, ce_namelen(ce))) - write_tempfile_record(last_ce->name); + write_tempfile_record(last_ce->name, prefix_length); } if (checkout_entry(ce, &state, to_tempfile ? topath[ce_stage(ce)] : NULL) < 0) @@ -149,7 +147,7 @@ static int checkout_all(void) last_ce = ce; } if (last_ce && to_tempfile) - write_tempfile_record(last_ce->name); + write_tempfile_record(last_ce->name, prefix_length); if (errs) /* we have already done our error reporting. * exit with the same code as die(). @@ -163,16 +161,16 @@ static const char checkout_cache_usage[] = static struct lock_file lock_file; -int main(int argc, char **argv) +int cmd_checkout_index(int argc, const char **argv, const char *prefix) { int i; int newfd = -1; int all = 0; int read_from_stdin = 0; + int prefix_length; - state.base_dir = ""; - prefix = setup_git_directory(); git_config(git_default_config); + state.base_dir = ""; prefix_length = prefix ? strlen(prefix) : 0; if (read_cache() < 0) { @@ -270,7 +268,7 @@ int main(int argc, char **argv) if (read_from_stdin) die("git-checkout-index: don't mix '--stdin' and explicit filenames"); p = prefix_path(prefix, prefix_length, arg); - checkout_file(p); + checkout_file(p, prefix_length); if (p < arg || p > arg + strlen(arg)) free((char*)p); } @@ -292,7 +290,7 @@ int main(int argc, char **argv) else path_name = buf.buf; p = prefix_path(prefix, prefix_length, path_name); - checkout_file(p); + checkout_file(p, prefix_length); if (p < path_name || p > path_name + strlen(path_name)) free((char *)p); if (path_name != buf.buf) @@ -301,7 +299,7 @@ int main(int argc, char **argv) } if (all) - checkout_all(); + checkout_all(prefix, prefix_length); if (0 <= newfd && (write_cache(newfd, active_cache, active_nr) || diff --git a/builtin.h b/builtin.h index b767245c75..3a24637b11 100644 --- a/builtin.h +++ b/builtin.h @@ -53,6 +53,7 @@ extern int cmd_name_rev(int argc, const char **argv, const char *prefix); extern int cmd_pack_objects(int argc, const char **argv, const char *prefix); extern int cmd_unpack_objects(int argc, const char **argv, const char *prefix); extern int cmd_symbolic_ref(int argc, const char **argv, const char *prefix); +extern int cmd_checkout_index(int argc, const char **argv, const char *prefix); extern int cmd_write_tree(int argc, const char **argv, const char *prefix); extern int write_tree(unsigned char *sha1, int missing_ok, const char *prefix); diff --git a/git.c b/git.c index e40e85935c..07b6d3e9dd 100644 --- a/git.c +++ b/git.c @@ -269,6 +269,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp) { "pack-objects", cmd_pack_objects, NEEDS_PREFIX }, { "unpack-objects", cmd_unpack_objects, NEEDS_PREFIX }, { "symbolic-ref", cmd_symbolic_ref, NEEDS_PREFIX }, + { "checkout-index", cmd_checkout_index, NEEDS_PREFIX }, }; int i; From f754fa9c5480c4556ad268fb5014c4b96cc7b9dc Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 4 Aug 2006 01:51:04 -0700 Subject: [PATCH 051/160] builtins: Makefile clean-up This cleans up the build procedure for built-in commands by: - generating mostly redundant definition of BUILT_INS from BUILTIN_OBJS in the Makefile, - renaming a few files to make the above possible, and - sorting the built-in command table in git.c. It might be a good idea to binary search (or perfect hash) the built-in command table, but that can be done later when somebody feels like. Signed-off-by: Junio C Hamano --- Makefile | 74 +++++++++------ builtin-count.c => builtin-count-objects.c | 0 builtin.h | 102 ++++++++++----------- git.c | 70 +++++++------- builtin-help.c => help.c | 0 5 files changed, 128 insertions(+), 118 deletions(-) rename builtin-count.c => builtin-count-objects.c (100%) rename builtin-help.c => help.c (100%) diff --git a/Makefile b/Makefile index 1a3605b123..dc39f72f1e 100644 --- a/Makefile +++ b/Makefile @@ -187,19 +187,9 @@ PROGRAMS = \ git-describe$X git-merge-tree$X git-blame$X git-imap-send$X BUILT_INS = \ - git-checkout-index$X \ - git-log$X git-whatchanged$X git-show$X git-update-ref$X \ - git-count-objects$X git-diff$X git-push$X git-mailsplit$X \ - git-grep$X git-add$X git-rm$X git-rev-list$X git-stripspace$X \ - git-check-ref-format$X git-rev-parse$X git-mailinfo$X \ - git-init-db$X git-tar-tree$X git-upload-tar$X git-format-patch$X \ - git-ls-files$X git-ls-tree$X git-get-tar-commit-id$X \ - git-read-tree$X git-commit-tree$X git-write-tree$X \ - git-apply$X git-show-branch$X git-diff-files$X git-update-index$X \ - git-diff-index$X git-diff-stages$X git-diff-tree$X git-cat-file$X \ - git-fmt-merge-msg$X git-prune$X git-mv$X git-prune-packed$X \ - git-repo-config$X git-name-rev$X git-pack-objects$X \ - git-unpack-objects$X git-symbolic-ref$X + git-format-patch$X git-show$X git-whatchanged$X \ + git-get-tar-commit-id$X \ + $(patsubst builtin-%.o,git-%$X,$(BUILTIN_OBJS)) # what 'all' will build and 'install' will install, in gitexecdir ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS) @@ -228,7 +218,7 @@ LIB_H = \ blob.h cache.h commit.h csum-file.h delta.h \ diff.h object.h pack.h pkt-line.h quote.h refs.h \ run-command.h strbuf.h tag.h tree.h git-compat-util.h revision.h \ - tree-walk.h log-tree.h dir.h path-list.h + tree-walk.h log-tree.h dir.h path-list.h builtin.h DIFF_OBJS = \ diff.o diff-lib.o diffcore-break.o diffcore-order.o \ @@ -243,23 +233,49 @@ LIB_OBJS = \ server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \ tag.o tree.o usage.o config.o environment.o ctype.o copy.o \ fetch-clone.o revision.o pager.o tree-walk.o xdiff-interface.o \ - alloc.o merge-file.o path-list.o $(DIFF_OBJS) + alloc.o merge-file.o path-list.o help.o $(DIFF_OBJS) BUILTIN_OBJS = \ + builtin-add.o \ + builtin-apply.o \ + builtin-cat-file.o \ builtin-checkout-index.o \ - builtin-log.o builtin-help.o builtin-count.o builtin-diff.o builtin-push.o \ - builtin-grep.o builtin-add.o builtin-rev-list.o builtin-check-ref-format.o \ - builtin-rm.o builtin-init-db.o builtin-rev-parse.o \ - builtin-tar-tree.o builtin-upload-tar.o builtin-update-index.o \ - builtin-ls-files.o builtin-ls-tree.o builtin-write-tree.o \ - builtin-read-tree.o builtin-commit-tree.o builtin-mailinfo.o \ - builtin-apply.o builtin-show-branch.o builtin-diff-files.o \ - builtin-diff-index.o builtin-diff-stages.o builtin-diff-tree.o \ - builtin-cat-file.o builtin-mailsplit.o builtin-stripspace.o \ - builtin-update-ref.o builtin-fmt-merge-msg.o builtin-prune.o \ - builtin-mv.o builtin-prune-packed.o builtin-repo-config.o \ - builtin-name-rev.o builtin-pack-objects.o builtin-unpack-objects.o \ - builtin-symbolic-ref.o + builtin-check-ref-format.o \ + builtin-commit-tree.o \ + builtin-count-objects.o \ + builtin-diff.o \ + builtin-diff-files.o \ + builtin-diff-index.o \ + builtin-diff-stages.o \ + builtin-diff-tree.o \ + builtin-fmt-merge-msg.o \ + builtin-grep.o \ + builtin-init-db.o \ + builtin-log.o \ + builtin-ls-files.o \ + builtin-ls-tree.o \ + builtin-mailinfo.o \ + builtin-mailsplit.o \ + builtin-mv.o \ + builtin-name-rev.o \ + builtin-pack-objects.o \ + builtin-prune.o \ + builtin-prune-packed.o \ + builtin-push.o \ + builtin-read-tree.o \ + builtin-repo-config.o \ + builtin-rev-list.o \ + builtin-rev-parse.o \ + builtin-rm.o \ + builtin-show-branch.o \ + builtin-stripspace.o \ + builtin-symbolic-ref.o \ + builtin-tar-tree.o \ + builtin-unpack-objects.o \ + builtin-update-index.o \ + builtin-update-ref.o \ + builtin-upload-tar.o \ + builtin-write-tree.o GITLIBS = $(LIB_FILE) $(XDIFF_LIB) LIBS = $(GITLIBS) -lz @@ -540,7 +556,7 @@ git$X: git.c common-cmds.h $(BUILTIN_OBJS) $(GITLIBS) GIT-CFLAGS $(ALL_CFLAGS) -o $@ $(filter %.c,$^) \ $(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS) -builtin-help.o: common-cmds.h +help.o: common-cmds.h $(BUILT_INS): git$X rm -f $@ && ln git$X $@ diff --git a/builtin-count.c b/builtin-count-objects.c similarity index 100% rename from builtin-count.c rename to builtin-count-objects.c diff --git a/builtin.h b/builtin.h index 3a24637b11..c0bdb051bd 100644 --- a/builtin.h +++ b/builtin.h @@ -8,62 +8,56 @@ extern const char git_version_string[]; extern const char git_usage_string[]; extern void help_unknown_cmd(const char *cmd); - -extern int cmd_help(int argc, const char **argv, const char *prefix); -extern int cmd_version(int argc, const char **argv, const char *prefix); - -extern int cmd_whatchanged(int argc, const char **argv, const char *prefix); -extern int cmd_show(int argc, const char **argv, const char *prefix); -extern int cmd_log(int argc, const char **argv, const char *prefix); -extern int cmd_diff(int argc, const char **argv, const char *prefix); -extern int cmd_format_patch(int argc, const char **argv, const char *prefix); -extern int cmd_count_objects(int argc, const char **argv, const char *prefix); - -extern int cmd_prune(int argc, const char **argv, const char *prefix); -extern int cmd_prune_packed(int argc, const char **argv, const char *prefix); - -extern int cmd_push(int argc, const char **argv, const char *prefix); -extern int cmd_grep(int argc, const char **argv, const char *prefix); -extern int cmd_rm(int argc, const char **argv, const char *prefix); -extern int cmd_add(int argc, const char **argv, const char *prefix); -extern int cmd_rev_list(int argc, const char **argv, const char *prefix); -extern int cmd_check_ref_format(int argc, const char **argv, const char *prefix); -extern int cmd_init_db(int argc, const char **argv, const char *prefix); -extern int cmd_tar_tree(int argc, const char **argv, const char *prefix); -extern int cmd_upload_tar(int argc, const char **argv, const char *prefix); -extern int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix); -extern int cmd_ls_files(int argc, const char **argv, const char *prefix); -extern int cmd_ls_tree(int argc, const char **argv, const char *prefix); -extern int cmd_read_tree(int argc, const char **argv, const char *prefix); -extern int cmd_commit_tree(int argc, const char **argv, const char *prefix); -extern int cmd_apply(int argc, const char **argv, const char *prefix); -extern int cmd_show_branch(int argc, const char **argv, const char *prefix); -extern int cmd_diff_files(int argc, const char **argv, const char *prefix); -extern int cmd_diff_index(int argc, const char **argv, const char *prefix); -extern int cmd_diff_stages(int argc, const char **argv, const char *prefix); -extern int cmd_diff_tree(int argc, const char **argv, const char *prefix); -extern int cmd_cat_file(int argc, const char **argv, const char *prefix); -extern int cmd_rev_parse(int argc, const char **argv, const char *prefix); -extern int cmd_update_index(int argc, const char **argv, const char *prefix); -extern int cmd_update_ref(int argc, const char **argv, const char *prefix); -extern int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix); -extern int cmd_mv(int argc, const char **argv, const char *prefix); -extern int cmd_repo_config(int argc, const char **argv, const char *prefix); -extern int cmd_name_rev(int argc, const char **argv, const char *prefix); -extern int cmd_pack_objects(int argc, const char **argv, const char *prefix); -extern int cmd_unpack_objects(int argc, const char **argv, const char *prefix); -extern int cmd_symbolic_ref(int argc, const char **argv, const char *prefix); -extern int cmd_checkout_index(int argc, const char **argv, const char *prefix); - -extern int cmd_write_tree(int argc, const char **argv, const char *prefix); +extern int mailinfo(FILE *in, FILE *out, int ks, const char *encoding, const char *msg, const char *patch); +extern int split_mbox(const char **mbox, const char *dir, int allow_bare, int nr_prec, int skip); +extern void stripspace(FILE *in, FILE *out); extern int write_tree(unsigned char *sha1, int missing_ok, const char *prefix); -extern int cmd_mailsplit(int argc, const char **argv, const char *prefix); -extern int split_mbox(const char **mbox, const char *dir, int allow_bare, int nr_prec, int skip); - +extern int cmd_add(int argc, const char **argv, const char *prefix); +extern int cmd_apply(int argc, const char **argv, const char *prefix); +extern int cmd_cat_file(int argc, const char **argv, const char *prefix); +extern int cmd_checkout_index(int argc, const char **argv, const char *prefix); +extern int cmd_check_ref_format(int argc, const char **argv, const char *prefix); +extern int cmd_commit_tree(int argc, const char **argv, const char *prefix); +extern int cmd_count_objects(int argc, const char **argv, const char *prefix); +extern int cmd_diff_files(int argc, const char **argv, const char *prefix); +extern int cmd_diff_index(int argc, const char **argv, const char *prefix); +extern int cmd_diff(int argc, const char **argv, const char *prefix); +extern int cmd_diff_stages(int argc, const char **argv, const char *prefix); +extern int cmd_diff_tree(int argc, const char **argv, const char *prefix); +extern int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix); +extern int cmd_format_patch(int argc, const char **argv, const char *prefix); +extern int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix); +extern int cmd_grep(int argc, const char **argv, const char *prefix); +extern int cmd_help(int argc, const char **argv, const char *prefix); +extern int cmd_init_db(int argc, const char **argv, const char *prefix); +extern int cmd_log(int argc, const char **argv, const char *prefix); +extern int cmd_ls_files(int argc, const char **argv, const char *prefix); +extern int cmd_ls_tree(int argc, const char **argv, const char *prefix); extern int cmd_mailinfo(int argc, const char **argv, const char *prefix); -extern int mailinfo(FILE *in, FILE *out, int ks, const char *encoding, const char *msg, const char *patch); - +extern int cmd_mailsplit(int argc, const char **argv, const char *prefix); +extern int cmd_mv(int argc, const char **argv, const char *prefix); +extern int cmd_name_rev(int argc, const char **argv, const char *prefix); +extern int cmd_pack_objects(int argc, const char **argv, const char *prefix); +extern int cmd_prune(int argc, const char **argv, const char *prefix); +extern int cmd_prune_packed(int argc, const char **argv, const char *prefix); +extern int cmd_push(int argc, const char **argv, const char *prefix); +extern int cmd_read_tree(int argc, const char **argv, const char *prefix); +extern int cmd_repo_config(int argc, const char **argv, const char *prefix); +extern int cmd_rev_list(int argc, const char **argv, const char *prefix); +extern int cmd_rev_parse(int argc, const char **argv, const char *prefix); +extern int cmd_rm(int argc, const char **argv, const char *prefix); +extern int cmd_show_branch(int argc, const char **argv, const char *prefix); +extern int cmd_show(int argc, const char **argv, const char *prefix); extern int cmd_stripspace(int argc, const char **argv, const char *prefix); -extern void stripspace(FILE *in, FILE *out); +extern int cmd_symbolic_ref(int argc, const char **argv, const char *prefix); +extern int cmd_tar_tree(int argc, const char **argv, const char *prefix); +extern int cmd_unpack_objects(int argc, const char **argv, const char *prefix); +extern int cmd_update_index(int argc, const char **argv, const char *prefix); +extern int cmd_update_ref(int argc, const char **argv, const char *prefix); +extern int cmd_upload_tar(int argc, const char **argv, const char *prefix); +extern int cmd_version(int argc, const char **argv, const char *prefix); +extern int cmd_whatchanged(int argc, const char **argv, const char *prefix); +extern int cmd_write_tree(int argc, const char **argv, const char *prefix); + #endif diff --git a/git.c b/git.c index 07b6d3e9dd..754db1a2ee 100644 --- a/git.c +++ b/git.c @@ -224,52 +224,52 @@ static void handle_internal_command(int argc, const char **argv, char **envp) int (*fn)(int, const char **, const char *); int option; } commands[] = { - { "version", cmd_version }, - { "help", cmd_help }, - { "log", cmd_log, NEEDS_PREFIX | USE_PAGER }, - { "whatchanged", cmd_whatchanged, NEEDS_PREFIX | USE_PAGER }, - { "show", cmd_show, NEEDS_PREFIX | USE_PAGER }, - { "push", cmd_push }, - { "format-patch", cmd_format_patch, NEEDS_PREFIX }, + { "add", cmd_add, NEEDS_PREFIX }, + { "apply", cmd_apply }, + { "cat-file", cmd_cat_file, NEEDS_PREFIX }, + { "checkout-index", cmd_checkout_index, NEEDS_PREFIX }, + { "check-ref-format", cmd_check_ref_format }, + { "commit-tree", cmd_commit_tree, NEEDS_PREFIX }, { "count-objects", cmd_count_objects }, { "diff", cmd_diff, NEEDS_PREFIX }, - { "grep", cmd_grep, NEEDS_PREFIX }, - { "rm", cmd_rm, NEEDS_PREFIX }, - { "add", cmd_add, NEEDS_PREFIX }, - { "rev-list", cmd_rev_list, NEEDS_PREFIX }, - { "init-db", cmd_init_db }, - { "get-tar-commit-id", cmd_get_tar_commit_id }, - { "upload-tar", cmd_upload_tar }, - { "check-ref-format", cmd_check_ref_format }, - { "ls-files", cmd_ls_files, NEEDS_PREFIX }, - { "ls-tree", cmd_ls_tree, NEEDS_PREFIX }, - { "tar-tree", cmd_tar_tree, NEEDS_PREFIX }, - { "read-tree", cmd_read_tree, NEEDS_PREFIX }, - { "commit-tree", cmd_commit_tree, NEEDS_PREFIX }, - { "apply", cmd_apply }, - { "show-branch", cmd_show_branch, NEEDS_PREFIX }, { "diff-files", cmd_diff_files, NEEDS_PREFIX }, { "diff-index", cmd_diff_index, NEEDS_PREFIX }, { "diff-stages", cmd_diff_stages, NEEDS_PREFIX }, { "diff-tree", cmd_diff_tree, NEEDS_PREFIX }, - { "cat-file", cmd_cat_file, NEEDS_PREFIX }, - { "rev-parse", cmd_rev_parse, NEEDS_PREFIX }, - { "write-tree", cmd_write_tree, NEEDS_PREFIX }, - { "mailsplit", cmd_mailsplit }, - { "mailinfo", cmd_mailinfo }, - { "stripspace", cmd_stripspace }, - { "update-index", cmd_update_index, NEEDS_PREFIX }, - { "update-ref", cmd_update_ref, NEEDS_PREFIX }, { "fmt-merge-msg", cmd_fmt_merge_msg, NEEDS_PREFIX }, - { "prune", cmd_prune, NEEDS_PREFIX }, + { "format-patch", cmd_format_patch, NEEDS_PREFIX }, + { "get-tar-commit-id", cmd_get_tar_commit_id }, + { "grep", cmd_grep, NEEDS_PREFIX }, + { "help", cmd_help }, + { "init-db", cmd_init_db }, + { "log", cmd_log, NEEDS_PREFIX | USE_PAGER }, + { "ls-files", cmd_ls_files, NEEDS_PREFIX }, + { "ls-tree", cmd_ls_tree, NEEDS_PREFIX }, + { "mailinfo", cmd_mailinfo }, + { "mailsplit", cmd_mailsplit }, { "mv", cmd_mv, NEEDS_PREFIX }, - { "prune-packed", cmd_prune_packed, NEEDS_PREFIX }, - { "repo-config", cmd_repo_config }, { "name-rev", cmd_name_rev, NEEDS_PREFIX }, { "pack-objects", cmd_pack_objects, NEEDS_PREFIX }, - { "unpack-objects", cmd_unpack_objects, NEEDS_PREFIX }, + { "prune", cmd_prune, NEEDS_PREFIX }, + { "prune-packed", cmd_prune_packed, NEEDS_PREFIX }, + { "push", cmd_push }, + { "read-tree", cmd_read_tree, NEEDS_PREFIX }, + { "repo-config", cmd_repo_config }, + { "rev-list", cmd_rev_list, NEEDS_PREFIX }, + { "rev-parse", cmd_rev_parse, NEEDS_PREFIX }, + { "rm", cmd_rm, NEEDS_PREFIX }, + { "show-branch", cmd_show_branch, NEEDS_PREFIX }, + { "show", cmd_show, NEEDS_PREFIX | USE_PAGER }, + { "stripspace", cmd_stripspace }, { "symbolic-ref", cmd_symbolic_ref, NEEDS_PREFIX }, - { "checkout-index", cmd_checkout_index, NEEDS_PREFIX }, + { "tar-tree", cmd_tar_tree, NEEDS_PREFIX }, + { "unpack-objects", cmd_unpack_objects, NEEDS_PREFIX }, + { "update-index", cmd_update_index, NEEDS_PREFIX }, + { "update-ref", cmd_update_ref, NEEDS_PREFIX }, + { "upload-tar", cmd_upload_tar }, + { "version", cmd_version }, + { "whatchanged", cmd_whatchanged, NEEDS_PREFIX | USE_PAGER }, + { "write-tree", cmd_write_tree, NEEDS_PREFIX }, }; int i; diff --git a/builtin-help.c b/help.c similarity index 100% rename from builtin-help.c rename to help.c From efffea033457eedb90ad63596687564f797f12de Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 4 Aug 2006 02:04:00 -0700 Subject: [PATCH 052/160] git.c: Rename NEEDS_PREFIX to RUN_SETUP As Matthias Kestenholz noted, the flag does not quite mean "needs prefix" -- it is more like "run setup_git_directory() before running this command", so rename it to avoid future confusion. While we are at it, rewrite the definition of options to make it obvious that we are talking about flag bits by using standard (1< --- git.c | 72 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/git.c b/git.c index 754db1a2ee..96e596b1a3 100644 --- a/git.c +++ b/git.c @@ -213,8 +213,8 @@ static int handle_alias(int *argcp, const char ***argv) const char git_version_string[] = GIT_VERSION; -#define NEEDS_PREFIX 1 -#define USE_PAGER 2 +#define RUN_SETUP (1<<0) +#define USE_PAGER (1<<1) static void handle_internal_command(int argc, const char **argv, char **envp) { @@ -224,52 +224,52 @@ static void handle_internal_command(int argc, const char **argv, char **envp) int (*fn)(int, const char **, const char *); int option; } commands[] = { - { "add", cmd_add, NEEDS_PREFIX }, + { "add", cmd_add, RUN_SETUP }, { "apply", cmd_apply }, - { "cat-file", cmd_cat_file, NEEDS_PREFIX }, - { "checkout-index", cmd_checkout_index, NEEDS_PREFIX }, + { "cat-file", cmd_cat_file, RUN_SETUP }, + { "checkout-index", cmd_checkout_index, RUN_SETUP }, { "check-ref-format", cmd_check_ref_format }, - { "commit-tree", cmd_commit_tree, NEEDS_PREFIX }, + { "commit-tree", cmd_commit_tree, RUN_SETUP }, { "count-objects", cmd_count_objects }, - { "diff", cmd_diff, NEEDS_PREFIX }, - { "diff-files", cmd_diff_files, NEEDS_PREFIX }, - { "diff-index", cmd_diff_index, NEEDS_PREFIX }, - { "diff-stages", cmd_diff_stages, NEEDS_PREFIX }, - { "diff-tree", cmd_diff_tree, NEEDS_PREFIX }, - { "fmt-merge-msg", cmd_fmt_merge_msg, NEEDS_PREFIX }, - { "format-patch", cmd_format_patch, NEEDS_PREFIX }, + { "diff", cmd_diff, RUN_SETUP }, + { "diff-files", cmd_diff_files, RUN_SETUP }, + { "diff-index", cmd_diff_index, RUN_SETUP }, + { "diff-stages", cmd_diff_stages, RUN_SETUP }, + { "diff-tree", cmd_diff_tree, RUN_SETUP }, + { "fmt-merge-msg", cmd_fmt_merge_msg, RUN_SETUP }, + { "format-patch", cmd_format_patch, RUN_SETUP }, { "get-tar-commit-id", cmd_get_tar_commit_id }, - { "grep", cmd_grep, NEEDS_PREFIX }, + { "grep", cmd_grep, RUN_SETUP }, { "help", cmd_help }, { "init-db", cmd_init_db }, - { "log", cmd_log, NEEDS_PREFIX | USE_PAGER }, - { "ls-files", cmd_ls_files, NEEDS_PREFIX }, - { "ls-tree", cmd_ls_tree, NEEDS_PREFIX }, + { "log", cmd_log, RUN_SETUP | USE_PAGER }, + { "ls-files", cmd_ls_files, RUN_SETUP }, + { "ls-tree", cmd_ls_tree, RUN_SETUP }, { "mailinfo", cmd_mailinfo }, { "mailsplit", cmd_mailsplit }, - { "mv", cmd_mv, NEEDS_PREFIX }, - { "name-rev", cmd_name_rev, NEEDS_PREFIX }, - { "pack-objects", cmd_pack_objects, NEEDS_PREFIX }, - { "prune", cmd_prune, NEEDS_PREFIX }, - { "prune-packed", cmd_prune_packed, NEEDS_PREFIX }, + { "mv", cmd_mv, RUN_SETUP }, + { "name-rev", cmd_name_rev, RUN_SETUP }, + { "pack-objects", cmd_pack_objects, RUN_SETUP }, + { "prune", cmd_prune, RUN_SETUP }, + { "prune-packed", cmd_prune_packed, RUN_SETUP }, { "push", cmd_push }, - { "read-tree", cmd_read_tree, NEEDS_PREFIX }, + { "read-tree", cmd_read_tree, RUN_SETUP }, { "repo-config", cmd_repo_config }, - { "rev-list", cmd_rev_list, NEEDS_PREFIX }, - { "rev-parse", cmd_rev_parse, NEEDS_PREFIX }, - { "rm", cmd_rm, NEEDS_PREFIX }, - { "show-branch", cmd_show_branch, NEEDS_PREFIX }, - { "show", cmd_show, NEEDS_PREFIX | USE_PAGER }, + { "rev-list", cmd_rev_list, RUN_SETUP }, + { "rev-parse", cmd_rev_parse, RUN_SETUP }, + { "rm", cmd_rm, RUN_SETUP }, + { "show-branch", cmd_show_branch, RUN_SETUP }, + { "show", cmd_show, RUN_SETUP | USE_PAGER }, { "stripspace", cmd_stripspace }, - { "symbolic-ref", cmd_symbolic_ref, NEEDS_PREFIX }, - { "tar-tree", cmd_tar_tree, NEEDS_PREFIX }, - { "unpack-objects", cmd_unpack_objects, NEEDS_PREFIX }, - { "update-index", cmd_update_index, NEEDS_PREFIX }, - { "update-ref", cmd_update_ref, NEEDS_PREFIX }, + { "symbolic-ref", cmd_symbolic_ref, RUN_SETUP }, + { "tar-tree", cmd_tar_tree, RUN_SETUP }, + { "unpack-objects", cmd_unpack_objects, RUN_SETUP }, + { "update-index", cmd_update_index, RUN_SETUP }, + { "update-ref", cmd_update_ref, RUN_SETUP }, { "upload-tar", cmd_upload_tar }, { "version", cmd_version }, - { "whatchanged", cmd_whatchanged, NEEDS_PREFIX | USE_PAGER }, - { "write-tree", cmd_write_tree, NEEDS_PREFIX }, + { "whatchanged", cmd_whatchanged, RUN_SETUP | USE_PAGER }, + { "write-tree", cmd_write_tree, RUN_SETUP }, }; int i; @@ -286,7 +286,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp) continue; prefix = NULL; - if (p->option & NEEDS_PREFIX) + if (p->option & RUN_SETUP) prefix = setup_git_directory(); if (p->option & USE_PAGER) setup_pager(); From 656517b9ef5cf443f72110dcd56b15825bc7f1ef Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Fri, 4 Aug 2006 17:55:57 +0200 Subject: [PATCH 053/160] autoconf: Check for ll hh j z t size specifiers introduced by C99 Add custom test for checking whether formatted IO functions (printf/scanf et.al.) support 'size specifiers' introduced by C99, namely ll, hh, j, z, t. (representing long long int, char, intmax_t, size_t, ptrdiff_t). Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- configure.ac | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/configure.ac b/configure.ac index 0a54b44939..a4becf8fa5 100644 --- a/configure.ac +++ b/configure.ac @@ -189,6 +189,27 @@ AC_CHECK_MEMBER(struct dirent.d_type,[], AC_CHECK_TYPE(struct sockaddr_storage,[], [GIT_CONF_APPEND_LINE(NO_SOCKADDR_STORAGE=YesPlease)], [#include ]) +# +# Define NO_C99_FORMAT if your formatted IO functions (printf/scanf et.al.) +# do not support the 'size specifiers' introduced by C99, namely ll, hh, +# j, z, t. (representing long long int, char, intmax_t, size_t, ptrdiff_t). +# some C compilers supported these specifiers prior to C99 as an extension. +AC_CACHE_CHECK(whether IO functions support %ll %hh %j %z %t size specifiers, + ac_cv_c_c99_format, +[# Actually git uses only %z (%zu) in alloc.c, and %t (%td) in mktag.c +AC_RUN_IFELSE( + [AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT], + [[char buf[64]; + if (sprintf(buf, "%lld%hhd%jd%zd%td", (long long int)1, (char)2, (intmax_t)3, (size_t)4, (ptrdiff_t)5) != 5) + exit(1); + else if (strcmp(buf, "12345")) + exit(2);]])], + [ac_cv_c_c99_format=yes], + [ac_cv_c_c99_format=no]) +]) +if test $ac_cv_c_c99_format = no; then + GIT_CONF_APPEND_LINE(NO_C99_FORMAT=YesPlease) +fi ## Checks for library functions. From 465e649d0c62847fd5cca212766e1a01183baeef Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Fri, 4 Aug 2006 17:55:58 +0200 Subject: [PATCH 054/160] autoconf: Typo cleanup, reordering etc. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- Makefile | 2 +- configure.ac | 43 +++++++++++++++++++++++-------------------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/Makefile b/Makefile index 700c77f564..ae4c0f2d90 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ all: # Define NO_C99_FORMAT if your formatted IO functions (printf/scanf et.al.) # do not support the 'size specifiers' introduced by C99, namely ll, hh, # j, z, t. (representing long long int, char, intmax_t, size_t, ptrdiff_t). -# some c compilers supported these specifiers prior to C99 as an extension. +# some C compilers supported these specifiers prior to C99 as an extension. # # Define NO_STRCASESTR if you don't have strcasestr. # diff --git a/configure.ac b/configure.ac index a4becf8fa5..cc6b3cd5fb 100644 --- a/configure.ac +++ b/configure.ac @@ -51,7 +51,7 @@ fi; \ ## Site configuration ## --with-PACKAGE[=ARG] and --without-PACKAGE # -# Define NO_SVN_TESTS if you want to skip time-consuming SVN interopability +# Define NO_SVN_TESTS if you want to skip time-consuming SVN interoperability # tests. These tests take up a significant amount of the total test time # but are not needed unless you plan to talk to SVN repos. # @@ -81,7 +81,24 @@ fi; \ # # Define NO_MMAP if you want to avoid mmap. # -# Define NO_PYTHON if you want to loose all benefits of the recursive merge. +# Define SHELL_PATH to provide path to shell. +GIT_ARG_SET_PATH(shell) +# +# Define PERL_PATH to provide path to Perl. +GIT_ARG_SET_PATH(perl) +# +# Define NO_PYTHON if you want to lose all benefits of the recursive merge. +# Define PYTHON_PATH to provide path to Python. +AC_ARG_WITH(python,[AS_HELP_STRING([--with-python=PATH], [provide PATH to python]) +AS_HELP_STRING([--no-python], [don't use python scripts])], + [if test "$withval" = "no"; then \ + NO_PYTHON=YesPlease; \ + elif test "$withval" != "yes"; then \ + PYTHON_PATH=$withval; \ + fi; \ + ]) +AC_SUBST(NO_PYTHON) +AC_SUBST(PYTHON_PATH) # ## --enable-FEATURE[=ARG] and --disable-FEATURE # Define COLLISION_CHECK below if you believe that SHA1's @@ -101,27 +118,13 @@ fi; \ ## Checks for programs. AC_MSG_NOTICE([CHECKS for programs]) # -GIT_ARG_SET_PATH(shell) -GIT_ARG_SET_PATH(perl) -AC_ARG_WITH(python,[AS_HELP_STRING([--with-python=PATH], [provide PATH to python]) -AS_HELP_STRING([--no-python], [don't use python scripts])], - [if test "$withval" = "no"; then \ - NO_PYTHON=YesPlease; \ - elif test "$withval" != "yes"; then \ - PYTHON_PATH=$withval; \ - fi; \ - ]) -AC_SUBST(NO_PYTHON) -AC_SUBST(PYTHON_PATH) - - -# -# Define NO_PYTHON if you want to lose all benefits of the recursive merge. -# Define PYTHON_PATH to provide path to Python. AC_PROG_CC #AC_PROG_INSTALL # needs install-sh or install.sh in sources AC_CHECK_TOOL(AR, ar, :) AC_CHECK_PROGS(TAR, [gtar tar]) +# +# Define NO_PYTHON if you want to lose all benefits of the recursive merge. +# Define PYTHON_PATH to provide path to Python. if test -z "$NO_PYTHON"; then AC_PATH_PROGS(PYTHON_PATH, [python2.4 python2.3 python2 python]) if test -n "$PYTHON_PATH"; then @@ -194,7 +197,7 @@ AC_CHECK_TYPE(struct sockaddr_storage,[], # do not support the 'size specifiers' introduced by C99, namely ll, hh, # j, z, t. (representing long long int, char, intmax_t, size_t, ptrdiff_t). # some C compilers supported these specifiers prior to C99 as an extension. -AC_CACHE_CHECK(whether IO functions support %ll %hh %j %z %t size specifiers, +AC_CACHE_CHECK(whether formatted IO functions support C99 size specifiers, ac_cv_c_c99_format, [# Actually git uses only %z (%zu) in alloc.c, and %t (%td) in mktag.c AC_RUN_IFELSE( From 34d4a67f47bb8954475077e91d513f445713c534 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Fri, 4 Aug 2006 17:55:59 +0200 Subject: [PATCH 055/160] Copy description of new build configuration variables to configure.ac Copy description of new build configuration variables from the commentary in the top Makefile, namely NO_FINK and NO_DARWIN_PORTS configuration variables, putting them in site configuration section. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- configure.ac | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/configure.ac b/configure.ac index cc6b3cd5fb..9ce00e9522 100644 --- a/configure.ac +++ b/configure.ac @@ -79,6 +79,18 @@ fi; \ # Define NO_EXPAT if you do not have expat installed. git-http-push is # not built, and you cannot push using http:// and https:// transports. # +# Define NO_FINK if you are building on Darwin/Mac OS X, have Fink +# installed in /sw, but don't want GIT to link against any libraries +# installed there. If defined you may specify your own (or Fink's) +# include directories and library directories by defining CFLAGS +# and LDFLAGS appropriately. +# +# Define NO_DARWIN_PORTS if you are building on Darwin/Mac OS X, +# have DarwinPorts installed in /opt/local, but don't want GIT to +# link against any libraries installed there. If defined you may +# specify your own (or DarwinPort's) include directories and +# library directories by defining CFLAGS and LDFLAGS appropriately. +# # Define NO_MMAP if you want to avoid mmap. # # Define SHELL_PATH to provide path to shell. From 3068f6c47d8ece84c7daba243d3f60492bd0611e Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 4 Aug 2006 16:33:18 -0700 Subject: [PATCH 056/160] autoconf: fix NEEDS_SSL_WITH_CRYPTO NEEDS_SSL_WITH_CRYPTO means you cannot just say "-lcrypto" to use SHA1 stuff, but need to say "-lcrypto -lssl". Signed-off-by: Junio C Hamano --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 9ce00e9522..fea18b69b4 100644 --- a/configure.ac +++ b/configure.ac @@ -154,8 +154,8 @@ AC_MSG_NOTICE([CHECKS for libraries]) # # Define NO_OPENSSL environment variable if you do not have OpenSSL. # Define NEEDS_SSL_WITH_CRYPTO if you need -lcrypto with -lssl (Darwin). -AC_CHECK_LIB([ssl], [SHA1_Init],[], -[AC_CHECK_LIB([crypto], [SHA1_INIT], +AC_CHECK_LIB([crypto], [SHA1_Init],[], +[AC_CHECK_LIB([ssl], [SHA1_Init], [GIT_CONF_APPEND_LINE(NEEDS_SSL_WITH_CRYPTO=YesPlease)], [GIT_CONF_APPEND_LINE(NO_OPENSSL=YesPlease)])]) # From f7b5e8d03a97e7d4a6e543d5f9972d1285947908 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Fri, 4 Aug 2006 23:28:11 +0200 Subject: [PATCH 057/160] autoconf: Set NEEDS_LIBICONV unconditionally if there is no iconv in libc Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- configure.ac | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index fea18b69b4..33ddee2120 100644 --- a/configure.ac +++ b/configure.ac @@ -172,8 +172,7 @@ AC_CHECK_LIB([expat], [XML_ParserCreate],[], # # Define NEEDS_LIBICONV if linking with libc is not enough (Darwin). AC_CHECK_LIB([c], [iconv],[], -[AC_CHECK_LIB([iconv],[iconv], - [GIT_CONF_APPEND_LINE(NEEDS_LIBICONV=YesPlease)],[])]) +[GIT_CONF_APPEND_LINE(NEEDS_LIBICONV=YesPlease)]) # # Define NEEDS_SOCKET if linking with libc is not enough (SunOS, # Patrick Mauritz). From 8c6ab35efe635b2f70cdd471903cd80886ec6eec Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 4 Aug 2006 16:46:16 -0700 Subject: [PATCH 058/160] autoconf: NO_IPV6 We would need both "struct addrinfo" and getaddrinfo() available. Check them and set NO_IPV6 otherwise. Signed-off-by: Junio C Hamano --- configure.ac | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 33ddee2120..74c271098c 100644 --- a/configure.ac +++ b/configure.ac @@ -203,6 +203,14 @@ AC_CHECK_MEMBER(struct dirent.d_type,[], AC_CHECK_TYPE(struct sockaddr_storage,[], [GIT_CONF_APPEND_LINE(NO_SOCKADDR_STORAGE=YesPlease)], [#include ]) +# Define NO_IPV6 if you lack IPv6 support and getaddrinfo(). +AC_CHECK_TYPE([struct addrinfo],[ +AC_CHECK_FUNC([getaddrinfo],[], +[GIT_CONF_APPEND_LINE(NO_IPV6=YesPlease)])],[],[ +#include +#include +#include +]) # # Define NO_C99_FORMAT if your formatted IO functions (printf/scanf et.al.) # do not support the 'size specifiers' introduced by C99, namely ll, hh, @@ -244,8 +252,6 @@ AC_CHECK_FUNC(setenv,[], # # Define NO_MMAP if you want to avoid mmap. # -# Define NO_IPV6 if you lack IPv6 support and getaddrinfo(). -# # Define NO_ICONV if your libc does not properly support iconv. From f9f02d012927cba2264b948d16008ede025f7c71 Mon Sep 17 00:00:00 2001 From: Luben Tuikov Date: Fri, 4 Aug 2006 15:14:27 -0700 Subject: [PATCH 059/160] gitweb: git_tree displays blame based on repository config git_tree() will now conditionally display "blame" depending on how "gitweb.blame" variable is configured using "git-repo-config". Signed-off-by: Luben Tuikov Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 58eb5b190f..b268b6344d 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -1757,6 +1757,7 @@ sub git_tree { git_header_html(); my $base_key = ""; my $base = ""; + my $have_blame = git_get_project_config_bool ('blame'); if (defined $hash_base && (my %co = git_read_commit($hash_base))) { $base_key = ";hb=$hash_base"; git_page_nav('tree','', $hash_base); @@ -1792,9 +1793,11 @@ sub git_tree { $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$t_hash$base_key;f=$base$t_name"), -class => "list"}, esc_html($t_name)) . "\n" . "
\n"; } elsif ($t_type eq "tree") { From 61ffbcb988046dfaf8266569f78a31483be026f6 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 4 Aug 2006 17:50:41 +0200 Subject: [PATCH 060/160] http-push: avoid fork() by calling merge_bases() directly Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- http-push.c | 47 ++++++----------------------------------------- 1 file changed, 6 insertions(+), 41 deletions(-) diff --git a/http-push.c b/http-push.c index 4021e7d927..dc82657830 100644 --- a/http-push.c +++ b/http-push.c @@ -2182,49 +2182,14 @@ static void fetch_symref(const char *path, char **symref, unsigned char *sha1) static int verify_merge_base(unsigned char *head_sha1, unsigned char *branch_sha1) { - int pipe_fd[2]; - pid_t merge_base_pid; - char line[PATH_MAX + 20]; - unsigned char merge_sha1[20]; - int verified = 0; + struct commit *head = lookup_commit(head_sha1); + struct commit *branch = lookup_commit(branch_sha1); + struct commit_list *merge_bases = get_merge_bases(head, branch, 1); - if (pipe(pipe_fd) < 0) - die("Verify merge base: pipe failed"); + if (merge_bases && !merge_bases->next && merge_bases->item == branch) + return 1; - merge_base_pid = fork(); - if (!merge_base_pid) { - static const char *args[] = { - "merge-base", - "-a", - NULL, - NULL, - NULL - }; - args[2] = strdup(sha1_to_hex(head_sha1)); - args[3] = sha1_to_hex(branch_sha1); - - dup2(pipe_fd[1], 1); - close(pipe_fd[0]); - close(pipe_fd[1]); - execv_git_cmd(args); - die("merge-base setup failed"); - } - if (merge_base_pid < 0) - die("merge-base fork failed"); - - dup2(pipe_fd[0], 0); - close(pipe_fd[0]); - close(pipe_fd[1]); - while (fgets(line, sizeof(line), stdin) != NULL) { - if (get_sha1_hex(line, merge_sha1)) - die("expected sha1, got garbage:\n %s", line); - if (!memcmp(branch_sha1, merge_sha1, 20)) { - verified = 1; - break; - } - } - - return verified; + return 0; } static int delete_remote_branch(char *pattern, int force) From 154b4d78cf35025268ed74c45f182b25ebaf4acc Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sat, 5 Aug 2006 12:55:20 +0200 Subject: [PATCH 061/160] gitweb: Separate input validation and dispatch, add comment about opml action Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index b268b6344d..7f4387fde6 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -71,6 +71,7 @@ if (! -d $git_temp) { mkdir($git_temp, 0700) || die_error("Couldn't mkdir $git_temp"); } +# ====================================================================== # input validation and dispatch our $action = $cgi->param('a'); if (defined $action) { @@ -78,6 +79,7 @@ if (defined $action) { undef $action; die_error(undef, "Invalid action parameter."); } + # action which does not check rest of parameters if ($action eq "opml") { git_opml(); exit; From cfd826693688245c6d8f48a5fdc1f6780ecca65b Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sat, 5 Aug 2006 12:56:04 +0200 Subject: [PATCH 062/160] gitweb: die_error first (optional) parameter is HTTP status Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 7f4387fde6..040024ccf7 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -68,7 +68,7 @@ our $git_version = qx($GIT --version) =~ m/git version (.*)$/ ? $1 : "unknown"; $projects_list ||= $projectroot; if (! -d $git_temp) { - mkdir($git_temp, 0700) || die_error("Couldn't mkdir $git_temp"); + mkdir($git_temp, 0700) || die_error(undef, "Couldn't mkdir $git_temp"); } # ====================================================================== @@ -1658,7 +1658,7 @@ sub git_blob_plain { } my $type = shift; open my $fd, "-|", $GIT, "cat-file", "blob", $hash - or die_error("Couldn't cat $file_name, $hash"); + or die_error(undef, "Couldn't cat $file_name, $hash"); $type ||= git_blob_plain_mimetype($fd, $file_name); From 623e4aeb42c313360d2c1edba7f844908882c2a1 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sat, 5 Aug 2006 12:56:42 +0200 Subject: [PATCH 063/160] gitweb: Use undef for die_error to use default first (status) parameter value Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 040024ccf7..c11c2f2b70 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -2323,7 +2323,7 @@ sub git_history { sub git_search { if (!defined $searchtext) { - die_error("", "Text field empty."); + die_error(undef, "Text field empty."); } if (!defined $hash) { $hash = git_read_head($project); From dbd954a8969a31741a676e9e7cc2dfd00f8f4e93 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sat, 5 Aug 2006 12:58:06 +0200 Subject: [PATCH 064/160] gitweb: Don't undefine query parameter related variables before die_error Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index c11c2f2b70..89ceb9765d 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -76,7 +76,6 @@ if (! -d $git_temp) { our $action = $cgi->param('a'); if (defined $action) { if ($action =~ m/[^0-9a-zA-Z\.\-_]/) { - undef $action; die_error(undef, "Invalid action parameter."); } # action which does not check rest of parameters @@ -89,16 +88,13 @@ if (defined $action) { our $project = ($cgi->param('p') || $ENV{'PATH_INFO'}); if (defined $project) { $project =~ s|^/||; $project =~ s|/$||; - $project = validate_input($project); - if (!defined($project)) { + if (!validate_input($project)) { die_error(undef, "Invalid project parameter."); } if (!(-d "$projectroot/$project")) { - undef $project; die_error(undef, "No such directory."); } if (!(-e "$projectroot/$project/HEAD")) { - undef $project; die_error(undef, "No such project."); } $rss_link = "param('f'); if (defined $file_name) { - $file_name = validate_input($file_name); - if (!defined($file_name)) { + if (!validate_input($file_name)) { die_error(undef, "Invalid file parameter."); } } our $hash = $cgi->param('h'); if (defined $hash) { - $hash = validate_input($hash); - if (!defined($hash)) { + if (!validate_input($hash)) { die_error(undef, "Invalid hash parameter."); } } our $hash_parent = $cgi->param('hp'); if (defined $hash_parent) { - $hash_parent = validate_input($hash_parent); - if (!defined($hash_parent)) { + if (!validate_input($hash_parent)) { die_error(undef, "Invalid hash parent parameter."); } } our $hash_base = $cgi->param('hb'); if (defined $hash_base) { - $hash_base = validate_input($hash_base); - if (!defined($hash_base)) { + if (!validate_input($hash_base)) { die_error(undef, "Invalid hash base parameter."); } } @@ -144,7 +136,6 @@ if (defined $hash_base) { our $page = $cgi->param('pg'); if (defined $page) { if ($page =~ m/[^0-9]$/) { - undef $page; die_error(undef, "Invalid page parameter."); } } @@ -152,7 +143,6 @@ if (defined $page) { our $searchtext = $cgi->param('s'); if (defined $searchtext) { if ($searchtext =~ m/[^a-zA-Z0-9_\.\/\-\+\:\@ ]/) { - undef $searchtext; die_error(undef, "Invalid search parameter."); } $searchtext = quotemeta $searchtext; @@ -182,7 +172,6 @@ my %actions = ( $action = 'summary' if (!defined($action)); if (!defined($actions{$action})) { - undef $action; die_error(undef, "Unknown action."); } $actions{$action}->(); From e484a2d6ad26ff7a6ebe84085dda00591476014e Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sat, 5 Aug 2006 13:12:51 +0200 Subject: [PATCH 065/160] gitweb: Cleanup and uniquify error messages Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 89ceb9765d..16e838fc6d 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -1464,7 +1464,7 @@ sub git_blame2 { die_error(undef, "Permission denied.") if (!git_get_project_config_bool ('blame')); die_error('404 Not Found', "File name not defined") if (!$file_name); $hash_base ||= git_read_head($project); - die_error(undef, "Reading commit failed") unless ($hash_base); + die_error(undef, "Couldn't find base commit.") unless ($hash_base); my %co = git_read_commit($hash_base) or die_error(undef, "Reading commit failed"); if (!defined $hash) { @@ -1473,7 +1473,7 @@ sub git_blame2 { } $ftype = git_get_type($hash); if ($ftype !~ "blob") { - die_error("400 Bad Request", "object is not a blob"); + die_error("400 Bad Request", "Object is not a blob"); } open ($fd, "-|", $GIT, "blame", '-l', $file_name, $hash_base) or die_error(undef, "Open git-blame failed."); @@ -1520,9 +1520,9 @@ sub git_blame2 { sub git_blame { my $fd; die_error('403 Permission denied', "Permission denied.") if (!git_get_project_config_bool ('blame')); - die_error('404 Not Found', "What file will it be, master?") if (!$file_name); + die_error('404 Not Found', "File name not defined.") if (!$file_name); $hash_base ||= git_read_head($project); - die_error(undef, "Reading commit failed.") unless ($hash_base); + die_error(undef, "Couldn't find base commit.") unless ($hash_base); my %co = git_read_commit($hash_base) or die_error(undef, "Reading commit failed."); if (!defined $hash) { @@ -2116,7 +2116,7 @@ sub git_commitdiff { open my $fd, "-|", $GIT, "diff-tree", '-r', $hash_parent, $hash or die_error(undef, "Open git-diff-tree failed."); my @difftree = map { chomp; $_ } <$fd>; - close $fd or die_error(undef, "Reading diff-tree failed."); + close $fd or die_error(undef, "Reading git-diff-tree failed."); # non-textual hash id's can be cached my $expires; @@ -2487,7 +2487,7 @@ sub git_rss { open my $fd, "-|", $GIT, "rev-list", "--max-count=150", git_read_head($project) or die_error(undef, "Open git-rev-list failed."); my @revlist = map { chomp; $_ } <$fd>; - close $fd or die_error(undef, "Reading rev-list failed."); + close $fd or die_error(undef, "Reading git-rev-list failed."); print $cgi->header(-type => 'text/xml', -charset => 'utf-8'); print "\n". "\n"; From cac4bd94fb6d5f3066614051827669476a9f0b56 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sat, 5 Aug 2006 13:13:53 +0200 Subject: [PATCH 066/160] gitweb: No periods for error messages Signed-off-by: Jakub Narebski Acked-by: Luben Tuikov Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 92 +++++++++++++++++++++++----------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 16e838fc6d..6284901457 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -76,7 +76,7 @@ if (! -d $git_temp) { our $action = $cgi->param('a'); if (defined $action) { if ($action =~ m/[^0-9a-zA-Z\.\-_]/) { - die_error(undef, "Invalid action parameter."); + die_error(undef, "Invalid action parameter"); } # action which does not check rest of parameters if ($action eq "opml") { @@ -89,13 +89,13 @@ our $project = ($cgi->param('p') || $ENV{'PATH_INFO'}); if (defined $project) { $project =~ s|^/||; $project =~ s|/$||; if (!validate_input($project)) { - die_error(undef, "Invalid project parameter."); + die_error(undef, "Invalid project parameter"); } if (!(-d "$projectroot/$project")) { - die_error(undef, "No such directory."); + die_error(undef, "No such directory"); } if (!(-e "$projectroot/$project/HEAD")) { - die_error(undef, "No such project."); + die_error(undef, "No such project"); } $rss_link = ""; @@ -108,42 +108,42 @@ if (defined $project) { our $file_name = $cgi->param('f'); if (defined $file_name) { if (!validate_input($file_name)) { - die_error(undef, "Invalid file parameter."); + die_error(undef, "Invalid file parameter"); } } our $hash = $cgi->param('h'); if (defined $hash) { if (!validate_input($hash)) { - die_error(undef, "Invalid hash parameter."); + die_error(undef, "Invalid hash parameter"); } } our $hash_parent = $cgi->param('hp'); if (defined $hash_parent) { if (!validate_input($hash_parent)) { - die_error(undef, "Invalid hash parent parameter."); + die_error(undef, "Invalid hash parent parameter"); } } our $hash_base = $cgi->param('hb'); if (defined $hash_base) { if (!validate_input($hash_base)) { - die_error(undef, "Invalid hash base parameter."); + die_error(undef, "Invalid hash base parameter"); } } our $page = $cgi->param('pg'); if (defined $page) { if ($page =~ m/[^0-9]$/) { - die_error(undef, "Invalid page parameter."); + die_error(undef, "Invalid page parameter"); } } our $searchtext = $cgi->param('s'); if (defined $searchtext) { if ($searchtext =~ m/[^a-zA-Z0-9_\.\/\-\+\:\@ ]/) { - die_error(undef, "Invalid search parameter."); + die_error(undef, "Invalid search parameter"); } $searchtext = quotemeta $searchtext; } @@ -172,7 +172,7 @@ my %actions = ( $action = 'summary' if (!defined($action)); if (!defined($actions{$action})) { - die_error(undef, "Unknown action."); + die_error(undef, "Unknown action"); } $actions{$action}->(); exit; @@ -418,7 +418,7 @@ sub git_get_hash_by_path { my $tree = $base; open my $fd, "-|", $GIT, "ls-tree", $base, "--", $path - or die_error(undef, "Open git-ls-tree failed."); + or die_error(undef, "Open git-ls-tree failed"); my $line = <$fd>; close $fd or return undef; @@ -1265,13 +1265,13 @@ sub git_diff_print { sub git_project_list { my $order = $cgi->param('o'); if (defined $order && $order !~ m/project|descr|owner|age/) { - die_error(undef, "Invalid order parameter '$order'."); + die_error(undef, "Invalid order parameter '$order'"); } my @list = git_read_projects(); my @projects; if (!@list) { - die_error(undef, "No projects found."); + die_error(undef, "No projects found"); } foreach my $pr (@list) { my $head = git_read_head($pr->{'path'}); @@ -1405,7 +1405,7 @@ sub git_summary { "
Project" . $cgi->a({-class => "header", -href => "$my_uri?" . esc_param("o=project")}, "Project") . "" . + $cgi->a({-href => "$my_uri?" . esc_param("o=project"), + -class => "header"}, "Project") . + "Description" . $cgi->a({-class => "header", -href => "$my_uri?" . esc_param("o=descr")}, "Description") . "" . + $cgi->a({-href => "$my_uri?" . esc_param("o=descr"), + -class => "header"}, "Description") . + "Owner" . $cgi->a({-class => "header", -href => "$my_uri?" . esc_param("o=owner")}, "Owner") . "" . + $cgi->a({-href => "$my_uri?" . esc_param("o=owner"), + -class => "header"}, "Owner") . + "Last Change" . $cgi->a({-class => "header", -href => "$my_uri?" . esc_param("o=age")}, "Last Change") . "" . + $cgi->a({-href => "$my_uri?" . esc_param("o=age"), + -class => "header"}, "Last Change") . + "
" . $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=summary"), -class => "list"}, esc_html($pr->{'path'})) . "" . $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=summary"), + -class => "list"}, esc_html($pr->{'path'})) . "" . esc_html($pr->{'descr'}) . "" . chop_str($pr->{'owner'}, 15) . "{'commit'}{'age'}) . "\">" . $pr->{'commit'}{'age_string'} . "{'commit'}{'age'}) . "\">" . + $pr->{'commit'}{'age_string'} . "" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=summary")}, "summary") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=shortlog")}, "shortlog") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=log")}, "log") . + $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=summary")}, "summary") . " | " . + $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=shortlog")}, "shortlog") . " | " . + $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=log")}, "log") . "
" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$t_hash$base_key;f=$base$t_name")}, "blob") . -# " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;h=$t_hash$base_key;f=$base$t_name")}, "blame") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;h=$t_hash;hb=$hash_base;f=$base$t_name")}, "history") . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$t_hash$base_key;f=$base$t_name")}, "blob"); + if ($have_blame) { + print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;h=$t_hash$base_key;f=$base$t_name")}, "blame"); + } + print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;h=$t_hash;hb=$hash_base;f=$base$t_name")}, "history") . " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;h=$t_hash;f=$base$t_name")}, "raw") . "
\n"; open my $fd, "-|", $GIT, "rev-list", "--max-count=17", git_read_head($project) - or die_error(undef, "Open git-rev-list failed."); + or die_error(undef, "Open git-rev-list failed"); my @revlist = map { chomp; $_ } <$fd>; close $fd; git_header_div('shortlog'); @@ -1461,10 +1461,10 @@ sub git_tag { sub git_blame2 { my $fd; my $ftype; - die_error(undef, "Permission denied.") if (!git_get_project_config_bool ('blame')); + die_error(undef, "Permission denied") if (!git_get_project_config_bool ('blame')); die_error('404 Not Found', "File name not defined") if (!$file_name); $hash_base ||= git_read_head($project); - die_error(undef, "Couldn't find base commit.") unless ($hash_base); + die_error(undef, "Couldn't find base commit") unless ($hash_base); my %co = git_read_commit($hash_base) or die_error(undef, "Reading commit failed"); if (!defined $hash) { @@ -1476,7 +1476,7 @@ sub git_blame2 { die_error("400 Bad Request", "Object is not a blob"); } open ($fd, "-|", $GIT, "blame", '-l', $file_name, $hash_base) - or die_error(undef, "Open git-blame failed."); + or die_error(undef, "Open git-blame failed"); git_header_html(); my $formats_nav = $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$hash;hb=$hash_base;f=$file_name")}, "blob") . @@ -1519,18 +1519,18 @@ sub git_blame2 { sub git_blame { my $fd; - die_error('403 Permission denied', "Permission denied.") if (!git_get_project_config_bool ('blame')); - die_error('404 Not Found', "File name not defined.") if (!$file_name); + die_error('403 Permission denied', "Permission denied") if (!git_get_project_config_bool ('blame')); + die_error('404 Not Found', "File name not defined") if (!$file_name); $hash_base ||= git_read_head($project); - die_error(undef, "Couldn't find base commit.") unless ($hash_base); + die_error(undef, "Couldn't find base commit") unless ($hash_base); my %co = git_read_commit($hash_base) - or die_error(undef, "Reading commit failed."); + or die_error(undef, "Reading commit failed"); if (!defined $hash) { $hash = git_get_hash_by_path($hash_base, $file_name, "blob") - or die_error(undef, "Error lookup file."); + or die_error(undef, "Error lookup file"); } open ($fd, "-|", $GIT, "annotate", '-l', '-t', '-r', $file_name, $hash_base) - or die_error(undef, "Open git-annotate failed."); + or die_error(undef, "Open git-annotate failed"); git_header_html(); my $formats_nav = $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$hash;hb=$hash_base;f=$file_name")}, "blob") . @@ -1640,9 +1640,9 @@ sub git_blob_plain { if (defined $file_name) { my $base = $hash_base || git_read_head($project); $hash = git_get_hash_by_path($base, $file_name, "blob") - or die_error(undef, "Error lookup file."); + or die_error(undef, "Error lookup file"); } else { - die_error(undef, "No file name defined."); + die_error(undef, "No file name defined"); } } my $type = shift; @@ -1673,14 +1673,14 @@ sub git_blob { if (defined $file_name) { my $base = $hash_base || git_read_head($project); $hash = git_get_hash_by_path($base, $file_name, "blob") - or die_error(undef, "Error lookup file."); + or die_error(undef, "Error lookup file"); } else { - die_error(undef, "No file name defined."); + die_error(undef, "No file name defined"); } } my $have_blame = git_get_project_config_bool ('blame'); open my $fd, "-|", $GIT, "cat-file", "blob", $hash - or die_error(undef, "Couldn't cat $file_name, $hash."); + or die_error(undef, "Couldn't cat $file_name, $hash"); my $mimetype = git_blob_plain_mimetype($fd, $file_name); if ($mimetype !~ m/^text\//) { close $fd; @@ -1738,9 +1738,9 @@ sub git_tree { } $/ = "\0"; open my $fd, "-|", $GIT, "ls-tree", '-z', $hash - or die_error(undef, "Open git-ls-tree failed."); + or die_error(undef, "Open git-ls-tree failed"); my @entries = map { chomp; $_ } <$fd>; - close $fd or die_error(undef, "Reading tree failed."); + close $fd or die_error(undef, "Reading tree failed"); $/ = "\n"; my $refs = read_info_ref(); @@ -1819,7 +1819,7 @@ sub git_log { my $limit = sprintf("--max-count=%i", (100 * ($page+1))); open my $fd, "-|", $GIT, "rev-list", $limit, $hash - or die_error(undef, "Open git-rev-list failed."); + or die_error(undef, "Open git-rev-list failed"); my @revlist = map { chomp; $_ } <$fd>; close $fd; @@ -1880,7 +1880,7 @@ sub git_log { sub git_commit { my %co = git_read_commit($hash); if (!%co) { - die_error(undef, "Unknown commit object."); + die_error(undef, "Unknown commit object"); } my %ad = date_str($co{'author_epoch'}, $co{'author_tz'}); my %cd = date_str($co{'committer_epoch'}, $co{'committer_tz'}); @@ -1890,9 +1890,9 @@ sub git_commit { $parent = "--root"; } open my $fd, "-|", $GIT, "diff-tree", '-r', '-M', $parent, $hash - or die_error(undef, "Open git-diff-tree failed."); + or die_error(undef, "Open git-diff-tree failed"); my @difftree = map { chomp; $_ } <$fd>; - close $fd or die_error(undef, "Reading git-diff-tree failed."); + close $fd or die_error(undef, "Reading git-diff-tree failed"); # non-textual hash id's can be cached my $expires; @@ -2108,15 +2108,15 @@ sub git_commitdiff { mkdir($git_temp, 0700); my %co = git_read_commit($hash); if (!%co) { - die_error(undef, "Unknown commit object."); + die_error(undef, "Unknown commit object"); } if (!defined $hash_parent) { $hash_parent = $co{'parent'}; } open my $fd, "-|", $GIT, "diff-tree", '-r', $hash_parent, $hash - or die_error(undef, "Open git-diff-tree failed."); + or die_error(undef, "Open git-diff-tree failed"); my @difftree = map { chomp; $_ } <$fd>; - close $fd or die_error(undef, "Reading git-diff-tree failed."); + close $fd or die_error(undef, "Reading git-diff-tree failed"); # non-textual hash id's can be cached my $expires; @@ -2194,9 +2194,9 @@ sub git_commitdiff { sub git_commitdiff_plain { mkdir($git_temp, 0700); open my $fd, "-|", $GIT, "diff-tree", '-r', $hash_parent, $hash - or die_error(undef, "Open git-diff-tree failed."); + or die_error(undef, "Open git-diff-tree failed"); my @difftree = map { chomp; $_ } <$fd>; - close $fd or die_error(undef, "Reading diff-tree failed."); + close $fd or die_error(undef, "Reading diff-tree failed"); # try to figure out the next tag after this commit my $tagname; @@ -2254,7 +2254,7 @@ sub git_history { my $ftype; my %co = git_read_commit($hash_base); if (!%co) { - die_error(undef, "Unknown commit object."); + die_error(undef, "Unknown commit object"); } my $refs = read_info_ref(); git_header_html(); @@ -2312,14 +2312,14 @@ sub git_history { sub git_search { if (!defined $searchtext) { - die_error(undef, "Text field empty."); + die_error(undef, "Text field empty"); } if (!defined $hash) { $hash = git_read_head($project); } my %co = git_read_commit($hash); if (!%co) { - die_error(undef, "Unknown commit object."); + die_error(undef, "Unknown commit object"); } # pickaxe may take all resources of your box and run for several minutes # with every query - so decide by yourself how public you make this feature :) @@ -2457,7 +2457,7 @@ sub git_shortlog { my $limit = sprintf("--max-count=%i", (100 * ($page+1))); open my $fd, "-|", $GIT, "rev-list", $limit, $hash - or die_error(undef, "Open git-rev-list failed."); + or die_error(undef, "Open git-rev-list failed"); my @revlist = map { chomp; $_ } <$fd>; close $fd; @@ -2485,9 +2485,9 @@ sub git_shortlog { sub git_rss { # http://www.notestips.com/80256B3A007F2692/1/NAMO5P9UPQ open my $fd, "-|", $GIT, "rev-list", "--max-count=150", git_read_head($project) - or die_error(undef, "Open git-rev-list failed."); + or die_error(undef, "Open git-rev-list failed"); my @revlist = map { chomp; $_ } <$fd>; - close $fd or die_error(undef, "Reading git-rev-list failed."); + close $fd or die_error(undef, "Reading git-rev-list failed"); print $cgi->header(-type => 'text/xml', -charset => 'utf-8'); print "\n". "\n"; From e2860ead31579a15ee94831f2b9b55e43caa2cac Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sat, 5 Aug 2006 13:15:24 +0200 Subject: [PATCH 067/160] gitweb: No error messages with unescaped/unprotected user input Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 6284901457..2e2629ca53 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -1265,7 +1265,7 @@ sub git_diff_print { sub git_project_list { my $order = $cgi->param('o'); if (defined $order && $order !~ m/project|descr|owner|age/) { - die_error(undef, "Invalid order parameter '$order'"); + die_error(undef, "Unknown order parameter"); } my @list = git_read_projects(); From 668e34d7cc1ab7d6135f0004ee7bea2ffdca0de0 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sat, 5 Aug 2006 13:16:03 +0200 Subject: [PATCH 068/160] gitweb: PATH_INFO=/ means no project Prepared for refactoring input validation. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 2e2629ca53..fdba15e2b2 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -86,8 +86,8 @@ if (defined $action) { } our $project = ($cgi->param('p') || $ENV{'PATH_INFO'}); -if (defined $project) { - $project =~ s|^/||; $project =~ s|/$||; +$project =~ s|^/||; $project =~ s|/$||; +if (defined $project && $project) { if (!validate_input($project)) { die_error(undef, "Invalid project parameter"); } From 10161355ba3b121c823649ef1acca526d73363f6 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sat, 5 Aug 2006 13:18:58 +0200 Subject: [PATCH 069/160] gitweb: Inline $rss_link Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index fdba15e2b2..1b5fec924f 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -21,7 +21,6 @@ our $cgi = new CGI; our $version = "++GIT_VERSION++"; our $my_url = $cgi->url(); our $my_uri = $cgi->url(-absolute => 1); -our $rss_link = ""; # core git executable to use # this can just be "git" if your webserver has a sensible PATH @@ -97,8 +96,6 @@ if (defined $project && $project) { if (!(-e "$projectroot/$project/HEAD")) { die_error(undef, "No such project"); } - $rss_link = ""; $ENV{'GIT_DIR'} = "$projectroot/$project"; } else { git_project_list(); @@ -862,11 +859,13 @@ sub git_header_html { $title -$rss_link - - EOF - print "
\n" . + print "\n" . + "\n"; + + print "\n" . + "
\n" . "" . "\"git\"" . "\n"; From f16db173a4680aebc2f14c103a1e125c3f4d4531 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sun, 6 Aug 2006 02:08:31 +0200 Subject: [PATCH 070/160] gitweb: Refactor untabifying - converting tabs to spaces Add untabify subroutine and use it. It also fixes git_diff_print which used to get the tabstop wrong. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 1b5fec924f..d0672cde3e 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -221,6 +221,20 @@ sub unquote { return $str; } +# escape tabs (convert tabs to spaces) +sub untabify { + my $line = shift; + + while ((my $pos = index($line, "\t")) != -1) { + if (my $count = (8 - ($pos % 8))) { + my $spaces = ' ' x $count; + $line =~ s/\t/$spaces/; + } + } + + return $line; +} + ## ---------------------------------------------------------------------- ## HTML aware string manipulation @@ -1237,12 +1251,7 @@ sub git_diff_print { # skip errors next; } - while ((my $pos = index($line, "\t")) != -1) { - if (my $count = (8 - (($pos-1) % 8))) { - my $spaces = ' ' x $count; - $line =~ s/\t/$spaces/; - } - } + $line = untabify($line); print "
" . esc_html($line) . "
\n"; } } @@ -1582,13 +1591,8 @@ HTML $age_class = age_class($age); $author = esc_html ($author); $author =~ s/ / /g; - # escape tabs - while ((my $pos = index($data, "\t")) != -1) { - if (my $count = (8 - ($pos % 8))) { - my $spaces = ' ' x $count; - $data =~ s/\t/$spaces/; - } - } + + $data = untabify($data); $data = esc_html ($data); print <) { chomp $line; $nr++; - while ((my $pos = index($line, "\t")) != -1) { - if (my $count = (8 - ($pos % 8))) { - my $spaces = ' ' x $count; - $line =~ s/\t/$spaces/; - } - } + $line = untabify($line); printf "
%4i %s
\n", $nr, $nr, $nr, esc_html($line); } close $fd or print "Reading blob failed.\n"; From 403ccc4f36101ca5084e659a8c3c9911ccc91de8 Mon Sep 17 00:00:00 2001 From: Matthias Kestenholz Date: Sun, 6 Aug 2006 12:47:33 +0200 Subject: [PATCH 071/160] Add gitweb.cgi to .gitignore Signed-off-by: Matthias Kestenholz Signed-off-by: Junio C Hamano --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index fb0fa3f16a..20df1f8b2f 100644 --- a/.gitignore +++ b/.gitignore @@ -125,6 +125,7 @@ git-verify-tag git-whatchanged git-write-tree git-core-*/?* +gitweb/gitweb.cgi test-date test-delta test-dump-cache-tree From bd943f4757ab1d62d862ea12b4cf8b6b495e115f Mon Sep 17 00:00:00 2001 From: Matthias Lederhofer Date: Sun, 6 Aug 2006 15:55:02 +0200 Subject: [PATCH 072/160] gitweb: check if HTTP_ACCEPT is really set Signed-off-by: Matthias Lederhofer Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index d0672cde3e..5e72b4f617 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -856,7 +856,7 @@ sub git_header_html { # 'application/xhtml+xml', otherwise send it as plain old 'text/html'. # we have to do this because MSIE sometimes globs '*/*', pretending to # support xhtml+xml but choking when it gets what it asked for. - if ($cgi->http('HTTP_ACCEPT') =~ m/(,|;|\s|^)application\/xhtml\+xml(,|;|\s|$)/ && $cgi->Accept('application/xhtml+xml') != 0) { + if (defined $cgi->http('HTTP_ACCEPT') && $cgi->http('HTTP_ACCEPT') =~ m/(,|;|\s|^)application\/xhtml\+xml(,|;|\s|$)/ && $cgi->Accept('application/xhtml+xml') != 0) { $content_type = 'application/xhtml+xml'; } else { $content_type = 'text/html'; From b5ff2cf9a6a4246a5443e904acf3165e89654b1e Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sun, 6 Aug 2006 16:14:25 +0200 Subject: [PATCH 073/160] gitweb: fix commitdiff for root commits After changing all "-|" open invocations to list form, commitdiff for initial commit (without parent) got broken; it returned incorrectly empty patch earlier. Use '--root' option to git-diff-tree for initial (root) commit. No checking for empty $hash_parent in git_commitdiff_plain -- we rely on gitweb to give correct parameters for commitdiff_plain action. Noticed by Matthias Lederhofer (matled). Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 5e72b4f617..9be35aebd1 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -2109,7 +2109,7 @@ sub git_commitdiff { die_error(undef, "Unknown commit object"); } if (!defined $hash_parent) { - $hash_parent = $co{'parent'}; + $hash_parent = $co{'parent'} || '--root'; } open my $fd, "-|", $GIT, "diff-tree", '-r', $hash_parent, $hash or die_error(undef, "Open git-diff-tree failed"); From e349d21ab47ae4a3753749c4579cce150c71c768 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sun, 6 Aug 2006 17:59:52 +0200 Subject: [PATCH 074/160] gitweb: Skip nonmatching lines in difftree output, consistently This fixes error for commitdiff on root commit (without parents). Noticed-by: Matthias Lederhofer (matled) Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 9be35aebd1..b8e266e0d9 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -1983,7 +1983,7 @@ sub git_commit { foreach my $line (@difftree) { # ':100644 100644 03b218260e99b78c6df0ed378e59ed9205ccc96d 3b93d5e7cc7f7dd4ebed13a5cc1a4ad976fc94d8 M ls-files.c' # ':100644 100644 7f9281985086971d3877aca27704f2aaf9c448ce bc190ebc71bbd923f2b728e505408f5e54bd073a M rev-tree.c' - if (!($line =~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)([0-9]{0,3})\t(.*)$/)) { + if ($line !~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)([0-9]{0,3})\t(.*)$/) { next; } my $from_mode = $1; @@ -2156,7 +2156,9 @@ sub git_commitdiff { foreach my $line (@difftree) { # ':100644 100644 03b218260e99b78c6df0ed378e59ed9205ccc96d 3b93d5e7cc7f7dd4ebed13a5cc1a4ad976fc94d8 M ls-files.c' # ':100644 100644 7f9281985086971d3877aca27704f2aaf9c448ce bc190ebc71bbd923f2b728e505408f5e54bd073a M rev-tree.c' - $line =~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)\t(.*)$/; + if ($line !~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)\t(.*)$/) { + next; + } my $from_mode = $1; my $to_mode = $2; my $from_id = $3; @@ -2230,7 +2232,9 @@ sub git_commitdiff_plain { print "---\n\n"; foreach my $line (@difftree) { - $line =~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)\t(.*)$/; + if ($line !~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)\t(.*)$/) { + next; + } my $from_id = $3; my $to_id = $4; my $status = $5; From 1568515d5b8350a6087c0976c841387d71075c01 Mon Sep 17 00:00:00 2001 From: Matthias Lederhofer Date: Sun, 6 Aug 2006 19:24:47 +0200 Subject: [PATCH 075/160] gitweb: fix commitdiff_plain for root commits Signed-off-by: Matthias Lederhofer Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index b8e266e0d9..08de2ce77e 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -2193,6 +2193,13 @@ sub git_commitdiff { sub git_commitdiff_plain { mkdir($git_temp, 0700); + my %co = git_read_commit($hash); + if (!%co) { + die_error(undef, "Unknown commit object"); + } + if (!defined $hash_parent) { + $hash_parent = $co{'parent'} || '--root'; + } open my $fd, "-|", $GIT, "diff-tree", '-r', $hash_parent, $hash or die_error(undef, "Open git-diff-tree failed"); my @difftree = map { chomp; $_ } <$fd>; @@ -2214,7 +2221,6 @@ sub git_commitdiff_plain { } print $cgi->header(-type => "text/plain", -charset => 'utf-8', '-content-disposition' => "inline; filename=\"git-$hash.patch\""); - my %co = git_read_commit($hash); my %ad = date_str($co{'author_epoch'}, $co{'author_tz'}); my $comment = $co{'comment'}; print "From: $co{'author'}\n" . From dd04c428cfea1d9dd7684bbd9e2919fbad051b26 Mon Sep 17 00:00:00 2001 From: Matthias Lederhofer Date: Sun, 6 Aug 2006 13:25:41 +0200 Subject: [PATCH 076/160] gitweb: fix $project usage There were some places where $project was used even if it was not defined. Signed-off-by: Matthias Lederhofer Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 08de2ce77e..b3bfc6bd9e 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -85,7 +85,10 @@ if (defined $action) { } our $project = ($cgi->param('p') || $ENV{'PATH_INFO'}); -$project =~ s|^/||; $project =~ s|/$||; +if (defined $project) { + $project =~ s|^/||; + $project =~ s|/$||; +} if (defined $project && $project) { if (!validate_input($project)) { die_error(undef, "Invalid project parameter"); @@ -874,11 +877,15 @@ sub git_header_html { $title EOF - print "\n" . - "\n"; + if (defined $project) { + printf(''."\n", + esc_param($project), + esc_param("$my_uri?p=$project;a=rss")); + } - print "\n" . + print "\n" . + "\n" . "
\n" . "" . "\"git\"" . From d5c31a1ccfa1195cff160bbad995c68037180570 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Fri, 4 Aug 2006 23:43:59 +0200 Subject: [PATCH 077/160] autoconf: Unset NO_STH and NEED_STH when it is detected not needed When configure detects some NO_XXX or NEEDS_XXX is unneeded, unset this variable (actually set it to empty string). This allow autodetection to override the default set in Makefile. [jc: while at it fixed a thinko in IPv6 detection.] Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- configure.ac | 47 +++++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/configure.ac b/configure.ac index 74c271098c..3c56cc51ac 100644 --- a/configure.ac +++ b/configure.ac @@ -154,31 +154,36 @@ AC_MSG_NOTICE([CHECKS for libraries]) # # Define NO_OPENSSL environment variable if you do not have OpenSSL. # Define NEEDS_SSL_WITH_CRYPTO if you need -lcrypto with -lssl (Darwin). -AC_CHECK_LIB([crypto], [SHA1_Init],[], +AC_CHECK_LIB([crypto], [SHA1_Init], +[GIT_CONF_APPEND_LINE(NEEDS_SSL_WITH_CRYPTO=)], [AC_CHECK_LIB([ssl], [SHA1_Init], - [GIT_CONF_APPEND_LINE(NEEDS_SSL_WITH_CRYPTO=YesPlease)], + [GIT_CONF_APPEND_LINE(NEEDS_SSL_WITH_CRYPTO=YesPlease) + GIT_CONF_APPEND_LINE(NEEDS_SSL_WITH_CRYPTO=)], [GIT_CONF_APPEND_LINE(NO_OPENSSL=YesPlease)])]) # # Define NO_CURL if you do not have curl installed. git-http-pull and # git-http-push are not built, and you cannot use http:// and https:// # transports. -AC_CHECK_LIB([curl], [curl_global_init],[], +AC_CHECK_LIB([curl], [curl_global_init], +[GIT_CONF_APPEND_LINE(NO_CURL=)], [GIT_CONF_APPEND_LINE(NO_CURL=YesPlease)]) # # Define NO_EXPAT if you do not have expat installed. git-http-push is # not built, and you cannot push using http:// and https:// transports. -AC_CHECK_LIB([expat], [XML_ParserCreate],[], +AC_CHECK_LIB([expat], [XML_ParserCreate], +[GIT_CONF_APPEND_LINE(NO_EXPAT=)], [GIT_CONF_APPEND_LINE(NO_EXPAT=YesPlease)]) # # Define NEEDS_LIBICONV if linking with libc is not enough (Darwin). -AC_CHECK_LIB([c], [iconv],[], +AC_CHECK_LIB([c], [iconv], +[GIT_CONF_APPEND_LINE(NEEDS_LIBICONV=)], [GIT_CONF_APPEND_LINE(NEEDS_LIBICONV=YesPlease)]) # # Define NEEDS_SOCKET if linking with libc is not enough (SunOS, # Patrick Mauritz). -AC_CHECK_LIB([c], [socket],[], -[AC_CHECK_LIB([socket],[socket], - [GIT_CONF_APPEND_LINE(NEEDS_SOCKET=YesPlease)],[])]) +AC_CHECK_LIB([c], [socket], +[GIT_CONF_APPEND_LINE(NEEDS_SOCKET=)], +[GIT_CONF_APPEND_LINE(NEEDS_SOCKET=YesPlease)]) ## Checks for header files. @@ -188,25 +193,30 @@ AC_CHECK_LIB([c], [socket],[], AC_MSG_NOTICE([CHECKS for typedefs, structures, and compiler characteristics]) # # Define NO_D_INO_IN_DIRENT if you don't have d_ino in your struct dirent. -AC_CHECK_MEMBER(struct dirent.d_ino,[], +AC_CHECK_MEMBER(struct dirent.d_ino, +[GIT_CONF_APPEND_LINE(NO_D_INO_IN_DIRENT=)], [GIT_CONF_APPEND_LINE(NO_D_INO_IN_DIRENT=YesPlease)], [#include ]) # # Define NO_D_TYPE_IN_DIRENT if your platform defines DT_UNKNOWN but lacks # d_type in struct dirent (latest Cygwin -- will be fixed soonish). -AC_CHECK_MEMBER(struct dirent.d_type,[], +AC_CHECK_MEMBER(struct dirent.d_type, +[GIT_CONF_APPEND_LINE(NO_D_TYPE_IN_DIRENT=)], [GIT_CONF_APPEND_LINE(NO_D_TYPE_IN_DIRENT=YesPlease)], [#include ]) # # Define NO_SOCKADDR_STORAGE if your platform does not have struct # sockaddr_storage. -AC_CHECK_TYPE(struct sockaddr_storage,[], +AC_CHECK_TYPE(struct sockaddr_storage, +[GIT_CONF_APPEND_LINE(NO_SOCKADDR_STORAGE=)], [GIT_CONF_APPEND_LINE(NO_SOCKADDR_STORAGE=YesPlease)], [#include ]) # Define NO_IPV6 if you lack IPv6 support and getaddrinfo(). AC_CHECK_TYPE([struct addrinfo],[ -AC_CHECK_FUNC([getaddrinfo],[], -[GIT_CONF_APPEND_LINE(NO_IPV6=YesPlease)])],[],[ + AC_CHECK_FUNC([getaddrinfo], + [GIT_CONF_APPEND_LINE(NO_IPV6=)], + [GIT_CONF_APPEND_LINE(NO_IPV6=YesPlease)]) +],[GIT_CONF_APPEND_LINE(NO_IPV6=YesPlease)],[ #include #include #include @@ -231,6 +241,8 @@ AC_RUN_IFELSE( ]) if test $ac_cv_c_c99_format = no; then GIT_CONF_APPEND_LINE(NO_C99_FORMAT=YesPlease) +else + GIT_CONF_APPEND_LINE(NO_C99_FORMAT=) fi @@ -239,15 +251,18 @@ fi AC_MSG_NOTICE([CHECKS for library functions]) # # Define NO_STRCASESTR if you don't have strcasestr. -AC_CHECK_FUNC(strcasestr,[], +AC_CHECK_FUNC(strcasestr, +[GIT_CONF_APPEND_LINE(NO_STRCASESTR=)], [GIT_CONF_APPEND_LINE(NO_STRCASESTR=YesPlease)]) # # Define NO_STRLCPY if you don't have strlcpy. -AC_CHECK_FUNC(strlcpy,[], +AC_CHECK_FUNC(strlcpy, +[GIT_CONF_APPEND_LINE(NO_STRLCPY=)], [GIT_CONF_APPEND_LINE(NO_STRLCPY=YesPlease)]) # # Define NO_SETENV if you don't have setenv in the C library. -AC_CHECK_FUNC(setenv,[], +AC_CHECK_FUNC(setenv, +[GIT_CONF_APPEND_LINE(NO_SETENV=)], [GIT_CONF_APPEND_LINE(NO_SETENV=YesPlease)]) # # Define NO_MMAP if you want to avoid mmap. From b7e58b17b50bbbf00299fc89c480efd7cc92c1bd Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 5 Aug 2006 04:16:02 -0700 Subject: [PATCH 078/160] Racy git: avoid having to be always too careful Immediately after a bulk checkout, most of the paths in the working tree would have the same timestamp as the index file, and this would force ce_match_stat() to take slow path for all of them. When writing an index file out, if many of the paths have very new (read: the same timestamp as the index file being written out) timestamp, we are better off delaying the return from the command, to make sure that later command to touch the working tree files will leave newer timestamps than recorded in the index, thereby avoiding to take the slow path. Signed-off-by: Junio C Hamano --- read-cache.c | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/read-cache.c b/read-cache.c index f92cdaacee..ce76c20f34 100644 --- a/read-cache.c +++ b/read-cache.c @@ -5,6 +5,7 @@ */ #include "cache.h" #include "cache-tree.h" +#include /* Index extensions. * @@ -923,7 +924,7 @@ static void ce_smudge_racily_clean_entry(struct cache_entry *ce) * $ echo filfre >nitfol * $ git-update-index --add nitfol * - * but it does not. Whe the second update-index runs, + * but it does not. When the second update-index runs, * it notices that the entry "frotz" has the same timestamp * as index, and if we were to smudge it by resetting its * size to zero here, then the object name recorded @@ -945,7 +946,9 @@ int write_cache(int newfd, struct cache_entry **cache, int entries) { SHA_CTX c; struct cache_header hdr; - int i, removed; + int i, removed, recent; + struct stat st; + time_t now; for (i = removed = 0; i < entries; i++) if (!cache[i]->ce_mode) @@ -959,15 +962,19 @@ int write_cache(int newfd, struct cache_entry **cache, int entries) if (ce_write(&c, newfd, &hdr, sizeof(hdr)) < 0) return -1; + now = fstat(newfd, &st) ? 0 : st.st_mtime; + recent = 0; for (i = 0; i < entries; i++) { struct cache_entry *ce = cache[i]; + time_t entry_time = (time_t) ntohl(ce->ce_mtime.sec); if (!ce->ce_mode) continue; - if (index_file_timestamp && - index_file_timestamp <= ntohl(ce->ce_mtime.sec)) + if (index_file_timestamp && index_file_timestamp <= entry_time) ce_smudge_racily_clean_entry(ce); if (ce_write(&c, newfd, ce, ce_size(ce)) < 0) return -1; + if (now && now <= entry_time) + recent++; } /* Write extension data here */ @@ -983,5 +990,34 @@ int write_cache(int newfd, struct cache_entry **cache, int entries) return -1; } } + + /* + * To prevent later ce_match_stat() from always falling into + * check_fs(), if we have too many entries that can trigger + * racily clean check, we are better off delaying the return. + * We arbitrarily say if more than 20 paths or 25% of total + * paths are very new, we delay the return until the index + * file gets a new timestamp. + * + * NOTE! NOTE! NOTE! + * + * This assumes that nobody is touching the working tree while + * we are updating the index. + */ + if (20 < recent || entries <= recent * 4) { + now = fstat(newfd, &st) ? 0 : st.st_mtime; + while (now && !fstat(newfd, &st) && st.st_mtime <= now) { + struct timespec rq, rm; + off_t where = lseek(newfd, 0, SEEK_CUR); + rq.tv_sec = 0; + rq.tv_nsec = 250000000; + nanosleep(&rq, &rm); + if ((where == (off_t) -1) || + (write(newfd, "", 1) != 1) || + (lseek(newfd, -1, SEEK_CUR) != where) || + ftruncate(newfd, where)) + break; + } + } return ce_flush(&c, newfd); } From f1efc38bf2856f875b878177c0f0a98d9eb3bb4e Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Tue, 8 Aug 2006 01:15:05 +0200 Subject: [PATCH 079/160] gitweb: Remove unused variables in git_shortlog_body and git_heads Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 2 -- 1 file changed, 2 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index b3bfc6bd9e..eabece78c2 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -1065,7 +1065,6 @@ sub git_shortlog_body { #my $ref = defined $refs ? git_get_referencing($refs, $commit) : ''; my $ref = git_get_referencing($refs, $commit); my %co = git_read_commit($commit); - my %ad = date_str($co{'author_epoch'}); if ($alternate) { print "
" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$file")}, "blob") . "" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$hash;f=$file"), -class => "list"}, esc_html($file)) . "[deleted " . file_type($from_mode). "]" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$hash;f=$file")}, "blob") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;hb=$hash;f=$file")}, "history") . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$parent;f=$file")}, "blob") . + " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;hb=$parent;f=$file")}, "history") . "" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$to_file"), -class => "list"}, esc_html($to_file)) . "[moved from " . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$hash;f=$from_file"), -class => "list"}, esc_html($from_file)) . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$parent;f=$from_file"), -class => "list"}, esc_html($from_file)) . " with " . (int $similarity) . "% similarity$mode_chng]" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$to_file")}, "blob"); @@ -2177,15 +2177,17 @@ sub git_commitdiff { git_diff_print(undef, "/dev/null", $to_id, "b/$file"); } elsif ($status eq "D") { print "
" . file_type($from_mode) . ":" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$hash;f=$file")}, $from_id) . "(deleted)" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$hash_parent;f=$file")}, $from_id) . "(deleted)" . "
\n"; git_diff_print($from_id, "a/$file", undef, "/dev/null"); } elsif ($status eq "M") { if ($from_id ne $to_id) { print "
" . - file_type($from_mode) . ":" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$hash;f=$file")}, $from_id) . + file_type($from_mode) . ":" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$hash_parent;f=$file")}, $from_id) . " -> " . - file_type($to_mode) . ":" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$file")}, $to_id); + file_type($to_mode) . ":" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$file")}, $to_id); print "
\n"; git_diff_print($from_id, "a/$file", $to_id, "b/$file"); } From 82f930deadc9a7990cbc0988255e6a5afd641f4b Mon Sep 17 00:00:00 2001 From: Luben Tuikov Date: Fri, 4 Aug 2006 15:09:59 -0700 Subject: [PATCH 081/160] gitweb: blame table row no highlight fix Until now blame just used the commit/tree/tags/etc style of highlight-able table rows, which have alternating light/dark rows that flash when mouse pointer passes over them. This is very annoying in blame, since the text is static and it interferes with the per-revision block highlighting. Signed-off-by: Luben Tuikov Signed-off-by: Junio C Hamano --- gitweb/gitweb.css | 4 ++++ gitweb/gitweb.perl | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css index 460e728718..47c1ade87e 100644 --- a/gitweb/gitweb.css +++ b/gitweb/gitweb.css @@ -171,6 +171,10 @@ tr.dark { background-color: #f6f6f0; } +tr.dark2 { + background-color: #f6f6f0; +} + tr.dark:hover { background-color: #edece6; } diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 6a92316677..ae13e3e701 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -1498,7 +1498,7 @@ sub git_blame2 { git_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); git_header_div('commit', esc_html($co{'title'}), $hash_base); git_print_page_path($file_name, $ftype); - my @rev_color = (qw(light dark)); + my @rev_color = (qw(light2 dark2)); my $num_colors = scalar(@rev_color); my $current_color = 0; my $last_rev; From 3900145ed72bf1dfd656af6a5b31034e818b425f Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Tue, 8 Aug 2006 18:35:23 +0200 Subject: [PATCH 082/160] autoconf: Add configure target to main Makefile While at it fill git version information in configure.ac configure target needs autoconf, of course. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- INSTALL | 2 +- Makefile | 7 +++++++ configure.ac | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/INSTALL b/INSTALL index ba9778cd4d..fa9bf74a20 100644 --- a/INSTALL +++ b/INSTALL @@ -16,7 +16,7 @@ install" would not work. Alternatively you can use autoconf generated ./configure script to set up install paths (via config.mak.autogen), so you can write instead - $ autoconf ;# as yourself if ./configure doesn't exist yet + $ make configure ;# as yourself $ ./configure --prefix=/usr ;# as yourself $ make all doc ;# as yourself # make install install-doc ;# as root diff --git a/Makefile b/Makefile index ae4c0f2d90..d8cc83507d 100644 --- a/Makefile +++ b/Makefile @@ -595,6 +595,13 @@ git-instaweb: git-instaweb.sh gitweb/gitweb.cgi gitweb/gitweb.css chmod +x $@+ mv $@+ $@ +configure: configure.ac + rm -f $@ $<+ + sed -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \ + $< > $<+ + autoconf -o $@ $<+ + rm -f $<+ + # These can record GIT_VERSION git$X git.spec \ $(patsubst %.sh,%,$(SCRIPT_SH)) \ diff --git a/configure.ac b/configure.ac index 3c56cc51ac..e2da89114e 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) -AC_INIT([git], [1.4.1], [git@vger.kernel.org]) +AC_INIT([git], [@@GIT_VERSION@@], [git@vger.kernel.org]) AC_CONFIG_SRCDIR([git.c]) From b52b1d433b47888d79a73a514aa3430257cba863 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Tue, 8 Aug 2006 18:36:21 +0200 Subject: [PATCH 083/160] autoconf: Error out on --without-shell and --without-perl Error out on --without-shell/--with-shell=no and --without-perl/--with-perl=no instead of just warning and continuing. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index e2da89114e..c2ddd9b6e8 100644 --- a/configure.ac +++ b/configure.ac @@ -37,7 +37,7 @@ AC_DEFUN([GIT_ARG_SET_PATH], AC_DEFUN([GIT_CONF_APPEND_PATH], [PROGRAM=m4_toupper($1); \ if test "$withval" = "no"; then \ - AC_MSG_WARN([You cannot use git without $1]); \ + AC_MSG_ERROR([You cannot use git without $1]); \ else \ if test "$withval" = "yes"; then \ AC_MSG_WARN([You should provide path for --with-$1=PATH]); \ From af6058cc2bf309631fc7f5cd44fb39b567286506 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Tue, 8 Aug 2006 18:38:06 +0200 Subject: [PATCH 084/160] autoconf: Improvements in NO_PYTHON/PYTHON_PATH handling Unset NO_PYTHON for --with-python without arguments, and when PYTHON_PATH is set. Do not check for PYTHON_PATH if it is set via --with-python=PYTHON_PATH. Prefer "python" over version specific names such as "python2.4". Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- configure.ac | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index c2ddd9b6e8..c27a994da0 100644 --- a/configure.ac +++ b/configure.ac @@ -105,7 +105,10 @@ AC_ARG_WITH(python,[AS_HELP_STRING([--with-python=PATH], [provide PATH to python AS_HELP_STRING([--no-python], [don't use python scripts])], [if test "$withval" = "no"; then \ NO_PYTHON=YesPlease; \ - elif test "$withval" != "yes"; then \ + elif test "$withval" = "yes"; then \ + NO_PYTHON=; \ + else \ + NO_PYTHON=; \ PYTHON_PATH=$withval; \ fi; \ ]) @@ -138,15 +141,15 @@ AC_CHECK_PROGS(TAR, [gtar tar]) # Define NO_PYTHON if you want to lose all benefits of the recursive merge. # Define PYTHON_PATH to provide path to Python. if test -z "$NO_PYTHON"; then - AC_PATH_PROGS(PYTHON_PATH, [python2.4 python2.3 python2 python]) + if test -z "$PYTHON_PATH"; then + AC_PATH_PROGS(PYTHON_PATH, [python python2.4 python2.3 python2]) + fi if test -n "$PYTHON_PATH"; then GIT_CONF_APPEND_LINE([PYTHON_PATH=@PYTHON_PATH@]) - else - GIT_CONF_APPEND_LINE([NO_PYTHON=@NO_PYTHON@]) + NO_PYTHON="" fi -else - GIT_CONF_APPEND_LINE([NO_PYTHON=@NO_PYTHON@]) fi +GIT_CONF_APPEND_LINE([NO_PYTHON=@NO_PYTHON@]) ## Checks for libraries. From 6015c28b1d6163f124332769989326ee470afbb6 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 8 Aug 2006 14:47:32 -0700 Subject: [PATCH 085/160] read-cache: tweak racy-git delay logic Instead of looping over the entries and writing out, use a separate loop after all entries have been written out to check how many entries are racily clean. Make sure that the newly created index file gets the right timestamp when we check by flushing the buffered data by ce_write(). Signed-off-by: Junio C Hamano --- read-cache.c | 73 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 21 deletions(-) diff --git a/read-cache.c b/read-cache.c index ce76c20f34..c923a32707 100644 --- a/read-cache.c +++ b/read-cache.c @@ -841,6 +841,18 @@ unmap: static unsigned char write_buffer[WRITE_BUFFER_SIZE]; static unsigned long write_buffer_len; +static int ce_write_flush(SHA_CTX *context, int fd) +{ + unsigned int buffered = write_buffer_len; + if (buffered) { + SHA1_Update(context, write_buffer, buffered); + if (write(fd, write_buffer, buffered) != buffered) + return -1; + write_buffer_len = 0; + } + return 0; +} + static int ce_write(SHA_CTX *context, int fd, void *data, unsigned int len) { while (len) { @@ -851,8 +863,8 @@ static int ce_write(SHA_CTX *context, int fd, void *data, unsigned int len) memcpy(write_buffer + buffered, data, partial); buffered += partial; if (buffered == WRITE_BUFFER_SIZE) { - SHA1_Update(context, write_buffer, WRITE_BUFFER_SIZE); - if (write(fd, write_buffer, WRITE_BUFFER_SIZE) != WRITE_BUFFER_SIZE) + write_buffer_len = buffered; + if (ce_write_flush(context, fd)) return -1; buffered = 0; } @@ -962,19 +974,15 @@ int write_cache(int newfd, struct cache_entry **cache, int entries) if (ce_write(&c, newfd, &hdr, sizeof(hdr)) < 0) return -1; - now = fstat(newfd, &st) ? 0 : st.st_mtime; - recent = 0; for (i = 0; i < entries; i++) { struct cache_entry *ce = cache[i]; - time_t entry_time = (time_t) ntohl(ce->ce_mtime.sec); if (!ce->ce_mode) continue; - if (index_file_timestamp && index_file_timestamp <= entry_time) + if (index_file_timestamp && + index_file_timestamp <= ntohl(ce->ce_mtime.sec)) ce_smudge_racily_clean_entry(ce); if (ce_write(&c, newfd, ce, ce_size(ce)) < 0) return -1; - if (now && now <= entry_time) - recent++; } /* Write extension data here */ @@ -1004,19 +1012,42 @@ int write_cache(int newfd, struct cache_entry **cache, int entries) * This assumes that nobody is touching the working tree while * we are updating the index. */ - if (20 < recent || entries <= recent * 4) { - now = fstat(newfd, &st) ? 0 : st.st_mtime; - while (now && !fstat(newfd, &st) && st.st_mtime <= now) { - struct timespec rq, rm; - off_t where = lseek(newfd, 0, SEEK_CUR); - rq.tv_sec = 0; - rq.tv_nsec = 250000000; - nanosleep(&rq, &rm); - if ((where == (off_t) -1) || - (write(newfd, "", 1) != 1) || - (lseek(newfd, -1, SEEK_CUR) != where) || - ftruncate(newfd, where)) - break; + + /* Make sure that the new index file has st_mtime + * that is current enough -- ce_write() batches the data + * so it might not have written anything yet. + */ + ce_write_flush(&c, newfd); + + now = fstat(newfd, &st) ? 0 : st.st_mtime; + if (now) { + recent = 0; + for (i = 0; i < entries; i++) { + struct cache_entry *ce = cache[i]; + time_t entry_time = (time_t) ntohl(ce->ce_mtime.sec); + if (!ce->ce_mode) + continue; + if (now && now <= entry_time) + recent++; + } + if (20 < recent && entries <= recent * 4) { +#if 0 + fprintf(stderr, "entries %d\n", entries); + fprintf(stderr, "recent %d\n", recent); + fprintf(stderr, "now %lu\n", now); +#endif + while (!fstat(newfd, &st) && st.st_mtime <= now) { + struct timespec rq, rm; + off_t where = lseek(newfd, 0, SEEK_CUR); + rq.tv_sec = 0; + rq.tv_nsec = 250000000; + nanosleep(&rq, &rm); + if ((where == (off_t) -1) || + (write(newfd, "", 1) != 1) || + (lseek(newfd, -1, SEEK_CUR) != where) || + ftruncate(newfd, where)) + break; + } } } return ce_flush(&c, newfd); From 424adc50b73f269ac3f3bd0195f9e7fea935109f Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Tue, 8 Aug 2006 18:39:06 +0200 Subject: [PATCH 086/160] autoconf: Move variables which we always set to config.mak.in Move detected NO_STH and NEED_STH variables, which we always output, either setting or unsetting (setting to empty string) to config.mak.in and use setting appropriately named variables and doing AC_SUBST instead of adding them via GIT_CONF_APPEND_LINE macro and config.mak.append temporary file. Variables which might and might not be set are still added via config.mak.append; this include all STH_PATH variables. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- config.mak.in | 16 +++++++++++ configure.ac | 75 ++++++++++++++++++++++++++++++--------------------- 2 files changed, 60 insertions(+), 31 deletions(-) diff --git a/config.mak.in b/config.mak.in index 04f508ab90..369e6116e0 100644 --- a/config.mak.in +++ b/config.mak.in @@ -22,3 +22,19 @@ VPATH = @srcdir@ export exec_prefix mandir export srcdir VPATH +NO_PYTHON=@NO_PYTHON@ +NEEDS_SSL_WITH_CRYPTO=@NEEDS_SSL_WITH_CRYPTO@ +NO_OPENSSL=@NO_OPENSSL@ +NO_CURL=@NO_CURL@ +NO_EXPAT=@NO_EXPAT@ +NEEDS_LIBICONV=@NEEDS_LIBICONV@ +NEEDS_SOCKET=@NEEDS_SOCKET@ +NO_D_INO_IN_DIRENT=@NO_D_INO_IN_DIRENT@ +NO_D_TYPE_IN_DIRENT=@NO_D_TYPE_IN_DIRENT@ +NO_SOCKADDR_STORAGE=@NO_SOCKADDR_STORAGE@ +NO_IPV6=@NO_IPV6@ +NO_C99_FORMAT=@NO_C99_FORMAT@ +NO_STRCASESTR=@NO_STRCASESTR@ +NO_STRLCPY=@NO_STRLCPY@ +NO_SETENV=@NO_SETENV@ + diff --git a/configure.ac b/configure.ac index c27a994da0..bc2824bb88 100644 --- a/configure.ac +++ b/configure.ac @@ -149,7 +149,6 @@ if test -z "$NO_PYTHON"; then NO_PYTHON="" fi fi -GIT_CONF_APPEND_LINE([NO_PYTHON=@NO_PYTHON@]) ## Checks for libraries. @@ -158,35 +157,41 @@ AC_MSG_NOTICE([CHECKS for libraries]) # Define NO_OPENSSL environment variable if you do not have OpenSSL. # Define NEEDS_SSL_WITH_CRYPTO if you need -lcrypto with -lssl (Darwin). AC_CHECK_LIB([crypto], [SHA1_Init], -[GIT_CONF_APPEND_LINE(NEEDS_SSL_WITH_CRYPTO=)], +[NEEDS_SSL_WITH_CRYPTO=], [AC_CHECK_LIB([ssl], [SHA1_Init], - [GIT_CONF_APPEND_LINE(NEEDS_SSL_WITH_CRYPTO=YesPlease) - GIT_CONF_APPEND_LINE(NEEDS_SSL_WITH_CRYPTO=)], - [GIT_CONF_APPEND_LINE(NO_OPENSSL=YesPlease)])]) + [NEEDS_SSL_WITH_CRYPTO=YesPlease + NEEDS_SSL_WITH_CRYPTO=], + [NO_OPENSSL=YesPlease])]) +AC_SUBST(NEEDS_SSL_WITH_CRYPTO) +AC_SUBST(NO_OPENSSL) # # Define NO_CURL if you do not have curl installed. git-http-pull and # git-http-push are not built, and you cannot use http:// and https:// # transports. AC_CHECK_LIB([curl], [curl_global_init], -[GIT_CONF_APPEND_LINE(NO_CURL=)], -[GIT_CONF_APPEND_LINE(NO_CURL=YesPlease)]) +[NO_CURL=], +[NO_CURL=YesPlease]) +AC_SUBST(NO_CURL) # # Define NO_EXPAT if you do not have expat installed. git-http-push is # not built, and you cannot push using http:// and https:// transports. AC_CHECK_LIB([expat], [XML_ParserCreate], -[GIT_CONF_APPEND_LINE(NO_EXPAT=)], -[GIT_CONF_APPEND_LINE(NO_EXPAT=YesPlease)]) +[NO_EXPAT=], +[NO_EXPAT=YesPlease]) +AC_SUBST(NO_EXPAT) # # Define NEEDS_LIBICONV if linking with libc is not enough (Darwin). AC_CHECK_LIB([c], [iconv], -[GIT_CONF_APPEND_LINE(NEEDS_LIBICONV=)], -[GIT_CONF_APPEND_LINE(NEEDS_LIBICONV=YesPlease)]) +[NEEDS_LIBICONV=], +[NEEDS_LIBICONV=YesPlease]) +AC_SUBST(NEEDS_LIBICONV) # # Define NEEDS_SOCKET if linking with libc is not enough (SunOS, # Patrick Mauritz). AC_CHECK_LIB([c], [socket], -[GIT_CONF_APPEND_LINE(NEEDS_SOCKET=)], -[GIT_CONF_APPEND_LINE(NEEDS_SOCKET=YesPlease)]) +[NEEDS_SOCKET=], +[NEEDS_SOCKET=YesPlease]) +AC_SUBST(NEEDS_SOCKET) ## Checks for header files. @@ -197,33 +202,38 @@ AC_MSG_NOTICE([CHECKS for typedefs, structures, and compiler characteristics]) # # Define NO_D_INO_IN_DIRENT if you don't have d_ino in your struct dirent. AC_CHECK_MEMBER(struct dirent.d_ino, -[GIT_CONF_APPEND_LINE(NO_D_INO_IN_DIRENT=)], -[GIT_CONF_APPEND_LINE(NO_D_INO_IN_DIRENT=YesPlease)], +[NO_D_INO_IN_DIRENT=], +[NO_D_INO_IN_DIRENT=YesPlease], [#include ]) +AC_SUBST(NO_D_INO_IN_DIRENT) # # Define NO_D_TYPE_IN_DIRENT if your platform defines DT_UNKNOWN but lacks # d_type in struct dirent (latest Cygwin -- will be fixed soonish). AC_CHECK_MEMBER(struct dirent.d_type, -[GIT_CONF_APPEND_LINE(NO_D_TYPE_IN_DIRENT=)], -[GIT_CONF_APPEND_LINE(NO_D_TYPE_IN_DIRENT=YesPlease)], +[NO_D_TYPE_IN_DIRENT=], +[NO_D_TYPE_IN_DIRENT=YesPlease], [#include ]) +AC_SUBST(NO_D_TYPE_IN_DIRENT) # # Define NO_SOCKADDR_STORAGE if your platform does not have struct # sockaddr_storage. AC_CHECK_TYPE(struct sockaddr_storage, -[GIT_CONF_APPEND_LINE(NO_SOCKADDR_STORAGE=)], -[GIT_CONF_APPEND_LINE(NO_SOCKADDR_STORAGE=YesPlease)], +[NO_SOCKADDR_STORAGE=], +[NO_SOCKADDR_STORAGE=YesPlease], [#include ]) +AC_SUBST(NO_SOCKADDR_STORAGE) +# # Define NO_IPV6 if you lack IPv6 support and getaddrinfo(). AC_CHECK_TYPE([struct addrinfo],[ AC_CHECK_FUNC([getaddrinfo], - [GIT_CONF_APPEND_LINE(NO_IPV6=)], - [GIT_CONF_APPEND_LINE(NO_IPV6=YesPlease)]) -],[GIT_CONF_APPEND_LINE(NO_IPV6=YesPlease)],[ + [NO_IPV6=], + [NO_IPV6=YesPlease]) +],[NO_IPV6=YesPlease],[ #include #include #include ]) +AC_SUBST(NO_IPV6) # # Define NO_C99_FORMAT if your formatted IO functions (printf/scanf et.al.) # do not support the 'size specifiers' introduced by C99, namely ll, hh, @@ -243,11 +253,11 @@ AC_RUN_IFELSE( [ac_cv_c_c99_format=no]) ]) if test $ac_cv_c_c99_format = no; then - GIT_CONF_APPEND_LINE(NO_C99_FORMAT=YesPlease) + NO_C99_FORMAT=YesPlease else - GIT_CONF_APPEND_LINE(NO_C99_FORMAT=) + NO_C99_FORMAT= fi - +AC_SUBST(NO_C99_FORMAT) ## Checks for library functions. ## (in default C library and libraries checked by AC_CHECK_LIB) @@ -255,18 +265,21 @@ AC_MSG_NOTICE([CHECKS for library functions]) # # Define NO_STRCASESTR if you don't have strcasestr. AC_CHECK_FUNC(strcasestr, -[GIT_CONF_APPEND_LINE(NO_STRCASESTR=)], -[GIT_CONF_APPEND_LINE(NO_STRCASESTR=YesPlease)]) +[NO_STRCASESTR=], +[NO_STRCASESTR=YesPlease]) +AC_SUBST(NO_STRCASESTR) # # Define NO_STRLCPY if you don't have strlcpy. AC_CHECK_FUNC(strlcpy, -[GIT_CONF_APPEND_LINE(NO_STRLCPY=)], -[GIT_CONF_APPEND_LINE(NO_STRLCPY=YesPlease)]) +[NO_STRLCPY=], +[NO_STRLCPY=YesPlease]) +AC_SUBST(NO_STRLCPY) # # Define NO_SETENV if you don't have setenv in the C library. AC_CHECK_FUNC(setenv, -[GIT_CONF_APPEND_LINE(NO_SETENV=)], -[GIT_CONF_APPEND_LINE(NO_SETENV=YesPlease)]) +[NO_SETENV=], +[NO_SETENV=YesPlease]) +AC_SUBST(NO_SETENV) # # Define NO_MMAP if you want to avoid mmap. # From 1b1b678e3c4eebe0302455c248941e5627ce2b5b Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 8 Aug 2006 13:42:35 -0700 Subject: [PATCH 087/160] autoconf: clean temporary file mak.append When configure is interrupted in the middle it leaves config.mak.append behind. Add it to .gitignore and make sure $(MAKE) clean removes it. Also earlier .gitignore listed config.mak.in which is a tracked file. Fix it. Signed-off-by: Junio C Hamano --- .gitignore | 2 +- Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index fb0fa3f16a..6e973b3d4b 100644 --- a/.gitignore +++ b/.gitignore @@ -140,7 +140,7 @@ config.mak autom4te.cache config.log config.status -config.mak.in config.mak.autogen +config.mak.append configure git-blame diff --git a/Makefile b/Makefile index d8cc83507d..d4297c27c1 100644 --- a/Makefile +++ b/Makefile @@ -793,7 +793,7 @@ clean: rm -f $(ALL_PROGRAMS) $(BUILT_INS) git$X rm -f *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags rm -rf autom4te.cache - rm -f config.log config.mak.autogen configure config.status config.cache + rm -f configure config.log config.mak.autogen config.mak.append config.status config.cache rm -rf $(GIT_TARNAME) .doc-tmp-dir rm -f $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz rm -f $(htmldocs).tar.gz $(manpages).tar.gz From 7b1e9d3d854f0c0df58b88809793c1b114a45b90 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Wed, 9 Aug 2006 02:19:22 +0200 Subject: [PATCH 088/160] autoconf: It is --without-python, not --no-python Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index bc2824bb88..3fd3d55e43 100644 --- a/configure.ac +++ b/configure.ac @@ -102,7 +102,7 @@ GIT_ARG_SET_PATH(perl) # Define NO_PYTHON if you want to lose all benefits of the recursive merge. # Define PYTHON_PATH to provide path to Python. AC_ARG_WITH(python,[AS_HELP_STRING([--with-python=PATH], [provide PATH to python]) -AS_HELP_STRING([--no-python], [don't use python scripts])], +AS_HELP_STRING([--without-python], [don't use python scripts])], [if test "$withval" = "no"; then \ NO_PYTHON=YesPlease; \ elif test "$withval" = "yes"; then \ From a20b4d899ae75e075641d7bfe9462a239c8b9236 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Wed, 9 Aug 2006 02:15:10 +0200 Subject: [PATCH 089/160] autoconf: Add support for setting CURLDIR, OPENSSLDIR, EXPATDIR Add support for --with-openssl=PATH and --without-openssl, --with-curl=PATH and --without-curl, --with-expat=PATH and --without-expat ./configure options, each setting or unsetting appropriate NO_PACKAGE and if called with argument also PACKAGEDIR (of which only CURLDIR is documented in Makefile) All above options are supported as override to autodetection; more to come in the same style (override to autodetection), so moved the bulk of comments for site configuration down. Needs review by someone well versed in autoconf and m4. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- configure.ac | 158 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 101 insertions(+), 57 deletions(-) diff --git a/configure.ac b/configure.ac index 3fd3d55e43..e890131c46 100644 --- a/configure.ac +++ b/configure.ac @@ -46,53 +46,29 @@ else \ fi; \ fi; \ ]) # GIT_CONF_APPEND_PATH +# +# GIT_PARSE_WITH(PACKAGE) +# ----------------------- +# For use in AC_ARG_WITH action-if-found, for packages default ON. +# * Set NO_PACKAGE=YesPlease for --without-PACKAGE +# * Set PACKAGEDIR=PATH for --with-PACKAGE=PATH +# * Unset NO_PACKAGE for --with-PACKAGE without ARG +AC_DEFUN([GIT_PARSE_WITH], +[PACKAGE=m4_toupper($1); \ +if test "$withval" = "no"; then \ + m4_toupper(NO_$1)=YesPlease; \ +elif test "$withval" = "yes"; then \ + m4_toupper(NO_$1)=; \ +else \ + m4_toupper(NO_$1)=; \ + GIT_CONF_APPEND_LINE(${PACKAGE}DIR=$withval); \ +fi \ +])# GIT_PARSE_WITH -## Site configuration +## Site configuration related to programs (before tests) ## --with-PACKAGE[=ARG] and --without-PACKAGE # -# Define NO_SVN_TESTS if you want to skip time-consuming SVN interoperability -# tests. These tests take up a significant amount of the total test time -# but are not needed unless you plan to talk to SVN repos. -# -# Define MOZILLA_SHA1 environment variable when running make to make use of -# a bundled SHA1 routine coming from Mozilla. It is GPL'd and should be fast -# on non-x86 architectures (e.g. PowerPC), while the OpenSSL version (default -# choice) has very fast version optimized for i586. -# -# Define PPC_SHA1 environment variable when running make to make use of -# a bundled SHA1 routine optimized for PowerPC. -# -# Define ARM_SHA1 environment variable when running make to make use of -# a bundled SHA1 routine optimized for ARM. -# -# Define NO_OPENSSL environment variable if you do not have OpenSSL. -# This also implies MOZILLA_SHA1. -# -# Define NO_CURL if you do not have curl installed. git-http-pull and -# git-http-push are not built, and you cannot use http:// and https:// -# transports. -# -# Define CURLDIR=/foo/bar if your curl header and library files are in -# /foo/bar/include and /foo/bar/lib directories. -# -# Define NO_EXPAT if you do not have expat installed. git-http-push is -# not built, and you cannot push using http:// and https:// transports. -# -# Define NO_FINK if you are building on Darwin/Mac OS X, have Fink -# installed in /sw, but don't want GIT to link against any libraries -# installed there. If defined you may specify your own (or Fink's) -# include directories and library directories by defining CFLAGS -# and LDFLAGS appropriately. -# -# Define NO_DARWIN_PORTS if you are building on Darwin/Mac OS X, -# have DarwinPorts installed in /opt/local, but don't want GIT to -# link against any libraries installed there. If defined you may -# specify your own (or DarwinPort's) include directories and -# library directories by defining CFLAGS and LDFLAGS appropriately. -# -# Define NO_MMAP if you want to avoid mmap. -# # Define SHELL_PATH to provide path to shell. GIT_ARG_SET_PATH(shell) # @@ -114,20 +90,6 @@ AS_HELP_STRING([--without-python], [don't use python scripts])], ]) AC_SUBST(NO_PYTHON) AC_SUBST(PYTHON_PATH) -# -## --enable-FEATURE[=ARG] and --disable-FEATURE -# Define COLLISION_CHECK below if you believe that SHA1's -# 1461501637330902918203684832716283019655932542976 hashes do not give you -# sufficient guarantee that no collisions between objects will ever happen. -# -# Define USE_NSEC below if you want git to care about sub-second file mtimes -# and ctimes. Note that you need recent glibc (at least 2.2.4) for this, and -# it will BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely -# randomly break unless your underlying filesystem supports those sub-second -# times (my ext3 doesn't). -# -# Define USE_STDEV below if you want git to care about the underlying device -# change being considered an inode change from the update-cache perspective. ## Checks for programs. @@ -259,6 +221,7 @@ else fi AC_SUBST(NO_C99_FORMAT) + ## Checks for library functions. ## (in default C library and libraries checked by AC_CHECK_LIB) AC_MSG_NOTICE([CHECKS for library functions]) @@ -299,6 +262,87 @@ AC_SUBST(NO_SETENV) # a missing newline at the end of the file. +## Site configuration (override autodetection) +## --with-PACKAGE[=ARG] and --without-PACKAGE +AC_MSG_NOTICE([CHECKS for site configuration]) +# +# Define NO_SVN_TESTS if you want to skip time-consuming SVN interoperability +# tests. These tests take up a significant amount of the total test time +# but are not needed unless you plan to talk to SVN repos. +# +# Define MOZILLA_SHA1 environment variable when running make to make use of +# a bundled SHA1 routine coming from Mozilla. It is GPL'd and should be fast +# on non-x86 architectures (e.g. PowerPC), while the OpenSSL version (default +# choice) has very fast version optimized for i586. +# +# Define PPC_SHA1 environment variable when running make to make use of +# a bundled SHA1 routine optimized for PowerPC. +# +# Define ARM_SHA1 environment variable when running make to make use of +# a bundled SHA1 routine optimized for ARM. +# +# Define NO_OPENSSL environment variable if you do not have OpenSSL. +# This also implies MOZILLA_SHA1. +# +# Define OPENSSLDIR=/foo/bar if your openssl header and library files are in +# /foo/bar/include and /foo/bar/lib directories. +AC_ARG_WITH(openssl, +AS_HELP_STRING([--with-openssl],[use OpenSSL library (default is YES)]) +AS_HELP_STRING([], [ARG can be prefix for openssl library and headers]),\ +GIT_PARSE_WITH(openssl)) +# +# Define NO_CURL if you do not have curl installed. git-http-pull and +# git-http-push are not built, and you cannot use http:// and https:// +# transports. +# +# Define CURLDIR=/foo/bar if your curl header and library files are in +# /foo/bar/include and /foo/bar/lib directories. +AC_ARG_WITH(curl, +AS_HELP_STRING([--with-curl],[support http(s):// transports (default is YES)]) +AS_HELP_STRING([], [ARG can be also prefix for curl library and headers]), +GIT_PARSE_WITH(curl)) +# +# Define NO_EXPAT if you do not have expat installed. git-http-push is +# not built, and you cannot push using http:// and https:// transports. +# +# Define EXPATDIR=/foo/bar if your expat header and library files are in +# /foo/bar/include and /foo/bar/lib directories. +AC_ARG_WITH(expat, +AS_HELP_STRING([--with-expat], +[support git-push using http:// and https:// transports via WebDAV (default is YES)]) +AS_HELP_STRING([], [ARG can be also prefix for expat library and headers]), +GIT_PARSE_WITH(expat)) +# +# Define NO_FINK if you are building on Darwin/Mac OS X, have Fink +# installed in /sw, but don't want GIT to link against any libraries +# installed there. If defined you may specify your own (or Fink's) +# include directories and library directories by defining CFLAGS +# and LDFLAGS appropriately. +# +# Define NO_DARWIN_PORTS if you are building on Darwin/Mac OS X, +# have DarwinPorts installed in /opt/local, but don't want GIT to +# link against any libraries installed there. If defined you may +# specify your own (or DarwinPort's) include directories and +# library directories by defining CFLAGS and LDFLAGS appropriately. +# +# Define NO_MMAP if you want to avoid mmap. + +## --enable-FEATURE[=ARG] and --disable-FEATURE +# +# Define COLLISION_CHECK below if you believe that SHA1's +# 1461501637330902918203684832716283019655932542976 hashes do not give you +# sufficient guarantee that no collisions between objects will ever happen. +# +# Define USE_NSEC below if you want git to care about sub-second file mtimes +# and ctimes. Note that you need recent glibc (at least 2.2.4) for this, and +# it will BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely +# randomly break unless your underlying filesystem supports those sub-second +# times (my ext3 doesn't). +# +# Define USE_STDEV below if you want git to care about the underlying device +# change being considered an inode change from the update-cache perspective. + + ## Output files AC_CONFIG_FILES(["${config_file}":"${config_in}":"${config_append}"]) AC_OUTPUT From 2e3ed670eb09feffe847af55db38da3dcecc2a88 Mon Sep 17 00:00:00 2001 From: Rene Scharfe Date: Thu, 10 Aug 2006 17:02:38 +0200 Subject: [PATCH 090/160] git-verify-pack: make builtin Convert git-verify-pack to a builtin command. Also rename ac to argc and av to argv for consistancy. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- Makefile | 1 + verify-pack.c => builtin-verify-pack.c | 15 ++++++++------- builtin.h | 1 + git.c | 1 + 4 files changed, 11 insertions(+), 7 deletions(-) rename verify-pack.c => builtin-verify-pack.c (83%) diff --git a/Makefile b/Makefile index 733fa660d9..a3ba585cee 100644 --- a/Makefile +++ b/Makefile @@ -275,6 +275,7 @@ BUILTIN_OBJS = \ builtin-update-index.o \ builtin-update-ref.o \ builtin-upload-tar.o \ + builtin-verify-pack.o \ builtin-write-tree.o GITLIBS = $(LIB_FILE) $(XDIFF_LIB) diff --git a/verify-pack.c b/builtin-verify-pack.c similarity index 83% rename from verify-pack.c rename to builtin-verify-pack.c index f440a39678..d700761e15 100644 --- a/verify-pack.c +++ b/builtin-verify-pack.c @@ -1,3 +1,4 @@ +#include "builtin.h" #include "cache.h" #include "pack.h" @@ -47,28 +48,28 @@ static int verify_one_pack(const char *path, int verbose) static const char verify_pack_usage[] = "git-verify-pack [-v] ..."; -int main(int ac, char **av) +int cmd_verify_pack(int argc, const char **argv, const char *prefix) { int err = 0; int verbose = 0; int no_more_options = 0; int nothing_done = 1; - while (1 < ac) { - if (!no_more_options && av[1][0] == '-') { - if (!strcmp("-v", av[1])) + while (1 < argc) { + if (!no_more_options && argv[1][0] == '-') { + if (!strcmp("-v", argv[1])) verbose = 1; - else if (!strcmp("--", av[1])) + else if (!strcmp("--", argv[1])) no_more_options = 1; else usage(verify_pack_usage); } else { - if (verify_one_pack(av[1], verbose)) + if (verify_one_pack(argv[1], verbose)) err = 1; nothing_done = 0; } - ac--; av++; + argc--; argv++; } if (nothing_done) diff --git a/builtin.h b/builtin.h index c0bdb051bd..ade58c4a1f 100644 --- a/builtin.h +++ b/builtin.h @@ -59,5 +59,6 @@ extern int cmd_upload_tar(int argc, const char **argv, const char *prefix); extern int cmd_version(int argc, const char **argv, const char *prefix); extern int cmd_whatchanged(int argc, const char **argv, const char *prefix); extern int cmd_write_tree(int argc, const char **argv, const char *prefix); +extern int cmd_verify_pack(int argc, const char **argv, const char *prefix); #endif diff --git a/git.c b/git.c index db0f86790d..5da7787d86 100644 --- a/git.c +++ b/git.c @@ -270,6 +270,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp) { "version", cmd_version }, { "whatchanged", cmd_whatchanged, RUN_SETUP | USE_PAGER }, { "write-tree", cmd_write_tree, RUN_SETUP }, + { "verify-pack", cmd_verify_pack }, }; int i; From 26298b5f7ba816960032f427aef331a46e2fb71b Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Thu, 10 Aug 2006 12:38:47 +0200 Subject: [PATCH 091/160] gitweb: Whitespace cleanup - tabs are for indent, spaces are for align Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index eabece78c2..ddf593a5bf 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -1003,7 +1003,7 @@ sub git_get_paging_nav { if ($page > 0) { $paging_nav .= " ⋅ " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$action;h=$hash;pg=" . ($page-1)), - -accesskey => "p", -title => "Alt-p"}, "prev"); + -accesskey => "p", -title => "Alt-p"}, "prev"); } else { $paging_nav .= " ⋅ prev"; } @@ -1011,7 +1011,7 @@ sub git_get_paging_nav { if ($nrevs >= (100 * ($page+1)-1)) { $paging_nav .= " ⋅ " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$action;h=$hash;pg=" . ($page+1)), - -accesskey => "n", -title => "Alt-n"}, "next"); + -accesskey => "n", -title => "Alt-n"}, "next"); } else { $paging_nav .= " ⋅ next"; } @@ -1844,9 +1844,9 @@ sub git_log { next if !%co; my %ad = date_str($co{'author_epoch'}); git_header_div('commit', - "$co{'age_string'}" . - esc_html($co{'title'}) . $ref, - $commit); + "$co{'age_string'}" . + esc_html($co{'title'}) . $ref, + $commit); print "
\n" . "
\n" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit")}, "commit") . @@ -1911,8 +1911,8 @@ sub git_commit { } git_header_html(undef, $expires); git_page_nav('commit', defined $co{'parent'} ? '' : 'commitdiff', - $hash, $co{'tree'}, $hash, - $formats_nav); + $hash, $co{'tree'}, $hash, + $formats_nav); if (defined $co{'parent'}) { git_header_div('commitdiff', esc_html($co{'title'}) . $ref, $hash); From f59a59e22f0005d799fe1d40e0c1f7e5c1f68b76 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 28 Jul 2006 23:56:15 +0200 Subject: [PATCH 092/160] Add the --color-words option to the diff options family With this option, the changed words are shown inline. For example, if a file containing "This is foo" is changed to "This is bar", the diff will now show "This is " in plain text, "foo" in red, and "bar" in green. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Documentation/diff-options.txt | 3 + diff.c | 178 +++++++++++++++++++++++++++++++-- diff.h | 3 +- 3 files changed, 177 insertions(+), 7 deletions(-) diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index 47ba9a403a..b5d9763594 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -36,6 +36,9 @@ Turn off colored diff, even when the configuration file gives the default to color output. +--color-words:: + Show colored word diff, i.e. color words which have changed. + --no-renames:: Turn off rename detection, even when the configuration file gives the default to do so. diff --git a/diff.c b/diff.c index b3b1781a9c..a8710cb9e2 100644 --- a/diff.c +++ b/diff.c @@ -358,12 +358,152 @@ static int fill_mmfile(mmfile_t *mf, struct diff_filespec *one) return 0; } +struct diff_words_buffer { + mmfile_t text; + long alloc; + long current; /* output pointer */ + int suppressed_newline; +}; + +static void diff_words_append(char *line, unsigned long len, + struct diff_words_buffer *buffer) +{ + if (buffer->text.size + len > buffer->alloc) { + buffer->alloc = (buffer->text.size + len) * 3 / 2; + buffer->text.ptr = xrealloc(buffer->text.ptr, buffer->alloc); + } + line++; + len--; + memcpy(buffer->text.ptr + buffer->text.size, line, len); + buffer->text.size += len; +} + +struct diff_words_data { + struct xdiff_emit_state xm; + struct diff_words_buffer minus, plus; +}; + +static void print_word(struct diff_words_buffer *buffer, int len, int color, + int suppress_newline) +{ + const char *ptr; + int eol = 0; + + if (len == 0) + return; + + ptr = buffer->text.ptr + buffer->current; + buffer->current += len; + + if (ptr[len - 1] == '\n') { + eol = 1; + len--; + } + + fputs(diff_get_color(1, color), stdout); + fwrite(ptr, len, 1, stdout); + fputs(diff_get_color(1, DIFF_RESET), stdout); + + if (eol) { + if (suppress_newline) + buffer->suppressed_newline = 1; + else + putchar('\n'); + } +} + +static void fn_out_diff_words_aux(void *priv, char *line, unsigned long len) +{ + struct diff_words_data *diff_words = priv; + + if (diff_words->minus.suppressed_newline) { + if (line[0] != '+') + putchar('\n'); + diff_words->minus.suppressed_newline = 0; + } + + len--; + switch (line[0]) { + case '-': + print_word(&diff_words->minus, len, DIFF_FILE_OLD, 1); + break; + case '+': + print_word(&diff_words->plus, len, DIFF_FILE_NEW, 0); + break; + case ' ': + print_word(&diff_words->plus, len, DIFF_PLAIN, 0); + diff_words->minus.current += len; + break; + } +} + +/* this executes the word diff on the accumulated buffers */ +static void diff_words_show(struct diff_words_data *diff_words) +{ + xpparam_t xpp; + xdemitconf_t xecfg; + xdemitcb_t ecb; + mmfile_t minus, plus; + int i; + + minus.size = diff_words->minus.text.size; + minus.ptr = xmalloc(minus.size); + memcpy(minus.ptr, diff_words->minus.text.ptr, minus.size); + for (i = 0; i < minus.size; i++) + if (isspace(minus.ptr[i])) + minus.ptr[i] = '\n'; + diff_words->minus.current = 0; + + plus.size = diff_words->plus.text.size; + plus.ptr = xmalloc(plus.size); + memcpy(plus.ptr, diff_words->plus.text.ptr, plus.size); + for (i = 0; i < plus.size; i++) + if (isspace(plus.ptr[i])) + plus.ptr[i] = '\n'; + diff_words->plus.current = 0; + + xpp.flags = XDF_NEED_MINIMAL; + xecfg.ctxlen = diff_words->minus.alloc + diff_words->plus.alloc; + xecfg.flags = 0; + ecb.outf = xdiff_outf; + ecb.priv = diff_words; + diff_words->xm.consume = fn_out_diff_words_aux; + xdl_diff(&minus, &plus, &xpp, &xecfg, &ecb); + + free(minus.ptr); + free(plus.ptr); + diff_words->minus.text.size = diff_words->plus.text.size = 0; + + if (diff_words->minus.suppressed_newline) { + putchar('\n'); + diff_words->minus.suppressed_newline = 0; + } +} + struct emit_callback { struct xdiff_emit_state xm; int nparents, color_diff; const char **label_path; + struct diff_words_data *diff_words; }; +static void free_diff_words_data(struct emit_callback *ecbdata) +{ + if (ecbdata->diff_words) { + /* flush buffers */ + if (ecbdata->diff_words->minus.text.size || + ecbdata->diff_words->plus.text.size) + diff_words_show(ecbdata->diff_words); + + if (ecbdata->diff_words->minus.text.ptr) + free (ecbdata->diff_words->minus.text.ptr); + if (ecbdata->diff_words->plus.text.ptr) + free (ecbdata->diff_words->plus.text.ptr); + free(ecbdata->diff_words); + ecbdata->diff_words = NULL; + } +} + const char *diff_get_color(int diff_use_color, enum color_diff ix) { if (diff_use_color) @@ -398,12 +538,31 @@ static void fn_out_consume(void *priv, char *line, unsigned long len) else { int nparents = ecbdata->nparents; int color = DIFF_PLAIN; - for (i = 0; i < nparents && len; i++) { - if (line[i] == '-') - color = DIFF_FILE_OLD; - else if (line[i] == '+') - color = DIFF_FILE_NEW; - } + if (ecbdata->diff_words && nparents != 1) + /* fall back to normal diff */ + free_diff_words_data(ecbdata); + if (ecbdata->diff_words) { + if (line[0] == '-') { + diff_words_append(line, len, + &ecbdata->diff_words->minus); + return; + } else if (line[0] == '+') { + diff_words_append(line, len, + &ecbdata->diff_words->plus); + return; + } + if (ecbdata->diff_words->minus.text.size || + ecbdata->diff_words->plus.text.size) + diff_words_show(ecbdata->diff_words); + line++; + len--; + } else + for (i = 0; i < nparents && len; i++) { + if (line[i] == '-') + color = DIFF_FILE_OLD; + else if (line[i] == '+') + color = DIFF_FILE_NEW; + } set = diff_get_color(ecbdata->color_diff, color); } if (len > 0 && line[len-1] == '\n') @@ -836,7 +995,12 @@ static void builtin_diff(const char *name_a, ecb.outf = xdiff_outf; ecb.priv = &ecbdata; ecbdata.xm.consume = fn_out_consume; + if (o->color_diff_words) + ecbdata.diff_words = + xcalloc(1, sizeof(struct diff_words_data)); xdl_diff(&mf1, &mf2, &xpp, &xecfg, &ecb); + if (o->color_diff_words) + free_diff_words_data(&ecbdata); } free_ab_and_return: @@ -1697,6 +1861,8 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac) options->xdl_opts |= XDF_IGNORE_WHITESPACE; else if (!strcmp(arg, "-b") || !strcmp(arg, "--ignore-space-change")) options->xdl_opts |= XDF_IGNORE_WHITESPACE_CHANGE; + else if (!strcmp(arg, "--color-words")) + options->color_diff = options->color_diff_words = 1; else if (!strcmp(arg, "--no-renames")) options->detect_rename = 0; else diff --git a/diff.h b/diff.h index 2cced530fa..b007240a5d 100644 --- a/diff.h +++ b/diff.h @@ -46,7 +46,8 @@ struct diff_options { full_index:1, silent_on_remove:1, find_copies_harder:1, - color_diff:1; + color_diff:1, + color_diff_words:1; int context; int break_opt; int detect_rename; From 0d042fecf2f4130717d198f9cc2d792e72370bda Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 11 Aug 2006 00:44:42 -0700 Subject: [PATCH 093/160] git-grep: show pathnames relative to the current directory By default, the command shows pathnames relative to the current directory. Use --full-name (the same flag to do so in ls-files) if you want to see the full pathname relative to the project root. This makes it very pleasant to run in Emacs compilation (or "grep-find") buffer. Signed-off-by: Junio C Hamano --- Documentation/git-grep.txt | 8 +++++- builtin-grep.c | 59 +++++++++++++++++++++++++++++++------- t/t7002-grep.sh | 31 ++++++++++++++++++-- 3 files changed, 85 insertions(+), 13 deletions(-) diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt index dc7683383c..7545dd9a3e 100644 --- a/Documentation/git-grep.txt +++ b/Documentation/git-grep.txt @@ -11,7 +11,7 @@ SYNOPSIS [verse] 'git-grep' [--cached] [-a | --text] [-I] [-i | --ignore-case] [-w | --word-regexp] - [-v | --invert-match] + [-v | --invert-match] [--full-name] [-E | --extended-regexp] [-G | --basic-regexp] [-F | --fixed-strings] [-n] [-l | --files-with-matches] [-L | --files-without-match] [-c | --count] @@ -47,6 +47,12 @@ OPTIONS -v | --invert-match:: Select non-matching lines. +--full-name:: + When run from a subdirectory, the command usually + outputs paths relative to the current directory. This + option forces paths to be output relative to the project + top directory. + -E | --extended-regexp | -G | --basic-regexp:: Use POSIX extended/basic regexp for patterns. Default is to use basic regexp. diff --git a/builtin-grep.c b/builtin-grep.c index 93b7e07b30..a561612e7e 100644 --- a/builtin-grep.c +++ b/builtin-grep.c @@ -123,6 +123,7 @@ struct grep_opt { struct grep_pat *pattern_list; struct grep_pat **pattern_tail; struct grep_expr *pattern_expression; + int prefix_length; regex_t regexp; unsigned linenum:1; unsigned invert:1; @@ -136,6 +137,7 @@ struct grep_opt { #define GREP_BINARY_TEXT 2 unsigned binary:2; unsigned extended:1; + unsigned relative:1; int regflags; unsigned pre_context; unsigned post_context; @@ -632,19 +634,40 @@ static int grep_buffer(struct grep_opt *opt, const char *name, return !!last_hit; } -static int grep_sha1(struct grep_opt *opt, const unsigned char *sha1, const char *name) +static int grep_sha1(struct grep_opt *opt, const unsigned char *sha1, const char *name, int tree_name_len) { unsigned long size; char *data; char type[20]; + char *to_free = NULL; int hit; + data = read_sha1_file(sha1, type, &size); if (!data) { error("'%s': unable to read %s", name, sha1_to_hex(sha1)); return 0; } + if (opt->relative && opt->prefix_length) { + static char name_buf[PATH_MAX]; + char *cp; + int name_len = strlen(name) - opt->prefix_length + 1; + + if (!tree_name_len) + name += opt->prefix_length; + else { + if (ARRAY_SIZE(name_buf) <= name_len) + cp = to_free = xmalloc(name_len); + else + cp = name_buf; + memcpy(cp, name, tree_name_len); + strcpy(cp + tree_name_len, + name + tree_name_len + opt->prefix_length); + name = cp; + } + } hit = grep_buffer(opt, name, data, size); free(data); + free(to_free); return hit; } @@ -674,6 +697,8 @@ static int grep_file(struct grep_opt *opt, const char *filename) return 0; } close(i); + if (opt->relative && opt->prefix_length) + filename += opt->prefix_length; i = grep_buffer(opt, filename, data, st.st_size); free(data); return i; @@ -720,7 +745,7 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached) char *argptr = randarg; struct grep_pat *p; - if (opt->extended) + if (opt->extended || (opt->relative && opt->prefix_length)) return -1; len = nr = 0; push_arg("grep"); @@ -845,7 +870,7 @@ static int grep_cache(struct grep_opt *opt, const char **paths, int cached) if (!pathspec_matches(paths, ce->name)) continue; if (cached) - hit |= grep_sha1(opt, ce->sha1, ce->name); + hit |= grep_sha1(opt, ce->sha1, ce->name, 0); else hit |= grep_file(opt, ce->name); } @@ -860,11 +885,12 @@ static int grep_tree(struct grep_opt *opt, const char **paths, int hit = 0; struct name_entry entry; char *down; - char *path_buf = xmalloc(PATH_MAX + strlen(tree_name) + 100); + int tn_len = strlen(tree_name); + char *path_buf = xmalloc(PATH_MAX + tn_len + 100); - if (tree_name[0]) { - int offset = sprintf(path_buf, "%s:", tree_name); - down = path_buf + offset; + if (tn_len) { + tn_len = sprintf(path_buf, "%s:", tree_name); + down = path_buf + tn_len; strcat(down, base); } else { @@ -886,7 +912,7 @@ static int grep_tree(struct grep_opt *opt, const char **paths, if (!pathspec_matches(paths, down)) ; else if (S_ISREG(entry.mode)) - hit |= grep_sha1(opt, entry.sha1, path_buf); + hit |= grep_sha1(opt, entry.sha1, path_buf, tn_len); else if (S_ISDIR(entry.mode)) { char type[20]; struct tree_desc sub; @@ -907,7 +933,7 @@ static int grep_object(struct grep_opt *opt, const char **paths, struct object *obj, const char *name) { if (obj->type == OBJ_BLOB) - return grep_sha1(opt, obj->sha1, name); + return grep_sha1(opt, obj->sha1, name, 0); if (obj->type == OBJ_COMMIT || obj->type == OBJ_TREE) { struct tree_desc tree; void *data; @@ -945,6 +971,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix) int i; memset(&opt, 0, sizeof(opt)); + opt.prefix_length = (prefix && *prefix) ? strlen(prefix) : 0; + opt.relative = 1; opt.pattern_tail = &opt.pattern_list; opt.regflags = REG_NEWLINE; @@ -1118,6 +1146,10 @@ int cmd_grep(int argc, const char **argv, const char *prefix) } die(emsg_missing_argument, arg); } + if (!strcmp("--full-name", arg)) { + opt.relative = 0; + continue; + } if (!strcmp("--", arg)) { /* later processing wants to have this at argv[1] */ argv--; @@ -1176,8 +1208,15 @@ int cmd_grep(int argc, const char **argv, const char *prefix) verify_filename(prefix, argv[j]); } - if (i < argc) + if (i < argc) { paths = get_pathspec(prefix, argv + i); + if (opt.prefix_length && opt.relative) { + /* Make sure we do not get outside of paths */ + for (i = 0; paths[i]; i++) + if (strncmp(prefix, paths[i], opt.prefix_length)) + die("git-grep: cannot generate relative filenames containing '..'"); + } + } else if (prefix) { paths = xcalloc(2, sizeof(const char *)); paths[0] = prefix; diff --git a/t/t7002-grep.sh b/t/t7002-grep.sh index 00a7d762ce..6bfb899ed1 100755 --- a/t/t7002-grep.sh +++ b/t/t7002-grep.sh @@ -3,7 +3,7 @@ # Copyright (c) 2006 Junio C Hamano # -test_description='git grep -w +test_description='git grep various. ' . ./test-lib.sh @@ -19,7 +19,9 @@ test_expect_success setup ' echo x x xx x >x && echo y yy >y && echo zzz > z && - git add file x y z && + mkdir t && + echo test >t/t && + git add file x y z t/t && git commit -m initial ' @@ -80,6 +82,31 @@ do diff expected actual fi ' + + test_expect_success "grep $L (t-1)" ' + echo "${HC}t/t:1:test" >expected && + git grep -n -e test $H >actual && + diff expected actual + ' + + test_expect_success "grep $L (t-2)" ' + echo "${HC}t:1:test" >expected && + ( + cd t && + git grep -n -e test $H + ) >actual && + diff expected actual + ' + + test_expect_success "grep $L (t-3)" ' + echo "${HC}t/t:1:test" >expected && + ( + cd t && + git grep --full-name -n -e test $H + ) >actual && + diff expected actual + ' + done test_done From e77235ea38385a127d2afc969435a56d3ff2b16d Mon Sep 17 00:00:00 2001 From: Luben Tuikov Date: Sun, 13 Aug 2006 00:34:37 -0700 Subject: [PATCH 094/160] Fix regex pattern in commit-msg Between the count and the line output, some uniq(1) versions put a TAB character, not a space. Make sure both are handled. Signed-off-by: Luben Tuikov Signed-off-by: Junio C Hamano --- templates/hooks--commit-msg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/hooks--commit-msg b/templates/hooks--commit-msg index 643822d235..23617f3906 100644 --- a/templates/hooks--commit-msg +++ b/templates/hooks--commit-msg @@ -11,4 +11,4 @@ # This example catches duplicate Signed-off-by lines. test "" = "$(grep '^Signed-off-by: ' "$1" | - sort | uniq -c | sed -e '/^[ ]*1 /d')" + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" From 9a1ae9ab03abaffc977421f182997f3e735e7098 Mon Sep 17 00:00:00 2001 From: Luben Tuikov Date: Sun, 13 Aug 2006 01:41:22 -0700 Subject: [PATCH 095/160] sample commit-msg hook: no silent exit on duplicate Signed-off-by lines git-commit would silently exit if duplicate Signed-off-by lines were found. Users of git-commit would not know it, unless they checked '$?'. This patch makes git-commit actually print out a message that nothing was commited since duplicate Signed-off-lines were found. Signed-off-by: Luben Tuikov Signed-off-by: Junio C Hamano --- templates/hooks--commit-msg | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/templates/hooks--commit-msg b/templates/hooks--commit-msg index 23617f3906..0b906caa98 100644 --- a/templates/hooks--commit-msg +++ b/templates/hooks--commit-msg @@ -11,4 +11,8 @@ # This example catches duplicate Signed-off-by lines. test "" = "$(grep '^Signed-off-by: ' "$1" | - sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} + From 89b0c4b5a3a9d026d9adb30d4e896965e480725e Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 13 Aug 2006 19:19:34 -0700 Subject: [PATCH 096/160] Fix type of combine-diff.c::show_patch_diff() The other function, show_raw_diff() is void and no callers use return value from neither. Signed-off-by: Junio C Hamano --- combine-diff.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/combine-diff.c b/combine-diff.c index ba8baca0ab..f2f3806477 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -609,15 +609,15 @@ static void dump_quoted_path(const char *prefix, const char *path, printf("%s\n", c_reset); } -static int show_patch_diff(struct combine_diff_path *elem, int num_parent, - int dense, struct rev_info *rev) +static void show_patch_diff(struct combine_diff_path *elem, int num_parent, + int dense, struct rev_info *rev) { struct diff_options *opt = &rev->diffopt; unsigned long result_size, cnt, lno; char *result, *cp; struct sline *sline; /* survived lines */ int mode_differs = 0; - int i, show_hunks, shown_header = 0; + int i, show_hunks; int working_tree_file = !memcmp(elem->sha1, null_sha1, 20); int abbrev = opt->full_index ? 40 : DEFAULT_ABBREV; mmfile_t result_file; @@ -769,7 +769,6 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent, } free(sline[0].p_lno); free(sline); - return shown_header; } #define COLONS "::::::::::::::::::::::::::::::::" @@ -837,11 +836,10 @@ void show_combined_diff(struct combine_diff_path *p, return; if (opt->output_format & (DIFF_FORMAT_RAW | DIFF_FORMAT_NAME | - DIFF_FORMAT_NAME_STATUS)) { + DIFF_FORMAT_NAME_STATUS)) show_raw_diff(p, num_parent, rev); - } else if (opt->output_format & DIFF_FORMAT_PATCH) { + else if (opt->output_format & DIFF_FORMAT_PATCH) show_patch_diff(p, num_parent, dense, rev); - } } void diff_tree_combined(const unsigned char *sha1, From c35f4c371ac12f4d29b08e46c519ddc0a6494f6e Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Sun, 13 Aug 2006 11:30:27 -0700 Subject: [PATCH 097/160] Add a newline before appending "Signed-off-by: " line Whef the last line of the commit log message does not end with "^[-A-Za-z]+: [^@]+@", append a newline after it to separate the body of the commit log message from the run of sign-off and ack lines. e.g. "Signed-off-by: A U Thor " or "Acked-by: Me ". Signed-off-by: Junio C Hamano --- log-tree.c | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/log-tree.c b/log-tree.c index 05ede0c175..031af88933 100644 --- a/log-tree.c +++ b/log-tree.c @@ -19,7 +19,7 @@ static int append_signoff(char *buf, int buf_sz, int at, const char *signoff) char *cp = buf; /* Do we have enough space to add it? */ - if (buf_sz - at <= strlen(signed_off_by) + signoff_len + 2) + if (buf_sz - at <= strlen(signed_off_by) + signoff_len + 3) return at; /* First see if we already have the sign-off by the signer */ @@ -34,6 +34,48 @@ static int append_signoff(char *buf, int buf_sz, int at, const char *signoff) return at; /* we already have him */ } + /* Does the last line already end with "^[-A-Za-z]+: [^@]+@"? + * If not, add a blank line to separate the message from + * the run of Signed-off-by: and Acked-by: lines. + */ + { + char ch; + int seen_colon, seen_at, seen_name, seen_head, not_signoff; + seen_colon = 0; + seen_at = 0; + seen_name = 0; + seen_head = 0; + not_signoff = 0; + cp = buf + at; + while (buf <= --cp && (ch = *cp) == '\n') + ; + while (!not_signoff && buf <= cp && (ch = *cp--) != '\n') { + if (!seen_at) { + if (ch == '@') + seen_at = 1; + continue; + } + if (!seen_colon) { + if (ch == '@') + not_signoff = 1; + else if (ch == ':') + seen_colon = 1; + else + seen_name = 1; + continue; + } + if (('A' <= ch && ch <= 'Z') || + ('a' <= ch && ch <= 'z') || + ch == '-') { + seen_head = 1; + continue; + } + not_signoff = 1; + } + if (not_signoff || !seen_head || !seen_name) + buf[at++] = '\n'; + } + strcpy(buf + at, signed_off_by); at += strlen(signed_off_by); strcpy(buf + at, signoff); From 847e01fb00872401c093957c2d6dd908aa8af30d Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Mon, 14 Aug 2006 02:05:47 +0200 Subject: [PATCH 098/160] gitweb: Great subroutines renaming Rename some of subroutines to better reflect what they do. Some renames were not performed because subroutine name reflects hash key. Subroutines name guideline: * git_ prefix for subroutines related to git commands, git repository, or to gitweb actions * git_get_ prefix for inner subroutines calling git command or reading some file in the repository and returning some output * parse_ prefix for subroutines parsing some text (or reading and parsing some text) into hash or list * format_ prefix for subroutines formatting, post-processing or generating some HTML/text fragment * _get_ infix for subroutines which return result * _print_ infix for subroutines which print fragment of output * _body suffix for subroutines which outputs main part (body) of related action (usually table) * _nav suffix for subroutines related to navigation bars * _div suffix for subroutines returning or printing div element * subroutine names should not be based on how the result is obtained, as this might change easily Renames performed: - git_get_referencing => format_ref_marker - git_get_paging_nav => format_paging_nav - git_read_head => git_get_head_hash - git_read_hash => git_get_hash_by_ref - git_read_description => git_get_project_description - git_read_projects => git_get_projects_list - read_info_ref => git_get_references - git_read_refs => git_get_refs_list - date_str => parse_date - git_read_tag => parse_tag - git_read_commit => parse_commit - git_blob_plain_mimetype => blob_mimetype - git_page_nav => git_print_page_nav - git_header_div => git_print_header_div Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 250 ++++++++++++++++++++++----------------------- 1 file changed, 125 insertions(+), 125 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 626fcc9201..28df59e6be 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -362,7 +362,7 @@ sub format_log_line_html { } # format marker of refs pointing to given object -sub git_get_referencing { +sub format_ref_marker { my ($refs, $id) = @_; if (defined $refs->{$id}) { @@ -376,7 +376,7 @@ sub git_get_referencing { ## git utility subroutines, invoking git commands # get HEAD ref of given project as hash -sub git_read_head { +sub git_get_head_hash { my $project = shift; my $oENV = $ENV{'GIT_DIR'}; my $retval = undef; @@ -445,7 +445,7 @@ sub git_get_hash_by_path { ## git utility functions, directly accessing git repository # assumes that PATH is not symref -sub git_read_hash { +sub git_get_hash_by_ref { my $path = shift; open my $fd, "$projectroot/$path" or return undef; @@ -457,7 +457,7 @@ sub git_read_hash { } } -sub git_read_description { +sub git_get_project_description { my $path = shift; open my $fd, "$projectroot/$path/description" or return undef; @@ -467,7 +467,7 @@ sub git_read_description { return $descr; } -sub git_read_projects { +sub git_get_projects_list { my @list; if (-d $projects_list) { @@ -511,7 +511,7 @@ sub git_read_projects { return @list; } -sub read_info_ref { +sub git_get_references { my $type = shift || ""; my %refs; # 5dc01c595e6c6ec9ccda4f6f69c131c0dd945f8c refs/tags/v2.6.11 @@ -536,7 +536,7 @@ sub read_info_ref { ## ---------------------------------------------------------------------- ## parse to hash functions -sub date_str { +sub parse_date { my $epoch = shift; my $tz = shift || "-0000"; @@ -561,7 +561,7 @@ sub date_str { return %date; } -sub git_read_tag { +sub parse_tag { my $tag_id = shift; my %tag; my @comment; @@ -596,7 +596,7 @@ sub git_read_tag { return %tag } -sub git_read_commit { +sub parse_commit { my $commit_id = shift; my $commit_text = shift; @@ -693,7 +693,7 @@ sub git_read_commit { ## ...................................................................... ## parse to array of hashes functions -sub git_read_refs { +sub git_get_refs_list { my $ref_dir = shift; my @reflist; @@ -707,7 +707,7 @@ sub git_read_refs { }, "$projectroot/$project/$ref_dir"); foreach my $ref_file (@refs) { - my $ref_id = git_read_hash("$project/$ref_dir/$ref_file"); + my $ref_id = git_get_hash_by_ref("$project/$ref_dir/$ref_file"); my $type = git_get_type($ref_id) || next; my %ref_item; my %co; @@ -716,10 +716,10 @@ sub git_read_refs { $ref_item{'epoch'} = 0; $ref_item{'age'} = "unknown"; if ($type eq "tag") { - my %tag = git_read_tag($ref_id); + my %tag = parse_tag($ref_id); $ref_item{'comment'} = $tag{'comment'}; if ($tag{'type'} eq "commit") { - %co = git_read_commit($tag{'object'}); + %co = parse_commit($tag{'object'}); $ref_item{'epoch'} = $co{'committer_epoch'}; $ref_item{'age'} = $co{'age_string'}; } elsif (defined($tag{'epoch'})) { @@ -731,7 +731,7 @@ sub git_read_refs { $ref_item{'name'} = $tag{'name'}; $ref_item{'refid'} = $tag{'object'}; } elsif ($type eq "commit"){ - %co = git_read_commit($ref_id); + %co = parse_commit($ref_id); $ref_item{'reftype'} = "commit"; $ref_item{'name'} = $ref_file; $ref_item{'title'} = $co{'title'}; @@ -806,7 +806,7 @@ sub mimetype_guess { return $mime; } -sub git_blob_plain_mimetype { +sub blob_mimetype { my $fd = shift; my $filename = shift; @@ -925,7 +925,7 @@ EOF sub git_footer_html { print "
\n"; if (defined $project) { - my $descr = git_read_description($project); + my $descr = git_get_project_description($project); if (defined $descr) { print "\n"; } @@ -955,7 +955,7 @@ sub die_error { ## ---------------------------------------------------------------------- ## functions printing or outputting HTML: navigation -sub git_page_nav { +sub git_print_page_nav { my ($current, $suppress, $head, $treehead, $treebase, $extra) = @_; $extra = '' if !defined $extra; # pager or formats @@ -989,7 +989,7 @@ sub git_page_nav { "
\n"; } -sub git_get_paging_nav { +sub format_paging_nav { my ($action, $hash, $head, $page, $nrevs) = @_; my $paging_nav; @@ -1022,7 +1022,7 @@ sub git_get_paging_nav { ## ...................................................................... ## functions printing or outputting HTML: div -sub git_header_div { +sub git_print_header_div { my ($action, $title, $hash, $hash_base) = @_; my $rest = ''; @@ -1062,9 +1062,9 @@ sub git_shortlog_body { my $alternate = 0; for (my $i = $from; $i <= $to; $i++) { my $commit = $revlist->[$i]; - #my $ref = defined $refs ? git_get_referencing($refs, $commit) : ''; - my $ref = git_get_referencing($refs, $commit); - my %co = git_read_commit($commit); + #my $ref = defined $refs ? format_ref_marker($refs, $commit) : ''; + my $ref = format_ref_marker($refs, $commit); + my %co = parse_commit($commit); if ($alternate) { print "
\n" . @@ -1418,24 +1418,24 @@ sub git_summary { "\n" . "
last change$cd{'rfc2822'}
\n"; - open my $fd, "-|", $GIT, "rev-list", "--max-count=17", git_read_head($project) + open my $fd, "-|", $GIT, "rev-list", "--max-count=17", git_get_head_hash($project) or die_error(undef, "Open git-rev-list failed"); my @revlist = map { chomp; $_ } <$fd>; close $fd; - git_header_div('shortlog'); + git_print_header_div('shortlog'); git_shortlog_body(\@revlist, 0, 15, $refs, $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog")}, "...")); - my $taglist = git_read_refs("refs/tags"); + my $taglist = git_get_refs_list("refs/tags"); if (defined @$taglist) { - git_header_div('tags'); + git_print_header_div('tags'); git_tags_body($taglist, 0, 15, $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tags")}, "...")); } - my $headlist = git_read_refs("refs/heads"); + my $headlist = git_get_refs_list("refs/heads"); if (defined @$headlist) { - git_header_div('heads'); + git_print_header_div('heads'); git_heads_body($headlist, $head, 0, 15, $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=heads")}, "...")); } @@ -1444,11 +1444,11 @@ sub git_summary { } sub git_tag { - my $head = git_read_head($project); + my $head = git_get_head_hash($project); git_header_html(); - git_page_nav('','', $head,undef,$head); - my %tag = git_read_tag($hash); - git_header_div('commit', esc_html($tag{'name'}), $hash); + git_print_page_nav('','', $head,undef,$head); + my %tag = parse_tag($hash); + git_print_header_div('commit', esc_html($tag{'name'}), $hash); print "
\n" . "\n" . "\n" . @@ -1457,7 +1457,7 @@ sub git_tag { "\n" . "\n"; if (defined($tag{'author'})) { - my %ad = date_str($tag{'epoch'}, $tag{'tz'}); + my %ad = parse_date($tag{'epoch'}, $tag{'tz'}); print "\n"; print "\n"; } @@ -1477,9 +1477,9 @@ sub git_blame2 { my $ftype; die_error(undef, "Permission denied") if (!git_get_project_config_bool ('blame')); die_error('404 Not Found', "File name not defined") if (!$file_name); - $hash_base ||= git_read_head($project); + $hash_base ||= git_get_head_hash($project); die_error(undef, "Couldn't find base commit") unless ($hash_base); - my %co = git_read_commit($hash_base) + my %co = parse_commit($hash_base) or die_error(undef, "Reading commit failed"); if (!defined $hash) { $hash = git_get_hash_by_path($hash_base, $file_name, "blob") @@ -1495,8 +1495,8 @@ sub git_blame2 { my $formats_nav = $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$hash;hb=$hash_base;f=$file_name")}, "blob") . " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;f=$file_name")}, "head"); - git_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); - git_header_div('commit', esc_html($co{'title'}), $hash_base); + git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); + git_print_header_div('commit', esc_html($co{'title'}), $hash_base); git_print_page_path($file_name, $ftype); my @rev_color = (qw(light2 dark2)); my $num_colors = scalar(@rev_color); @@ -1535,9 +1535,9 @@ sub git_blame { my $fd; die_error('403 Permission denied', "Permission denied") if (!git_get_project_config_bool ('blame')); die_error('404 Not Found', "File name not defined") if (!$file_name); - $hash_base ||= git_read_head($project); + $hash_base ||= git_get_head_hash($project); die_error(undef, "Couldn't find base commit") unless ($hash_base); - my %co = git_read_commit($hash_base) + my %co = parse_commit($hash_base) or die_error(undef, "Reading commit failed"); if (!defined $hash) { $hash = git_get_hash_by_path($hash_base, $file_name, "blob") @@ -1549,8 +1549,8 @@ sub git_blame { my $formats_nav = $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$hash;hb=$hash_base;f=$file_name")}, "blob") . " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;f=$file_name")}, "head"); - git_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); - git_header_div('commit', esc_html($co{'title'}), $hash_base); + git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); + git_print_header_div('commit', esc_html($co{'title'}), $hash_base); git_print_page_path($file_name, 'blob'); print "
\n"; print <a({-href => "$my_uri?" . esc_param("p=$project;a=blame;h=$hash;hb=$hash_base;f=$file_name")}, "blame") . " | "; @@ -1707,8 +1707,8 @@ sub git_blob { } else { $formats_nav .= $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;h=$hash")}, "plain"); } - git_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); - git_header_div('commit', esc_html($co{'title'}), $hash_base); + git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); + git_print_header_div('commit', esc_html($co{'title'}), $hash_base); } else { print "
\n" . "

\n" . @@ -1730,7 +1730,7 @@ sub git_blob { sub git_tree { if (!defined $hash) { - $hash = git_read_head($project); + $hash = git_get_head_hash($project); if (defined $file_name) { my $base = $hash_base || $hash; $hash = git_get_hash_by_path($base, $file_name, "tree"); @@ -1746,16 +1746,16 @@ sub git_tree { close $fd or die_error(undef, "Reading tree failed"); $/ = "\n"; - my $refs = read_info_ref(); - my $ref = git_get_referencing($refs, $hash_base); + my $refs = git_get_references(); + my $ref = format_ref_marker($refs, $hash_base); git_header_html(); my $base_key = ""; my $base = ""; my $have_blame = git_get_project_config_bool ('blame'); - if (defined $hash_base && (my %co = git_read_commit($hash_base))) { + if (defined $hash_base && (my %co = parse_commit($hash_base))) { $base_key = ";hb=$hash_base"; - git_page_nav('tree','', $hash_base); - git_header_div('commit', esc_html($co{'title'}) . $ref, $hash_base); + git_print_page_nav('tree','', $hash_base); + git_print_header_div('commit', esc_html($co{'title'}) . $ref, $hash_base); } else { print "
\n"; print "

\n"; @@ -1811,14 +1811,14 @@ sub git_tree { } sub git_log { - my $head = git_read_head($project); + my $head = git_get_head_hash($project); if (!defined $hash) { $hash = $head; } if (!defined $page) { $page = 0; } - my $refs = read_info_ref(); + my $refs = git_get_references(); my $limit = sprintf("--max-count=%i", (100 * ($page+1))); open my $fd, "-|", $GIT, "rev-list", $limit, $hash @@ -1826,24 +1826,24 @@ sub git_log { my @revlist = map { chomp; $_ } <$fd>; close $fd; - my $paging_nav = git_get_paging_nav('log', $hash, $head, $page, $#revlist); + my $paging_nav = format_paging_nav('log', $hash, $head, $page, $#revlist); git_header_html(); - git_page_nav('log','', $hash,undef,undef, $paging_nav); + git_print_page_nav('log','', $hash,undef,undef, $paging_nav); if (!@revlist) { - my %co = git_read_commit($hash); + my %co = parse_commit($hash); - git_header_div('summary', $project); + git_print_header_div('summary', $project); print "
Last change $co{'age_string'}.

\n"; } for (my $i = ($page * 100); $i <= $#revlist; $i++) { my $commit = $revlist[$i]; - my $ref = git_get_referencing($refs, $commit); - my %co = git_read_commit($commit); + my $ref = format_ref_marker($refs, $commit); + my %co = parse_commit($commit); next if !%co; - my %ad = date_str($co{'author_epoch'}); - git_header_div('commit', + my %ad = parse_date($co{'author_epoch'}); + git_print_header_div('commit', "$co{'age_string'}" . esc_html($co{'title'}) . $ref, $commit); @@ -1881,12 +1881,12 @@ sub git_log { } sub git_commit { - my %co = git_read_commit($hash); + my %co = parse_commit($hash); if (!%co) { die_error(undef, "Unknown commit object"); } - my %ad = date_str($co{'author_epoch'}, $co{'author_tz'}); - my %cd = date_str($co{'committer_epoch'}, $co{'committer_tz'}); + my %ad = parse_date($co{'author_epoch'}, $co{'author_tz'}); + my %cd = parse_date($co{'committer_epoch'}, $co{'committer_tz'}); my $parent = $co{'parent'}; if (!defined $parent) { @@ -1902,22 +1902,22 @@ sub git_commit { if ($hash =~ m/^[0-9a-fA-F]{40}$/) { $expires = "+1d"; } - my $refs = read_info_ref(); - my $ref = git_get_referencing($refs, $co{'id'}); + my $refs = git_get_references(); + my $ref = format_ref_marker($refs, $co{'id'}); my $formats_nav = ''; if (defined $file_name && defined $co{'parent'}) { my $parent = $co{'parent'}; $formats_nav .= $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;hb=$parent;f=$file_name")}, "blame"); } git_header_html(undef, $expires); - git_page_nav('commit', defined $co{'parent'} ? '' : 'commitdiff', + git_print_page_nav('commit', defined $co{'parent'} ? '' : 'commitdiff', $hash, $co{'tree'}, $hash, $formats_nav); if (defined $co{'parent'}) { - git_header_div('commitdiff', esc_html($co{'title'}) . $ref, $hash); + git_print_header_div('commitdiff', esc_html($co{'title'}) . $ref, $hash); } else { - git_header_div('tree', esc_html($co{'title'}) . $ref, $co{'tree'}, $hash); + git_print_header_div('tree', esc_html($co{'title'}) . $ref, $co{'tree'}, $hash); } print "
\n" . "
" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$tag{'type'};h=$tag{'object'}")}, $tag{'type'}) . "
author" . esc_html($tag{'author'}) . "
" . $ad{'rfc2822'} . sprintf(" (%02d:%02d %s)", $ad{'hour_local'}, $ad{'minute_local'}, $ad{'tz_local'}) . "
\n"; @@ -2079,11 +2079,11 @@ sub git_commit { sub git_blobdiff { mkdir($git_temp, 0700); git_header_html(); - if (defined $hash_base && (my %co = git_read_commit($hash_base))) { + if (defined $hash_base && (my %co = parse_commit($hash_base))) { my $formats_nav = $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blobdiff_plain;h=$hash;hp=$hash_parent")}, "plain"); - git_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); - git_header_div('commit', esc_html($co{'title'}), $hash_base); + git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); + git_print_header_div('commit', esc_html($co{'title'}), $hash_base); } else { print "
\n" . "

\n" . @@ -2109,7 +2109,7 @@ sub git_blobdiff_plain { sub git_commitdiff { mkdir($git_temp, 0700); - my %co = git_read_commit($hash); + my %co = parse_commit($hash); if (!%co) { die_error(undef, "Unknown commit object"); } @@ -2126,13 +2126,13 @@ sub git_commitdiff { if ($hash =~ m/^[0-9a-fA-F]{40}$/) { $expires = "+1d"; } - my $refs = read_info_ref(); - my $ref = git_get_referencing($refs, $co{'id'}); + my $refs = git_get_references(); + my $ref = format_ref_marker($refs, $co{'id'}); my $formats_nav = $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff_plain;h=$hash;hp=$hash_parent")}, "plain"); git_header_html(undef, $expires); - git_page_nav('commitdiff','', $hash,$co{'tree'},$hash, $formats_nav); - git_header_div('commit', esc_html($co{'title'}) . $ref, $hash); + git_print_page_nav('commitdiff','', $hash,$co{'tree'},$hash, $formats_nav); + git_print_header_div('commit', esc_html($co{'title'}) . $ref, $hash); print "
\n"; my $comment = $co{'comment'}; my $empty = 0; @@ -2200,7 +2200,7 @@ sub git_commitdiff { sub git_commitdiff_plain { mkdir($git_temp, 0700); - my %co = git_read_commit($hash); + my %co = parse_commit($hash); if (!%co) { die_error(undef, "Unknown commit object"); } @@ -2214,7 +2214,7 @@ sub git_commitdiff_plain { # try to figure out the next tag after this commit my $tagname; - my $refs = read_info_ref("tags"); + my $refs = git_get_references("tags"); open $fd, "-|", $GIT, "rev-list", "HEAD"; my @commits = map { chomp; $_ } <$fd>; close $fd; @@ -2228,7 +2228,7 @@ sub git_commitdiff_plain { } print $cgi->header(-type => "text/plain", -charset => 'utf-8', '-content-disposition' => "inline; filename=\"git-$hash.patch\""); - my %ad = date_str($co{'author_epoch'}, $co{'author_tz'}); + my %ad = parse_date($co{'author_epoch'}, $co{'author_tz'}); my $comment = $co{'comment'}; print "From: $co{'author'}\n" . "Date: $ad{'rfc2822'} ($ad{'tz_local'})\n". @@ -2264,17 +2264,17 @@ sub git_commitdiff_plain { sub git_history { if (!defined $hash_base) { - $hash_base = git_read_head($project); + $hash_base = git_get_head_hash($project); } my $ftype; - my %co = git_read_commit($hash_base); + my %co = parse_commit($hash_base); if (!%co) { die_error(undef, "Unknown commit object"); } - my $refs = read_info_ref(); + my $refs = git_get_references(); git_header_html(); - git_page_nav('','', $hash_base,$co{'tree'},$hash_base); - git_header_div('commit', esc_html($co{'title'}), $hash_base); + git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base); + git_print_header_div('commit', esc_html($co{'title'}), $hash_base); if (!defined $hash && defined $file_name) { $hash = git_get_hash_by_path($hash_base, $file_name); } @@ -2290,11 +2290,11 @@ sub git_history { while (my $line = <$fd>) { if ($line =~ m/^([0-9a-fA-F]{40})/){ my $commit = $1; - my %co = git_read_commit($commit); + my %co = parse_commit($commit); if (!%co) { next; } - my $ref = git_get_referencing($refs, $commit); + my $ref = format_ref_marker($refs, $commit); if ($alternate) { print "
\n"; } else { @@ -2330,9 +2330,9 @@ sub git_search { die_error(undef, "Text field empty"); } if (!defined $hash) { - $hash = git_read_head($project); + $hash = git_get_head_hash($project); } - my %co = git_read_commit($hash); + my %co = parse_commit($hash); if (!%co) { die_error(undef, "Unknown commit object"); } @@ -2351,8 +2351,8 @@ sub git_search { $pickaxe_search = 1; } git_header_html(); - git_page_nav('','', $hash,$co{'tree'},$hash); - git_header_div('commit', esc_html($co{'title'}), $hash); + git_print_page_nav('','', $hash,$co{'tree'},$hash); + git_print_header_div('commit', esc_html($co{'title'}), $hash); print "
\n"; my $alternate = 0; @@ -2370,7 +2370,7 @@ sub git_search { next; } my @commit_lines = split "\n", $commit_text; - my %co = git_read_commit(undef, \@commit_lines); + my %co = parse_commit(undef, \@commit_lines); if (!%co) { next; } @@ -2451,7 +2451,7 @@ sub git_search { print "\n" . "\n"; } - %co = git_read_commit($1); + %co = parse_commit($1); } } close $fd; @@ -2461,14 +2461,14 @@ sub git_search { } sub git_shortlog { - my $head = git_read_head($project); + my $head = git_get_head_hash($project); if (!defined $hash) { $hash = $head; } if (!defined $page) { $page = 0; } - my $refs = read_info_ref(); + my $refs = git_get_references(); my $limit = sprintf("--max-count=%i", (100 * ($page+1))); open my $fd, "-|", $GIT, "rev-list", $limit, $hash @@ -2476,7 +2476,7 @@ sub git_shortlog { my @revlist = map { chomp; $_ } <$fd>; close $fd; - my $paging_nav = git_get_paging_nav('shortlog', $hash, $head, $page, $#revlist); + my $paging_nav = format_paging_nav('shortlog', $hash, $head, $page, $#revlist); my $next_link = ''; if ($#revlist >= (100 * ($page+1)-1)) { $next_link = @@ -2486,8 +2486,8 @@ sub git_shortlog { git_header_html(); - git_page_nav('shortlog','', $hash,$hash,$hash, $paging_nav); - git_header_div('summary', $project); + git_print_page_nav('shortlog','', $hash,$hash,$hash, $paging_nav); + git_print_header_div('summary', $project); git_shortlog_body(\@revlist, ($page * 100), $#revlist, $refs, $next_link); @@ -2499,7 +2499,7 @@ sub git_shortlog { sub git_rss { # http://www.notestips.com/80256B3A007F2692/1/NAMO5P9UPQ - open my $fd, "-|", $GIT, "rev-list", "--max-count=150", git_read_head($project) + open my $fd, "-|", $GIT, "rev-list", "--max-count=150", git_get_head_hash($project) or die_error(undef, "Open git-rev-list failed"); my @revlist = map { chomp; $_ } <$fd>; close $fd or die_error(undef, "Reading git-rev-list failed"); @@ -2514,12 +2514,12 @@ sub git_rss { for (my $i = 0; $i <= $#revlist; $i++) { my $commit = $revlist[$i]; - my %co = git_read_commit($commit); + my %co = parse_commit($commit); # we read 150, we always show 30 and the ones more recent than 48 hours if (($i >= 20) && ((time - $co{'committer_epoch'}) > 48*60*60)) { last; } - my %cd = date_str($co{'committer_epoch'}); + my %cd = parse_date($co{'committer_epoch'}); open $fd, "-|", $GIT, "diff-tree", '-r', $co{'parent'}, $co{'id'} or next; my @difftree = map { chomp; $_ } <$fd>; close $fd or next; @@ -2556,7 +2556,7 @@ sub git_rss { } sub git_opml { - my @list = git_read_projects(); + my @list = git_get_projects_list(); print $cgi->header(-type => 'text/xml', -charset => 'utf-8'); print "\n". @@ -2569,12 +2569,12 @@ sub git_opml { foreach my $pr (@list) { my %proj = %$pr; - my $head = git_read_head($proj{'path'}); + my $head = git_get_head_hash($proj{'path'}); if (!defined $head) { next; } $ENV{'GIT_DIR'} = "$projectroot/$proj{'path'}"; - my %co = git_read_commit($head); + my %co = parse_commit($head); if (!%co) { next; } From a446d6bb53cb59f559603c411747d7ac5373e326 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Mon, 14 Aug 2006 02:07:00 +0200 Subject: [PATCH 099/160] gitweb: Separate ref parsing in git_get_refs_list into parse_ref Note that for each ref there are usually two calls to git subroutines: first to get the type of ref, second to parse ref if ref is of commit or tag type. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 80 ++++++++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 35 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 28df59e6be..0c4ec92894 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -690,6 +690,49 @@ sub parse_commit { return %co; } +# parse ref from ref_file, given by ref_id, with given type +sub parse_ref { + my $ref_file = shift; + my $ref_id = shift; + my $type = shift || git_get_type($ref_id); + my %ref_item; + + $ref_item{'type'} = $type; + $ref_item{'id'} = $ref_id; + $ref_item{'epoch'} = 0; + $ref_item{'age'} = "unknown"; + if ($type eq "tag") { + my %tag = parse_tag($ref_id); + $ref_item{'comment'} = $tag{'comment'}; + if ($tag{'type'} eq "commit") { + my %co = parse_commit($tag{'object'}); + $ref_item{'epoch'} = $co{'committer_epoch'}; + $ref_item{'age'} = $co{'age_string'}; + } elsif (defined($tag{'epoch'})) { + my $age = time - $tag{'epoch'}; + $ref_item{'epoch'} = $tag{'epoch'}; + $ref_item{'age'} = age_string($age); + } + $ref_item{'reftype'} = $tag{'type'}; + $ref_item{'name'} = $tag{'name'}; + $ref_item{'refid'} = $tag{'object'}; + } elsif ($type eq "commit"){ + my %co = parse_commit($ref_id); + $ref_item{'reftype'} = "commit"; + $ref_item{'name'} = $ref_file; + $ref_item{'title'} = $co{'title'}; + $ref_item{'refid'} = $ref_id; + $ref_item{'epoch'} = $co{'committer_epoch'}; + $ref_item{'age'} = $co{'age_string'}; + } else { + $ref_item{'reftype'} = $type; + $ref_item{'name'} = $ref_file; + $ref_item{'refid'} = $ref_id; + } + + return %ref_item; +} + ## ...................................................................... ## parse to array of hashes functions @@ -709,44 +752,11 @@ sub git_get_refs_list { foreach my $ref_file (@refs) { my $ref_id = git_get_hash_by_ref("$project/$ref_dir/$ref_file"); my $type = git_get_type($ref_id) || next; - my %ref_item; - my %co; - $ref_item{'type'} = $type; - $ref_item{'id'} = $ref_id; - $ref_item{'epoch'} = 0; - $ref_item{'age'} = "unknown"; - if ($type eq "tag") { - my %tag = parse_tag($ref_id); - $ref_item{'comment'} = $tag{'comment'}; - if ($tag{'type'} eq "commit") { - %co = parse_commit($tag{'object'}); - $ref_item{'epoch'} = $co{'committer_epoch'}; - $ref_item{'age'} = $co{'age_string'}; - } elsif (defined($tag{'epoch'})) { - my $age = time - $tag{'epoch'}; - $ref_item{'epoch'} = $tag{'epoch'}; - $ref_item{'age'} = age_string($age); - } - $ref_item{'reftype'} = $tag{'type'}; - $ref_item{'name'} = $tag{'name'}; - $ref_item{'refid'} = $tag{'object'}; - } elsif ($type eq "commit"){ - %co = parse_commit($ref_id); - $ref_item{'reftype'} = "commit"; - $ref_item{'name'} = $ref_file; - $ref_item{'title'} = $co{'title'}; - $ref_item{'refid'} = $ref_id; - $ref_item{'epoch'} = $co{'committer_epoch'}; - $ref_item{'age'} = $co{'age_string'}; - } else { - $ref_item{'reftype'} = $type; - $ref_item{'name'} = $ref_file; - $ref_item{'refid'} = $ref_id; - } + my %ref_item = parse_ref($ref_file, $ref_id, $type); push @reflist, \%ref_item; } - # sort tags by age + # sort refs by age @reflist = sort {$b->{'epoch'} <=> $a->{'epoch'}} @reflist; return \@reflist; } From 17d07443188909ef5f8b8c24043cb6d9fef51bca Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Mon, 14 Aug 2006 02:08:27 +0200 Subject: [PATCH 100/160] gitweb: Refactor printing shortened title in git_shortlog_body and git_tags_body Separate printing of perhaps shortened title (subject) in git_shortlog_body and git_tags_body into format_subject_html. While at it, remove presentation element ... used to format title (subject) and move formatting to CSS. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.css | 5 +++++ gitweb/gitweb.perl | 34 ++++++++++++++++++---------------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css index 47c1ade87e..f58a418fab 100644 --- a/gitweb/gitweb.css +++ b/gitweb/gitweb.css @@ -117,9 +117,14 @@ div.list_head { a.list { text-decoration: none; + font-weight: bold; color: #000000; } +table.tags a.list { + font-weight: normal; +} + a.list:hover { text-decoration: underline; color: #880000; diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 0c4ec92894..c4d6eab779 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -372,6 +372,22 @@ sub format_ref_marker { } } +# format, perhaps shortened and with markers, title line +sub format_subject_html { + my ($long, $short, $query, $extra) = @_; + $extra = '' unless defined($extra); + + if (length($short) < length($long)) { + return $cgi->a({-href => "$my_uri?" . esc_param($query), + -class => "list", -title => $long}, + esc_html($short) . $extra); + } else { + return $cgi->a({-href => "$my_uri?" . esc_param($query), + -class => "list"}, + esc_html($long) . $extra); + } +} + ## ---------------------------------------------------------------------- ## git utility subroutines, invoking git commands @@ -1085,15 +1101,7 @@ sub git_shortlog_body { print "\n" . "\n" . "\n" . "\n" . "\n" . "
$co{'age_string_date'}" . esc_html(chop_str($co{'author_name'}, 10)) . ""; - if (length($co{'title_short'}) < length($co{'title'})) { - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit"), - -class => "list", -title => "$co{'title'}"}, - "" . esc_html($co{'title_short'}) . "$ref"); - } else { - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit"), - -class => "list"}, - "" . esc_html($co{'title'}) . "$ref"); - } + print format_subject_html($co{'title'}, $co{'title_short'}, "p=$project;a=commit;h=$commit", $ref); print "" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit")}, "commit") . " | " . @@ -1139,13 +1147,7 @@ sub git_tags_body { ""; if (defined $comment) { - if (length($comment_short) < length($comment)) { - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}"), - -class => "list", -title => $comment}, $comment_short); - } else { - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}"), - -class => "list"}, $comment); - } + print format_subject_html($comment, $comment_short, "p=$project;a=tag;h=$tag{'id'}"); } print ""; From 581860e1b8ac01c2cdcb5d98862ef7a80e789781 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Mon, 14 Aug 2006 02:09:08 +0200 Subject: [PATCH 101/160] gitweb: Separate main part of git_history into git_history_body Separates main part of git_history into git_history_body subroutine, and makes output more similar to git_shortlog. Adds "diff to current" link only for history of regular file (blob). Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 96 +++++++++++++++++++++++++++++----------------- 1 file changed, 60 insertions(+), 36 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index c4d6eab779..5af6e77e22 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -1117,6 +1117,64 @@ sub git_shortlog_body { print "
\n"; } +sub git_history_body { + # Warning: assumes constant type (blob or tree) during history + my ($fd, $refs, $hash_base, $ftype, $extra) = @_; + + print "\n"; + my $alternate = 0; + while (my $line = <$fd>) { + if ($line !~ m/^([0-9a-fA-F]{40})/) { + next; + } + + my $commit = $1; + my %co = parse_commit($commit); + if (!%co) { + next; + } + + my $ref = format_ref_marker($refs, $commit); + + if ($alternate) { + print "\n"; + } else { + print "\n"; + } + $alternate ^= 1; + print "\n" . + # shortlog uses chop_str($co{'author_name'}, 10) + "\n" . + "\n" . + "\n" . + "\n"; + } + if (defined $extra) { + print "\n" . + "\n" . + "\n"; + } + print "
$co{'age_string_date'}" . esc_html(chop_str($co{'author_name'}, 15, 3)) . ""; + # originally git_history used chop_str($co{'title'}, 50) + print format_subject_html($co{'title'}, $co{'title_short'}, "p=$project;a=commit;h=$commit", $ref); + print "" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit")}, "commit") . " | " . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$commit")}, "commitdiff") . " | " . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$ftype;hb=$commit;f=$file_name")}, $ftype); + + if ($ftype eq 'blob') { + my $blob_current = git_get_hash_by_path($hash_base, $file_name); + my $blob_parent = git_get_hash_by_path($commit, $file_name); + if (defined $blob_current && defined $blob_parent && + $blob_current ne $blob_parent) { + print " | " . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blobdiff;h=$blob_current;hp=$blob_parent;hb=$commit;f=$file_name")}, + "diff to current"); + } + } + print "
$extra
\n"; +} + sub git_tags_body { # uses global variable $project my ($taglist, $from, $to, $extra) = @_; @@ -2297,42 +2355,8 @@ sub git_history { open my $fd, "-|", $GIT, "rev-list", "--full-history", $hash_base, "--", $file_name; - print "\n"; - my $alternate = 0; - while (my $line = <$fd>) { - if ($line =~ m/^([0-9a-fA-F]{40})/){ - my $commit = $1; - my %co = parse_commit($commit); - if (!%co) { - next; - } - my $ref = format_ref_marker($refs, $commit); - if ($alternate) { - print "\n"; - } else { - print "\n"; - } - $alternate ^= 1; - print "\n" . - "\n" . - "\n" . - "\n" . - "\n"; - } - } - print "
$co{'age_string_date'}" . esc_html(chop_str($co{'author_name'}, 15, 3)) . "" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit"), -class => "list"}, "" . - esc_html(chop_str($co{'title'}, 50)) . "$ref") . "" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit")}, "commit") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$commit")}, "commitdiff") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$ftype;hb=$commit;f=$file_name")}, $ftype); - my $blob = git_get_hash_by_path($hash_base, $file_name); - my $blob_parent = git_get_hash_by_path($commit, $file_name); - if (defined $blob && defined $blob_parent && $blob ne $blob_parent) { - print " | " . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blobdiff;h=$blob;hp=$blob_parent;hb=$commit;f=$file_name")}, - "diff to current"); - } - print "
\n"; + git_history_body($fd, $refs, $hash_base, $ftype); + close $fd; git_footer_html(); } From 1e0cf030c047741cab9ef36b91bc2ae57b83e405 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Mon, 14 Aug 2006 02:10:06 +0200 Subject: [PATCH 102/160] gitweb: Separate finding project owner into git_get_project_owner Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 50 +++++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 5af6e77e22..6be6c55009 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -527,6 +527,37 @@ sub git_get_projects_list { return @list; } +sub git_get_project_owner { + my $project = shift; + my $owner; + + return undef unless $project; + + # read from file (url-encoded): + # 'git%2Fgit.git Linus+Torvalds' + # 'libs%2Fklibc%2Fklibc.git H.+Peter+Anvin' + # 'linux%2Fhotplug%2Fudev.git Greg+Kroah-Hartman' + if (-f $projects_list) { + open (my $fd , $projects_list); + while (my $line = <$fd>) { + chomp $line; + my ($pr, $ow) = split ' ', $line; + $pr = unescape($pr); + $ow = unescape($ow); + if ($pr eq $project) { + $owner = decode("utf8", $ow, Encode::FB_DEFAULT); + last; + } + } + close $fd; + } + if (!defined $owner) { + $owner = get_file_owner("$projectroot/$project"); + } + + return $owner; +} + sub git_get_references { my $type = shift || ""; my %refs; @@ -1458,24 +1489,7 @@ sub git_summary { my %co = parse_commit($head); my %cd = parse_date($co{'committer_epoch'}, $co{'committer_tz'}); - my $owner; - if (-f $projects_list) { - open (my $fd , $projects_list); - while (my $line = <$fd>) { - chomp $line; - my ($pr, $ow) = split ' ', $line; - $pr = unescape($pr); - $ow = unescape($ow); - if ($pr eq $project) { - $owner = decode("utf8", $ow, Encode::FB_DEFAULT); - last; - } - } - close $fd; - } - if (!defined $owner) { - $owner = get_file_owner("$projectroot/$project"); - } + my $owner = git_get_project_owner($project); my $refs = git_get_references(); git_header_html(); From d294e1cad4eef263c7f4912332fd0094e37e95a7 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Mon, 14 Aug 2006 02:14:20 +0200 Subject: [PATCH 103/160] gitweb: Change appereance of marker of refs pointing to given object Change git_get_references to include type of ref in the %refs value, which means putting everything after 'refs/' as a ref name, not only last part of the name. Instead of separating refs pointing to the same object by " / " separator, use anonymous array reference to store all refs pointing to given object. Use 'git-ls-remote .' if $projectroot/$project/info/refs does not exist. (Perhaps it should be used always.) Refs are now in separate span elements. Class is dependent on the ref type: currently known classes are 'tag', 'head', 'remote', and 'ref' (last one for HEAD and other refs in the main directory). There is encompassing span element of class refs, just in case of unknown ref type. This might be considered cleaner separating of git_get_references into filling %refs hash only, and not taking part in formatting ref marker. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.css | 19 +++++++++++++++++-- gitweb/gitweb.perl | 37 ++++++++++++++++++++++++++++++------- 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css index f58a418fab..21ce99cc91 100644 --- a/gitweb/gitweb.css +++ b/gitweb/gitweb.css @@ -326,15 +326,30 @@ a.rss_logo:hover { background-color: #ee5500; } -span.tag { +span.refs span { padding: 0px 4px; font-size: 10px; font-weight: normal; - background-color: #ffffaa; border: 1px solid; + background-color: #ffaaff; + border-color: #ffccff #ff00ee #ff00ee #ffccff; +} + +span.refs span.ref { + background-color: #aaaaff; + border-color: #ccccff #0033cc #0033cc #ccccff; +} + +span.refs span.tag { + background-color: #ffffaa; border-color: #ffffcc #ffee00 #ffee00 #ffffcc; } +span.refs span.head { + background-color: #aaffaa; + border-color: #ccffcc #00cc33 #00cc33 #ccffcc; +} + span.atnight { color: #cc0000; } diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 6be6c55009..4fe3fc7b44 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -364,9 +364,26 @@ sub format_log_line_html { # format marker of refs pointing to given object sub format_ref_marker { my ($refs, $id) = @_; + my $markers = ''; if (defined $refs->{$id}) { - return ' ' . esc_html($refs->{$id}) . ''; + foreach my $ref (@{$refs->{$id}}) { + my ($type, $name) = qw(); + # e.g. tags/v2.6.11 or heads/next + if ($ref =~ m!^(.*?)s?/(.*)$!) { + $type = $1; + $name = $2; + } else { + $type = "ref"; + $name = $ref; + } + + $markers .= " " . esc_html($name) . ""; + } + } + + if ($markers) { + return ' '. $markers . ''; } else { return ""; } @@ -561,18 +578,24 @@ sub git_get_project_owner { sub git_get_references { my $type = shift || ""; my %refs; + my $fd; # 5dc01c595e6c6ec9ccda4f6f69c131c0dd945f8c refs/tags/v2.6.11 # c39ae07f393806ccf406ef966e9a15afc43cc36a refs/tags/v2.6.11^{} - open my $fd, "$projectroot/$project/info/refs" or return; + if (-f "$projectroot/$project/info/refs") { + open $fd, "$projectroot/$project/info/refs" + or return; + } else { + open $fd, "-|", $GIT, "ls-remote", "." + or return; + } + while (my $line = <$fd>) { chomp $line; - # attention: for $type == "" it saves only last path part of ref name - # e.g. from 'refs/heads/jn/gitweb' it would leave only 'gitweb' - if ($line =~ m/^([0-9a-fA-F]{40})\t.*$type\/([^\^]+)/) { + if ($line =~ m/^([0-9a-fA-F]{40})\trefs\/($type\/?[^\^]+)/) { if (defined $refs{$1}) { - $refs{$1} .= " / $2"; + push @{$refs{$1}}, $2; } else { - $refs{$1} = $2; + $refs{$1} = [ $2 ]; } } } From 618918e5411e2e769ad5e8d44c5d1cc363b983b5 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Mon, 14 Aug 2006 02:15:22 +0200 Subject: [PATCH 104/160] gitweb: Skip comments in mime.types like file Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 1 + 1 file changed, 1 insertion(+) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 4fe3fc7b44..52ae2aa861 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -858,6 +858,7 @@ sub mimetype_guess_file { my %mimemap; open(MIME, $mimemap) or return undef; while () { + next if m/^#/; # skip comments my ($mime, $exts) = split(/\t+/); if (defined $exts) { my @exts = split(/\s+/, $exts); From d5aa50de621220d7451a5d497479327d2a608009 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Mon, 14 Aug 2006 02:16:33 +0200 Subject: [PATCH 105/160] gitweb: True fix: Support for the standard mime.types map in gitweb True fix for error in mimetype_guess, error introduced in original commit 2d00737489b8c61ed616b261c7c9bd314e2b0b41 and later fixed temporarily by commenting out the line that caused error in commit 57bd4d3523efecf60197040cad34154aff4ddf80. Gitweb now supports mime.types map $mimetypes_file relative to project. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 52ae2aa861..15875a8663 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -880,7 +880,10 @@ sub mimetype_guess { if ($mimetypes_file) { my $file = $mimetypes_file; - #$file =~ m#^/# or $file = "$projectroot/$path/$file"; + if ($file !~ m!^/!) { # if it is relative path + # it is relative to project + $file = "$projectroot/$project/$file"; + } $mime = mimetype_guess_file($filename, $file); } $mime ||= mimetype_guess_file($filename, '/etc/mime.types'); From 4a4a1a53d1c4a272d4cf0d53116896d057174671 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Mon, 14 Aug 2006 02:18:33 +0200 Subject: [PATCH 106/160] gitweb: Separate printing difftree in git_commit into git_difftree_body Separate printing difftree in git_commit into separate git_difftree_body subroutine. Add support for "C" (copied) status. For "M" and "C" add parameter 'fp' (filename parent) to the "diff" link; currently not supported by git_blobdiff ("blobdiff" action). Reindented, realigned, added comments. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.css | 4 + gitweb/gitweb.perl | 237 +++++++++++++++++++++++++++------------------ 2 files changed, 146 insertions(+), 95 deletions(-) diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css index 21ce99cc91..9013895857 100644 --- a/gitweb/gitweb.css +++ b/gitweb/gitweb.css @@ -226,6 +226,10 @@ table.diff_tree span.file_status.mode_chnge { color: #777777; } +table.diff_tree span.file_status.copied { + color: #70a070; +} + /* age2: 60*60*24*2 <= age */ table.project_list td.age2, table.blame td.age2 { font-style: italic; diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 15875a8663..ab28caa8c8 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -1136,6 +1136,145 @@ sub git_print_page_path { ## ...................................................................... ## functions printing large fragments of HTML +sub git_difftree_body { + my ($difftree, $parent) = @_; + + print "
\n"; + if ($#{$difftree} > 10) { + print(($#{$difftree} + 1) . " files changed:\n"); + } + print "
\n"; + + print "\n"; + my $alternate = 0; + foreach my $line (@{$difftree}) { + # ':100644 100644 03b218260e99b78c6df0ed378e59ed9205ccc96d 3b93d5e7cc7f7dd4ebed13a5cc1a4ad976fc94d8 M ls-files.c' + # ':100644 100644 7f9281985086971d3877aca27704f2aaf9c448ce bc190ebc71bbd923f2b728e505408f5e54bd073a M rev-tree.c' + if ($line !~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)([0-9]{0,3})\t(.*)$/) { + next; + } + my $from_mode = $1; + my $to_mode = $2; + my $from_id = $3; + my $to_id = $4; + my $status = $5; + my $similarity = $6; # score + my $file = validate_input(unquote($7)); + + if ($alternate) { + print "\n"; + } else { + print "\n"; + } + $alternate ^= 1; + + if ($status eq "A") { # created + my $mode_chng = ""; + if (S_ISREG(oct $to_mode)) { + $mode_chng = sprintf(" with mode: %04o", (oct $to_mode) & 0777); + } + print "\n" . + "\n" . + "\n"; + + } elsif ($status eq "D") { # deleted + print "\n" . + "\n" . + "\n" + + } elsif ($status eq "M" || $status eq "T") { # modified, or type changed + my $mode_chnge = ""; + if ($from_mode != $to_mode) { + $mode_chnge = " [changed"; + if (((oct $from_mode) & S_IFMT) != ((oct $to_mode) & S_IFMT)) { + $mode_chnge .= " from " . file_type($from_mode) . " to " . file_type($to_mode); + } + if (((oct $from_mode) & 0777) != ((oct $to_mode) & 0777)) { + if (S_ISREG($from_mode) && S_ISREG($to_mode)) { + $mode_chnge .= sprintf(" mode: %04o->%04o", (oct $from_mode) & 0777, (oct $to_mode) & 0777); + } elsif (S_ISREG($to_mode)) { + $mode_chnge .= sprintf(" mode: %04o", (oct $to_mode) & 0777); + } + } + $mode_chnge .= "]\n"; + } + print "\n" . + "\n" . + "\n"; + + } elsif ($status eq "R") { # renamed + my ($from_file, $to_file) = split "\t", $file; + my $mode_chng = ""; + if ($from_mode != $to_mode) { + $mode_chng = sprintf(", mode: %04o", (oct $to_mode) & 0777); + } + print "\n" . + "\n" . + "\n"; + + } elsif ($status eq "C") { # copied + my ($from_file, $to_file) = split "\t", $file; + my $mode_chng = ""; + if ($from_mode != $to_mode) { + $mode_chng = sprintf(", mode: %04o", (oct $to_mode) & 0777); + } + print "\n" . + "\n" . + "\n"; + } # we should not encounter Unmerged (U) or Unknown (X) status + print "\n"; + } + print "
" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$file"), + -class => "list"}, esc_html($file)) . + "[new " . file_type($to_mode) . "$mode_chng]" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$file")}, "blob") . + "" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$parent;f=$file"), + -class => "list"}, esc_html($file)) . "[deleted " . file_type($from_mode). "]" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$parent;f=$file")}, "blob") . " | " . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;hb=$parent;f=$file")}, "history") . + ""; + if ($to_id ne $from_id) { # modified + print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blobdiff;h=$to_id;hp=$from_id;hb=$hash;f=$file"), + -class => "list"}, esc_html($file)); + } else { # mode changed + print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$file"), + -class => "list"}, esc_html($file)); + } + print "$mode_chnge" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$file")}, "blob"); + if ($to_id ne $from_id) { # modified + print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blobdiff;h=$to_id;hp=$from_id;hb=$hash;f=$file")}, "diff"); + } + print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;hb=$hash;f=$file")}, "history") . "\n"; + print "" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$to_file"), + -class => "list"}, esc_html($to_file)) . "[moved from " . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$parent;f=$from_file"), + -class => "list"}, esc_html($from_file)) . + " with " . (int $similarity) . "% similarity$mode_chng]" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$to_file")}, "blob"); + if ($to_id ne $from_id) { + print " | " . + $cgi->a({-href => "$my_uri?" . + esc_param("p=$project;a=blobdiff;h=$to_id;hp=$from_id;hb=$hash;f=$to_file;fp=$from_file")}, "diff"); + } + print "" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$to_file"), + -class => "list"}, esc_html($to_file)) . "[copied from " . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$parent;f=$from_file"), + -class => "list"}, esc_html($from_file)) . + " with " . (int $similarity) . "% similarity$mode_chng]" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$to_file")}, "blob"); + if ($to_id ne $from_id) { + print " | " . + $cgi->a({-href => "$my_uri?" . + esc_param("p=$project;a=blobdiff;h=$to_id;hp=$from_id;hb=$hash;f=$to_file;fp=$from_file")}, "diff"); + } + print "
\n"; +} + sub git_shortlog_body { # uses global variable $project my ($revlist, $from, $to, $refs, $extra) = @_; @@ -2089,101 +2228,9 @@ sub git_commit { } } print "
\n"; - print "
\n"; - if ($#difftree > 10) { - print(($#difftree + 1) . " files changed:\n"); - } - print "
\n"; - print "\n"; - my $alternate = 0; - foreach my $line (@difftree) { - # ':100644 100644 03b218260e99b78c6df0ed378e59ed9205ccc96d 3b93d5e7cc7f7dd4ebed13a5cc1a4ad976fc94d8 M ls-files.c' - # ':100644 100644 7f9281985086971d3877aca27704f2aaf9c448ce bc190ebc71bbd923f2b728e505408f5e54bd073a M rev-tree.c' - if ($line !~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)([0-9]{0,3})\t(.*)$/) { - next; - } - my $from_mode = $1; - my $to_mode = $2; - my $from_id = $3; - my $to_id = $4; - my $status = $5; - my $similarity = $6; - my $file = validate_input(unquote($7)); - if ($alternate) { - print "\n"; - } else { - print "\n"; - } - $alternate ^= 1; - if ($status eq "A") { - my $mode_chng = ""; - if (S_ISREG(oct $to_mode)) { - $mode_chng = sprintf(" with mode: %04o", (oct $to_mode) & 0777); - } - print "\n" . - "\n" . - "\n"; - } elsif ($status eq "D") { - print "\n" . - "\n" . - "\n" - } elsif ($status eq "M" || $status eq "T") { - my $mode_chnge = ""; - if ($from_mode != $to_mode) { - $mode_chnge = " [changed"; - if (((oct $from_mode) & S_IFMT) != ((oct $to_mode) & S_IFMT)) { - $mode_chnge .= " from " . file_type($from_mode) . " to " . file_type($to_mode); - } - if (((oct $from_mode) & 0777) != ((oct $to_mode) & 0777)) { - if (S_ISREG($from_mode) && S_ISREG($to_mode)) { - $mode_chnge .= sprintf(" mode: %04o->%04o", (oct $from_mode) & 0777, (oct $to_mode) & 0777); - } elsif (S_ISREG($to_mode)) { - $mode_chnge .= sprintf(" mode: %04o", (oct $to_mode) & 0777); - } - } - $mode_chnge .= "]\n"; - } - print "\n" . - "\n" . - "\n"; - } elsif ($status eq "R") { - my ($from_file, $to_file) = split "\t", $file; - my $mode_chng = ""; - if ($from_mode != $to_mode) { - $mode_chng = sprintf(", mode: %04o", (oct $to_mode) & 0777); - } - print "\n" . - "\n" . - "\n"; - } - print "\n"; - } - print "
" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$file"), -class => "list"}, esc_html($file)) . "[new " . file_type($to_mode) . "$mode_chng]" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$file")}, "blob") . "" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$parent;f=$file"), -class => "list"}, esc_html($file)) . "[deleted " . file_type($from_mode). "]" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$parent;f=$file")}, "blob") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;hb=$parent;f=$file")}, "history") . - ""; - if ($to_id ne $from_id) { - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blobdiff;h=$to_id;hp=$from_id;hb=$hash;f=$file"), -class => "list"}, esc_html($file)); - } else { - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$file"), -class => "list"}, esc_html($file)); - } - print "$mode_chnge"; - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$file")}, "blob"); - if ($to_id ne $from_id) { - print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blobdiff;h=$to_id;hp=$from_id;hb=$hash;f=$file")}, "diff"); - } - print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;hb=$hash;f=$file")}, "history") . "\n"; - print "" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$to_file"), -class => "list"}, esc_html($to_file)) . "[moved from " . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$parent;f=$from_file"), -class => "list"}, esc_html($from_file)) . - " with " . (int $similarity) . "% similarity$mode_chng]" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$to_file")}, "blob"); - if ($to_id ne $from_id) { - print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blobdiff;h=$to_id;hp=$from_id;hb=$hash;f=$to_file")}, "diff"); - } - print "
\n"; + + git_difftree_body(\@difftree, $parent); + git_footer_html(); } From 2de21fac9842650fceb3db68f15711e38fabc3c8 Mon Sep 17 00:00:00 2001 From: Yasushi SHOJI Date: Tue, 15 Aug 2006 07:50:49 +0900 Subject: [PATCH 107/160] gitweb: configurable home link string I've always found difficult to figure out git URL for clone from gitweb URL because git:// and http:// are different on many site including kernel.org. I've found this enhancement at http://dev.laptop.org/git when I was on git channel, and thought that it'd be nice if all public gitweb site show it's git URL on its page. This patch allow us to change the home link string. The current default is "projects" as we all see on gitweb now. ie. kernel.org might set this variable to "git://git.kernel.org/pub/scm/" Signed-off-by: Yasushi SHOJI Signed-off-by: Junio C Hamano --- Makefile | 2 ++ gitweb/gitweb.perl | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a538710ed6..b363f50d48 100644 --- a/Makefile +++ b/Makefile @@ -123,6 +123,7 @@ GIT_PYTHON_DIR = $(prefix)/share/git-core/python # default configuration for gitweb GITWEB_CONFIG = gitweb_config.perl +GITWEB_HOME_LINK_STR = projects GITWEB_SITENAME = GITWEB_PROJECTROOT = /pub/git GITWEB_LIST = @@ -617,6 +618,7 @@ gitweb/gitweb.cgi: gitweb/gitweb.perl -e 's|++GIT_VERSION++|$(GIT_VERSION)|g' \ -e 's|++GIT_BINDIR++|$(bindir)|g' \ -e 's|++GITWEB_CONFIG++|$(GITWEB_CONFIG)|g' \ + -e 's|++GITWEB_HOME_LINK_STR++|$(GITWEB_HOME_LINK_STR)|g' \ -e 's|++GITWEB_SITENAME++|$(GITWEB_SITENAME)|g' \ -e 's|++GITWEB_PROJECTROOT++|$(GITWEB_PROJECTROOT)|g' \ -e 's|++GITWEB_LIST++|$(GITWEB_LIST)|g' \ diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index ab28caa8c8..b5b89de91b 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -36,6 +36,9 @@ our $git_temp = "/tmp/gitweb"; # target of the home link on top of all pages our $home_link = $my_uri; +# string of the home link on top of all pages +our $home_link_str = "++GITWEB_HOME_LINK_STR++"; + # name of your site or organization to appear in page titles # replace this with something more descriptive for clearer bookmarks our $site_name = "++GITWEB_SITENAME++" || $ENV{'SERVER_NAME'} || "Untitled"; @@ -974,7 +977,7 @@ EOF "" . "\"git\"" . "\n"; - print $cgi->a({-href => esc_param($home_link)}, "projects") . " / "; + print $cgi->a({-href => esc_param($home_link)}, $home_link_str) . " / "; if (defined $project) { print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary")}, esc_html($project)); if (defined $action) { From b4e275992f7ea56b7944abb2b9339c7f6f5c9423 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Mon, 14 Aug 2006 13:18:11 -0700 Subject: [PATCH 108/160] blame.c return cleanup Removes conditional from return Signed-off-by: David Rientjes Signed-off-by: Junio C Hamano --- blame.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/blame.c b/blame.c index 7099b53c72..54a43d5c54 100644 --- a/blame.c +++ b/blame.c @@ -351,10 +351,7 @@ static int fill_util_info(struct commit *commit) assert(util); assert(util->pathname); - if (get_blob_sha1(commit->tree, util->pathname, util->sha1)) - return 1; - else - return 0; + return !!get_blob_sha1(commit->tree, util->pathname, util->sha1); } static void alloc_line_map(struct commit *commit) From b756776d19356a961cc3d1861b15720a6d0e8462 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Mon, 14 Aug 2006 13:22:15 -0700 Subject: [PATCH 109/160] builtin-grep.c cleanup Removes conditional return. Signed-off-by: David Rientjes Signed-off-by: Junio C Hamano --- builtin-grep.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/builtin-grep.c b/builtin-grep.c index a561612e7e..3ec99b7010 100644 --- a/builtin-grep.c +++ b/builtin-grep.c @@ -390,9 +390,7 @@ static int buffer_is_binary(const char *ptr, unsigned long size) { if (FIRST_FEW_BYTES < size) size = FIRST_FEW_BYTES; - if (memchr(ptr, 0, size)) - return 1; - return 0; + return !!memchr(ptr, 0, size); } static int fixmatch(const char *pattern, char *line, regmatch_t *match) From 9e0ec82cac84e6963d7e4aa229b7464daaed4ef8 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Mon, 14 Aug 2006 13:26:58 -0700 Subject: [PATCH 110/160] builtin-push.c cleanup Removes conditional return in builtin-push.c Signed-off-by: David Rientjes Signed-off-by: Junio C Hamano --- builtin-push.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/builtin-push.c b/builtin-push.c index 53bc378f73..c09ff2f65e 100644 --- a/builtin-push.c +++ b/builtin-push.c @@ -32,10 +32,8 @@ static int expand_one_ref(const char *ref, const unsigned char *sha1) /* Ignore the "refs/" at the beginning of the refname */ ref += 5; - if (strncmp(ref, "tags/", 5)) - return 0; - - add_refspec(strdup(ref)); + if (!strncmp(ref, "tags/", 5)) + add_refspec(strdup(ref)); return 0; } From 8c0b2bb636c15a1cd0adb8bcf3b42497d699c884 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Mon, 14 Aug 2006 13:34:16 -0700 Subject: [PATCH 111/160] diff.c cleanup Removes conditional return. Signed-off-by: David Rientjes Signed-off-by: Junio C Hamano --- diff.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/diff.c b/diff.c index 8861b853e7..2327e6065b 100644 --- a/diff.c +++ b/diff.c @@ -904,9 +904,7 @@ static int mmfile_is_binary(mmfile_t *mf) long sz = mf->size; if (FIRST_FEW_BYTES < sz) sz = FIRST_FEW_BYTES; - if (memchr(mf->ptr, 0, sz)) - return 1; - return 0; + return !!memchr(mf->ptr, 0, sz); } static void builtin_diff(const char *name_a, From 0bc87ffb6c8edbb44bd72a4e1a5aa81c64f7eb37 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Mon, 14 Aug 2006 13:37:05 -0700 Subject: [PATCH 112/160] http-push.c cleanup Removes conditional return. Signed-off-by: David Rientjes Signed-off-by: Junio C Hamano --- http-push.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/http-push.c b/http-push.c index 0359ae5b6f..22a3e2bc0a 100644 --- a/http-push.c +++ b/http-push.c @@ -2186,10 +2186,7 @@ static int verify_merge_base(unsigned char *head_sha1, unsigned char *branch_sha struct commit *branch = lookup_commit(branch_sha1); struct commit_list *merge_bases = get_merge_bases(head, branch, 1); - if (merge_bases && !merge_bases->next && merge_bases->item == branch) - return 1; - - return 0; + return (merge_bases && !merge_bases->next && merge_bases->item == branch); } static int delete_remote_branch(char *pattern, int force) From 968a1d65f430e4e8234204c62361e3d21cac810c Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Mon, 14 Aug 2006 13:38:14 -0700 Subject: [PATCH 113/160] read-cache.c cleanup Removes conditional returns. Signed-off-by: David Rientjes Signed-off-by: Junio C Hamano --- read-cache.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/read-cache.c b/read-cache.c index c923a32707..b18f9f72d9 100644 --- a/read-cache.c +++ b/read-cache.c @@ -880,10 +880,8 @@ static int write_index_ext_header(SHA_CTX *context, int fd, { ext = htonl(ext); sz = htonl(sz); - if ((ce_write(context, fd, &ext, 4) < 0) || - (ce_write(context, fd, &sz, 4) < 0)) - return -1; - return 0; + return ((ce_write(context, fd, &ext, 4) < 0) || + (ce_write(context, fd, &sz, 4) < 0)) ? -1 : 0; } static int ce_flush(SHA_CTX *context, int fd) @@ -905,9 +903,7 @@ static int ce_flush(SHA_CTX *context, int fd) /* Append the SHA1 signature at the end */ SHA1_Final(write_buffer + left, context); left += 20; - if (write(fd, write_buffer, left) != left) - return -1; - return 0; + return (write(fd, write_buffer, left) != left) ? -1 : 0; } static void ce_smudge_racily_clean_entry(struct cache_entry *ce) From a976b0a5933f37e7e8a1829703705268bc829794 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 14 Aug 2006 18:36:00 -0700 Subject: [PATCH 114/160] Remove combine-diff.c::uninteresting() A patch from David Rientjes made me realize we do not have to have this function -- just call diff_unmodified_pair() directly. Signed-off-by: Junio C Hamano --- combine-diff.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/combine-diff.c b/combine-diff.c index f2f3806477..4c6bfed56e 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -7,13 +7,6 @@ #include "xdiff-interface.h" #include "log-tree.h" -static int uninteresting(struct diff_filepair *p) -{ - if (diff_unmodified_pair(p)) - return 1; - return 0; -} - static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr, int n, int num_parent) { struct diff_queue_struct *q = &diff_queued_diff; @@ -25,7 +18,7 @@ static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr, for (i = 0; i < q->nr; i++) { int len; const char *path; - if (uninteresting(q->queue[i])) + if (diff_unmodified_pair(q->queue[i])) continue; path = q->queue[i]->two->path; len = strlen(path); @@ -57,7 +50,7 @@ static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr, const char *path; int len; - if (uninteresting(q->queue[i])) + if (diff_unmodified_pair(q->queue[i])) continue; path = q->queue[i]->two->path; len = strlen(path); From eddd1c8cefa596abbb81ac5a0af21ba104033b3d Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Mon, 14 Aug 2006 13:19:15 -0700 Subject: [PATCH 115/160] Make pprint_tag void and cleans up call in cmd_cat_file. Signed-off-by: David Rientjes Signed-off-by: Junio C Hamano --- builtin-cat-file.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/builtin-cat-file.c b/builtin-cat-file.c index 814fb0743f..df009ade7a 100644 --- a/builtin-cat-file.c +++ b/builtin-cat-file.c @@ -26,7 +26,7 @@ static void flush_buffer(const char *buf, unsigned long size) } } -static int pprint_tag(const unsigned char *sha1, const char *buf, unsigned long size) +static void pprint_tag(const unsigned char *sha1, const char *buf, unsigned long size) { /* the parser in tag.c is useless here. */ const char *endp = buf + size; @@ -91,7 +91,6 @@ static int pprint_tag(const unsigned char *sha1, const char *buf, unsigned long */ if (cp < endp) flush_buffer(cp, endp - cp); - return 0; } int cmd_cat_file(int argc, const char **argv, const char *prefix) @@ -145,8 +144,10 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix) buf = read_sha1_file(sha1, type, &size); if (!buf) die("Cannot read object %s", argv[2]); - if (!strcmp(type, tag_type)) - return pprint_tag(sha1, buf, size); + if (!strcmp(type, tag_type)) { + pprint_tag(sha1, buf, size); + return 0; + } /* otherwise just spit out the data */ break; From cf995ede2cf53d70e5de2525184597211c827dc5 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Mon, 14 Aug 2006 13:39:27 -0700 Subject: [PATCH 116/160] Make show_entry void Signed-off-by: David Rientjes Signed-off-by: Junio C Hamano --- tree-diff.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tree-diff.c b/tree-diff.c index 1cdf8aa908..916f489c5b 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -15,7 +15,8 @@ static char *malloc_base(const char *base, const char *path, int pathlen) return newbase; } -static int show_entry(struct diff_options *opt, const char *prefix, struct tree_desc *desc, const char *base); +static void show_entry(struct diff_options *opt, const char *prefix, struct tree_desc *desc, + const char *base); static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const char *base, struct diff_options *opt) { @@ -131,7 +132,8 @@ static void show_tree(struct diff_options *opt, const char *prefix, struct tree_ } /* A file entry went away or appeared */ -static int show_entry(struct diff_options *opt, const char *prefix, struct tree_desc *desc, const char *base) +static void show_entry(struct diff_options *opt, const char *prefix, struct tree_desc *desc, + const char *base) { unsigned mode; const char *path; @@ -152,11 +154,9 @@ static int show_entry(struct diff_options *opt, const char *prefix, struct tree_ free(tree); free(newbase); - return 0; + } else { + opt->add_remove(opt, prefix[0], mode, sha1, base, path); } - - opt->add_remove(opt, prefix[0], mode, sha1, base, path); - return 0; } int diff_tree(struct tree_desc *t1, struct tree_desc *t2, const char *base, struct diff_options *opt) From f7f0fbfcf4fb9367a12aba3a205fb5e1276a2800 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Mon, 14 Aug 2006 13:20:12 -0700 Subject: [PATCH 117/160] Make checkout_all void. Signed-off-by: David Rientjes Signed-off-by: Junio C Hamano --- builtin-checkout-index.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/builtin-checkout-index.c b/builtin-checkout-index.c index 8d0dbad49e..6b55f931cb 100644 --- a/builtin-checkout-index.c +++ b/builtin-checkout-index.c @@ -122,7 +122,7 @@ static int checkout_file(const char *name, int prefix_length) return -1; } -static int checkout_all(const char *prefix, int prefix_length) +static void checkout_all(const char *prefix, int prefix_length) { int i, errs = 0; struct cache_entry* last_ce = NULL; @@ -153,7 +153,6 @@ static int checkout_all(const char *prefix, int prefix_length) * exit with the same code as die(). */ exit(128); - return 0; } static const char checkout_cache_usage[] = From b5524c826dc36e5d9d2455cfca85aa62f1a776d1 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Mon, 14 Aug 2006 13:36:18 -0700 Subject: [PATCH 118/160] Make fsck_dir void. Signed-off-by: David Rientjes Signed-off-by: Junio C Hamano --- fsck-objects.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fsck-objects.c b/fsck-objects.c index e167f4105f..4ba3377aef 100644 --- a/fsck-objects.c +++ b/fsck-objects.c @@ -366,13 +366,13 @@ static void add_sha1_list(unsigned char *sha1, unsigned long ino) sha1_list.nr = ++nr; } -static int fsck_dir(int i, char *path) +static void fsck_dir(int i, char *path) { DIR *dir = opendir(path); struct dirent *de; if (!dir) - return 0; + return; while ((de = readdir(dir)) != NULL) { char name[100]; @@ -398,7 +398,6 @@ static int fsck_dir(int i, char *path) fprintf(stderr, "bad sha1 file: %s/%s\n", path, de->d_name); } closedir(dir); - return 0; } static int default_refs = 0; From aa145403da905aaa9f129b0f13b5bca7994cb329 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Mon, 14 Aug 2006 13:38:50 -0700 Subject: [PATCH 119/160] Make pack_objects void. Signed-off-by: David Rientjes Signed-off-by: Junio C Hamano --- send-pack.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/send-pack.c b/send-pack.c index 10bc8bc359..b7cc1a9089 100644 --- a/send-pack.c +++ b/send-pack.c @@ -111,7 +111,7 @@ static void rev_list(int fd, struct ref *refs) exec_rev_list(refs); } -static int pack_objects(int fd, struct ref *refs) +static void pack_objects(int fd, struct ref *refs) { pid_t rev_list_pid; @@ -126,7 +126,6 @@ static int pack_objects(int fd, struct ref *refs) * We don't wait for the rev-list pipeline in the parent: * we end up waiting for the other end instead */ - return 0; } static void unmark_and_free(struct commit_list *list, unsigned int mark) From 74b504f67173a9f4dd06f01d109c58ea13f279b4 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Mon, 14 Aug 2006 13:40:06 -0700 Subject: [PATCH 120/160] Make track_tree_refs void. Signed-off-by: David Rientjes Signed-off-by: Junio C Hamano --- tree.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tree.c b/tree.c index a6032e35ec..ef456be9dd 100644 --- a/tree.c +++ b/tree.c @@ -144,7 +144,7 @@ struct tree *lookup_tree(const unsigned char *sha1) return (struct tree *) obj; } -static int track_tree_refs(struct tree *item) +static void track_tree_refs(struct tree *item) { int n_refs = 0, i; struct object_refs *refs; @@ -174,7 +174,6 @@ static int track_tree_refs(struct tree *item) refs->ref[i++] = obj; } set_object_refs(&item->object, refs); - return 0; } int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size) From 59076eba6e1a41c2e0032dbd656d8429e9655358 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Mon, 14 Aug 2006 13:40:51 -0700 Subject: [PATCH 121/160] Make upload_pack void and remove conditional return. Signed-off-by: David Rientjes Signed-off-by: Junio C Hamano --- upload-pack.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/upload-pack.c b/upload-pack.c index bbd6bd60b5..27e2abe36c 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -459,18 +459,17 @@ static int send_ref(const char *refname, const unsigned char *sha1) return 0; } -static int upload_pack(void) +static void upload_pack(void) { reset_timeout(); head_ref(send_ref); for_each_ref(send_ref); packet_flush(1); receive_needs(); - if (!want_obj.nr) - return 0; - get_common_commits(); - create_pack_file(); - return 0; + if (want_obj.nr) { + get_common_commits(); + create_pack_file(); + } } int main(int argc, char **argv) From 78b713a1d0909c8eb8dc0bad5df624c33d065c16 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Mon, 14 Aug 2006 13:32:01 -0700 Subject: [PATCH 122/160] Make sha1flush void and remove conditional return. Signed-off-by: David Rientjes Signed-off-by: Junio C Hamano --- csum-file.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/csum-file.c b/csum-file.c index 6a7b40fd09..e2278897d0 100644 --- a/csum-file.c +++ b/csum-file.c @@ -10,7 +10,7 @@ #include "cache.h" #include "csum-file.h" -static int sha1flush(struct sha1file *f, unsigned int count) +static void sha1flush(struct sha1file *f, unsigned int count) { void *buf = f->buffer; @@ -21,7 +21,7 @@ static int sha1flush(struct sha1file *f, unsigned int count) count -= ret; if (count) continue; - return 0; + return; } if (!ret) die("sha1 file '%s' write error. Out of diskspace", f->name); From 6a0ebe8ced66b154a48074d3e3321ff1972ec669 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 14 Aug 2006 23:24:55 -0700 Subject: [PATCH 123/160] t4116 apply --reverse test The binary patch test needs to be made more careful not to have the postimage blob in the repository in which the patch is applied Signed-off-by: Junio C Hamano --- t/t4116-apply-reverse.sh | 46 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100755 t/t4116-apply-reverse.sh diff --git a/t/t4116-apply-reverse.sh b/t/t4116-apply-reverse.sh new file mode 100755 index 0000000000..69aebe6005 --- /dev/null +++ b/t/t4116-apply-reverse.sh @@ -0,0 +1,46 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='git-apply in reverse + +' + +. ./test-lib.sh + +test_expect_success setup ' + + for i in a b c d e f g h i j k l m n; do echo $i; done >file1 && + tr "[ijk]" '\''[\0\1\2]'\'' file2 && + + git add file1 file2 && + git commit -m initial && + git tag initial && + + for i in a b c g h i J K L m o n p q; do echo $i; done >file1 && + tr "[mon]" '\''[\0\1\2]'\'' file2 && + + git commit -a -m second && + + git diff --binary -R initial >patch + +' + +test_expect_success 'apply in forward' ' + + git apply --index --binary patch && + git diff initial >diff && + diff -u /dev/null diff + +' + +test_expect_success 'apply in reverse' ' + + git apply --reverse --binary --index patch && + git diff >diff && + diff -u /dev/null diff + +' + +test_done From f686d03034c74bd0de2002b7c277a0838662ea00 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 14 Aug 2006 23:26:51 -0700 Subject: [PATCH 124/160] git-apply --reverse: simplify reverse option. Having is_reverse in each patch did not make sense. This will hopefully simplify the work needed to introduce reversible binary diff format. Signed-off-by: Junio C Hamano --- builtin-apply.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/builtin-apply.c b/builtin-apply.c index 9cf477c701..267aab0e84 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -37,6 +37,7 @@ static int numstat = 0; static int summary = 0; static int check = 0; static int apply = 1; +static int apply_in_reverse = 0; static int no_add = 0; static int show_index_info = 0; static int line_termination = '\n'; @@ -120,7 +121,7 @@ struct fragment { struct patch { char *new_name, *old_name, *def_name; unsigned int old_mode, new_mode; - int is_rename, is_copy, is_new, is_delete, is_binary, is_reverse; + int is_rename, is_copy, is_new, is_delete, is_binary; #define BINARY_DELTA_DEFLATED 1 #define BINARY_LITERAL_DEFLATED 2 unsigned long deflate_origlen; @@ -1143,7 +1144,6 @@ static void reverse_patches(struct patch *p) swap(frag->newpos, frag->oldpos); swap(frag->newlines, frag->oldlines); } - p->is_reverse = !p->is_reverse; } } @@ -1363,8 +1363,7 @@ static int apply_line(char *output, const char *patch, int plen) return plen; } -static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, - int reverse, int inaccurate_eof) +static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, int inaccurate_eof) { int match_beginning, match_end; char *buf = desc->buffer; @@ -1396,7 +1395,7 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, if (len < size && patch[len] == '\\') plen--; first = *patch; - if (reverse) { + if (apply_in_reverse) { if (first == '-') first = '+'; else if (first == '+') @@ -1536,7 +1535,7 @@ static int apply_binary_fragment(struct buffer_desc *desc, struct patch *patch) void *result; /* Binary patch is irreversible */ - if (patch->is_reverse) + if (apply_in_reverse) return error("cannot reverse-apply a binary patch to '%s'", patch->new_name ? patch->new_name : patch->old_name); @@ -1657,8 +1656,7 @@ static int apply_fragments(struct buffer_desc *desc, struct patch *patch) return apply_binary(desc, patch); while (frag) { - if (apply_one_fragment(desc, frag, patch->is_reverse, - patch->inaccurate_eof) < 0) + if (apply_one_fragment(desc, frag, patch->inaccurate_eof) < 0) return error("patch failed: %s:%ld", name, frag->oldpos); frag = frag->next; @@ -2194,8 +2192,7 @@ static int use_patch(struct patch *p) return 1; } -static int apply_patch(int fd, const char *filename, - int reverse, int inaccurate_eof) +static int apply_patch(int fd, const char *filename, int inaccurate_eof) { unsigned long offset, size; char *buffer = read_patch_file(fd, &size); @@ -2215,7 +2212,7 @@ static int apply_patch(int fd, const char *filename, nr = parse_chunk(buffer + offset, size, patch); if (nr < 0) break; - if (reverse) + if (apply_in_reverse) reverse_patches(patch); if (use_patch(patch)) { patch_stats(patch); @@ -2278,7 +2275,6 @@ int cmd_apply(int argc, const char **argv, const char *prefix) { int i; int read_stdin = 1; - int reverse = 0; int inaccurate_eof = 0; const char *whitespace_option = NULL; @@ -2289,7 +2285,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix) int fd; if (!strcmp(arg, "-")) { - apply_patch(0, "", reverse, inaccurate_eof); + apply_patch(0, "", inaccurate_eof); read_stdin = 0; continue; } @@ -2367,7 +2363,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix) continue; } if (!strcmp(arg, "-R") || !strcmp(arg, "--reverse")) { - reverse = 1; + apply_in_reverse = 1; continue; } if (!strcmp(arg, "--inaccurate-eof")) { @@ -2390,12 +2386,12 @@ int cmd_apply(int argc, const char **argv, const char *prefix) usage(apply_usage); read_stdin = 0; set_default_whitespace_mode(whitespace_option); - apply_patch(fd, arg, reverse, inaccurate_eof); + apply_patch(fd, arg, inaccurate_eof); close(fd); } set_default_whitespace_mode(whitespace_option); if (read_stdin) - apply_patch(0, "", reverse, inaccurate_eof); + apply_patch(0, "", inaccurate_eof); if (whitespace_error) { if (squelch_whitespace_errors && squelch_whitespace_errors < whitespace_error) { From 66c4509b73eeb66de3196a43e3171b3764f74100 Mon Sep 17 00:00:00 2001 From: Dennis Stosberg Date: Tue, 15 Aug 2006 11:01:22 +0200 Subject: [PATCH 125/160] Solaris does not support C99 format strings before version 10 Signed-off-by: Dennis Stosberg Signed-off-by: Junio C Hamano --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index 0761d6c6ed..02a036b960 100644 --- a/Makefile +++ b/Makefile @@ -301,10 +301,12 @@ ifeq ($(uname_S),SunOS) NEEDS_LIBICONV = YesPlease NO_UNSETENV = YesPlease NO_SETENV = YesPlease + NO_C99_FORMAT = YesPlease endif ifeq ($(uname_R),5.9) NO_UNSETENV = YesPlease NO_SETENV = YesPlease + NO_C99_FORMAT = YesPlease endif INSTALL = ginstall TAR = gtar From f4e14ca9e05876ec1e0d79d7c12b5b3a6b2e9d08 Mon Sep 17 00:00:00 2001 From: Dennis Stosberg Date: Tue, 15 Aug 2006 11:01:20 +0200 Subject: [PATCH 126/160] Solaris has strlcpy() at least since version 8 See http://docs.sun.com/app/docs/doc/816-3321/6m9k23sjk?a=view Signed-off-by: Dennis Stosberg Signed-off-by: Junio C Hamano --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index b363f50d48..b86de761ff 100644 --- a/Makefile +++ b/Makefile @@ -327,7 +327,6 @@ ifeq ($(uname_S),SunOS) NEEDS_NSL = YesPlease SHELL_PATH = /bin/bash NO_STRCASESTR = YesPlease - NO_STRLCPY = YesPlease ifeq ($(uname_R),5.8) NEEDS_LIBICONV = YesPlease NO_UNSETENV = YesPlease From ab5573ae9f4178a7b6f6920f04c73a65feb3c690 Mon Sep 17 00:00:00 2001 From: Dennis Stosberg Date: Tue, 15 Aug 2006 11:01:25 +0200 Subject: [PATCH 127/160] Look for sockaddr_storage in sys/socket.h On Solaris and the BSDs the definition of "struct sockaddr_storage" is not available from "netinet/in.h". On Solaris "sys/socket.h" is enough, at least OpenBSD needs "sys/types.h", too. Using "sys/types.h" and "sys/socket.h" seems to be a more portable way. Signed-off-by: Dennis Stosberg Signed-off-by: Junio C Hamano --- configure.ac | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index e890131c46..0321d437d9 100644 --- a/configure.ac +++ b/configure.ac @@ -181,8 +181,10 @@ AC_SUBST(NO_D_TYPE_IN_DIRENT) # sockaddr_storage. AC_CHECK_TYPE(struct sockaddr_storage, [NO_SOCKADDR_STORAGE=], -[NO_SOCKADDR_STORAGE=YesPlease], -[#include ]) +[NO_SOCKADDR_STORAGE=YesPlease],[ +#include +#include +]) AC_SUBST(NO_SOCKADDR_STORAGE) # # Define NO_IPV6 if you lack IPv6 support and getaddrinfo(). From d1b9944db8f66131b259be407472e53db33718ea Mon Sep 17 00:00:00 2001 From: Dennis Stosberg Date: Tue, 15 Aug 2006 11:01:27 +0200 Subject: [PATCH 128/160] Fix detection of ipv6 on Solaris The configuration script detects whether linking with -lsocket is necessary but doesn't add -lsocket to LIBS. This lets the ipv6 test fail. Signed-off-by: Dennis Stosberg Signed-off-by: Junio C Hamano --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 0321d437d9..36f9cd94d8 100644 --- a/configure.ac +++ b/configure.ac @@ -154,6 +154,7 @@ AC_CHECK_LIB([c], [socket], [NEEDS_SOCKET=], [NEEDS_SOCKET=YesPlease]) AC_SUBST(NEEDS_SOCKET) +test -n "$NEEDS_SOCKET" && LIBS="$LIBS -lsocket" ## Checks for header files. From 3cd4f5e8eb04ae01298ceaf46bb41a4277031916 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 15 Aug 2006 02:23:06 -0700 Subject: [PATCH 129/160] git-apply --binary: clean up and prepare for --reverse This cleans up the implementation of "git-apply --binary", and implements reverse application of binary patches (when git-diff is converted to emit reversible binary patches). Earlier, the types of encoding (either deflated literal or deflated delta) were stored in is_binary field in struct patch, which meant that we cannot store more than one fragment that differ in the encoding for a patch. This moves the information to a field in struct fragment that is otherwise unused for binary patches, and makes it possible to hang two (or more, but two is enough) hunks for a binary patch. The original "binary patch" output from git-diff is internally parsed into an "is_binary" patch with one fragment. Upcoming reversible binary patch output will have two fragments, the first one being the forward patch and the second one the reverse patch. Signed-off-by: Junio C Hamano --- builtin-apply.c | 206 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 141 insertions(+), 65 deletions(-) diff --git a/builtin-apply.c b/builtin-apply.c index 267aab0e84..4573c9abb2 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -109,6 +109,13 @@ static int max_change, max_len; */ static int linenr = 1; +/* + * This represents one "hunk" from a patch, starting with + * "@@ -oldpos,oldlines +newpos,newlines @@" marker. The + * patch text is pointed at by patch, and its byte length + * is stored in size. leading and trailing are the number + * of context lines. + */ struct fragment { unsigned long leading, trailing; unsigned long oldpos, oldlines; @@ -118,12 +125,19 @@ struct fragment { struct fragment *next; }; +/* + * When dealing with a binary patch, we reuse "leading" field + * to store the type of the binary hunk, either deflated "delta" + * or deflated "literal". + */ +#define binary_patch_method leading +#define BINARY_DELTA_DEFLATED 1 +#define BINARY_LITERAL_DEFLATED 2 + struct patch { char *new_name, *old_name, *def_name; unsigned int old_mode, new_mode; int is_rename, is_copy, is_new, is_delete, is_binary; -#define BINARY_DELTA_DEFLATED 1 -#define BINARY_LITERAL_DEFLATED 2 unsigned long deflate_origlen; int lines_added, lines_deleted; int score; @@ -979,43 +993,70 @@ static inline int metadata_changes(struct patch *patch) patch->old_mode != patch->new_mode); } -static int parse_binary(char *buffer, unsigned long size, struct patch *patch) +static char *inflate_it(const void *data, unsigned long size, + unsigned long inflated_size) { - /* We have read "GIT binary patch\n"; what follows is a line - * that says the patch method (currently, either "deflated - * literal" or "deflated delta") and the length of data before - * deflating; a sequence of 'length-byte' followed by base-85 - * encoded data follows. + z_stream stream; + void *out; + int st; + + memset(&stream, 0, sizeof(stream)); + + stream.next_in = (unsigned char *)data; + stream.avail_in = size; + stream.next_out = out = xmalloc(inflated_size); + stream.avail_out = inflated_size; + inflateInit(&stream); + st = inflate(&stream, Z_FINISH); + if ((st != Z_STREAM_END) || stream.total_out != inflated_size) { + free(out); + return NULL; + } + return out; +} + +static struct fragment *parse_binary_hunk(char **buf_p, + unsigned long *sz_p, + int *status_p, + int *used_p) +{ + /* Expect a line that begins with binary patch method ("literal" + * or "delta"), followed by the length of data before deflating. + * a sequence of 'length-byte' followed by base-85 encoded data + * should follow, terminated by a newline. * * Each 5-byte sequence of base-85 encodes up to 4 bytes, * and we would limit the patch line to 66 characters, * so one line can fit up to 13 groups that would decode * to 52 bytes max. The length byte 'A'-'Z' corresponds * to 1-26 bytes, and 'a'-'z' corresponds to 27-52 bytes. - * The end of binary is signaled with an empty line. */ int llen, used; - struct fragment *fragment; + unsigned long size = *sz_p; + char *buffer = *buf_p; + int patch_method; + unsigned long origlen; char *data = NULL; + int hunk_size = 0; + struct fragment *frag; - patch->fragments = fragment = xcalloc(1, sizeof(*fragment)); - - /* Grab the type of patch */ llen = linelen(buffer, size); used = llen; - linenr++; + + *status_p = 0; if (!strncmp(buffer, "delta ", 6)) { - patch->is_binary = BINARY_DELTA_DEFLATED; - patch->deflate_origlen = strtoul(buffer + 6, NULL, 10); + patch_method = BINARY_DELTA_DEFLATED; + origlen = strtoul(buffer + 6, NULL, 10); } else if (!strncmp(buffer, "literal ", 8)) { - patch->is_binary = BINARY_LITERAL_DEFLATED; - patch->deflate_origlen = strtoul(buffer + 8, NULL, 10); + patch_method = BINARY_LITERAL_DEFLATED; + origlen = strtoul(buffer + 8, NULL, 10); } else - return error("unrecognized binary patch at line %d: %.*s", - linenr-1, llen-1, buffer); + return NULL; + + linenr++; buffer += llen; while (1) { int byte_length, max_byte_length, newsize; @@ -1044,21 +1085,79 @@ static int parse_binary(char *buffer, unsigned long size, struct patch *patch) if (max_byte_length < byte_length || byte_length <= max_byte_length - 4) goto corrupt; - newsize = fragment->size + byte_length; + newsize = hunk_size + byte_length; data = xrealloc(data, newsize); - if (decode_85(data + fragment->size, - buffer + 1, - byte_length)) + if (decode_85(data + hunk_size, buffer + 1, byte_length)) goto corrupt; - fragment->size = newsize; + hunk_size = newsize; buffer += llen; size -= llen; } - fragment->patch = data; - return used; + + frag = xcalloc(1, sizeof(*frag)); + frag->patch = inflate_it(data, hunk_size, origlen); + if (!frag->patch) + goto corrupt; + free(data); + frag->size = origlen; + *buf_p = buffer; + *sz_p = size; + *used_p = used; + frag->binary_patch_method = patch_method; + return frag; + corrupt: - return error("corrupt binary patch at line %d: %.*s", - linenr-1, llen-1, buffer); + if (data) + free(data); + *status_p = -1; + error("corrupt binary patch at line %d: %.*s", + linenr-1, llen-1, buffer); + return NULL; +} + +static int parse_binary(char *buffer, unsigned long size, struct patch *patch) +{ + /* We have read "GIT binary patch\n"; what follows is a line + * that says the patch method (currently, either "literal" or + * "delta") and the length of data before deflating; a + * sequence of 'length-byte' followed by base-85 encoded data + * follows. + * + * When a binary patch is reversible, there is another binary + * hunk in the same format, starting with patch method (either + * "literal" or "delta") with the length of data, and a sequence + * of length-byte + base-85 encoded data, terminated with another + * empty line. This data, when applied to the postimage, produces + * the preimage. + */ + struct fragment *forward; + struct fragment *reverse; + int status; + int used, used_1; + + forward = parse_binary_hunk(&buffer, &size, &status, &used); + if (!forward && !status) + /* there has to be one hunk (forward hunk) */ + return error("unrecognized binary patch at line %d", linenr-1); + if (status) + /* otherwise we already gave an error message */ + return status; + + reverse = parse_binary_hunk(&buffer, &size, &status, &used_1); + if (reverse) + used += used_1; + else if (status) { + /* not having reverse hunk is not an error, but having + * a corrupt reverse hunk is. + */ + free((void*) forward->patch); + free(forward); + return status; + } + forward->next = reverse; + patch->fragments = forward; + patch->is_binary = 1; + return used; } static int parse_chunk(char *buffer, unsigned long size, struct patch *patch) @@ -1505,28 +1604,6 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i return offset; } -static char *inflate_it(const void *data, unsigned long size, - unsigned long inflated_size) -{ - z_stream stream; - void *out; - int st; - - memset(&stream, 0, sizeof(stream)); - - stream.next_in = (unsigned char *)data; - stream.avail_in = size; - stream.next_out = out = xmalloc(inflated_size); - stream.avail_out = inflated_size; - inflateInit(&stream); - st = inflate(&stream, Z_FINISH); - if ((st != Z_STREAM_END) || stream.total_out != inflated_size) { - free(out); - return NULL; - } - return out; -} - static int apply_binary_fragment(struct buffer_desc *desc, struct patch *patch) { unsigned long dst_size; @@ -1534,30 +1611,29 @@ static int apply_binary_fragment(struct buffer_desc *desc, struct patch *patch) void *data; void *result; - /* Binary patch is irreversible */ - if (apply_in_reverse) - return error("cannot reverse-apply a binary patch to '%s'", - patch->new_name - ? patch->new_name : patch->old_name); - - data = inflate_it(fragment->patch, fragment->size, - patch->deflate_origlen); - if (!data) - return error("corrupt patch data"); - switch (patch->is_binary) { + /* Binary patch is irreversible without the optional second hunk */ + if (apply_in_reverse) { + if (!fragment->next) + return error("cannot reverse-apply a binary patch " + "without the reverse hunk to '%s'", + patch->new_name + ? patch->new_name : patch->old_name); + fragment = fragment; + } + data = (void*) fragment->patch; + switch (fragment->binary_patch_method) { case BINARY_DELTA_DEFLATED: result = patch_delta(desc->buffer, desc->size, data, - patch->deflate_origlen, + fragment->size, &dst_size); free(desc->buffer); desc->buffer = result; - free(data); break; case BINARY_LITERAL_DEFLATED: free(desc->buffer); desc->buffer = data; - dst_size = patch->deflate_origlen; + dst_size = fragment->size; break; } if (!desc->buffer) From 789a09b4874ae2616987794e0e739b8227957175 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 15 Aug 2006 03:39:47 -0700 Subject: [PATCH 130/160] avoid nanosleep(2) On Solaris nanosleep(2) is not available in libc; you need to link with -lrt to get it. The purpose of the loop is to wait until the next filesystem timestamp granularity, and the code uses subsecond sleep in the hope that it can shorten the delay to 0.5 seconds on average instead of a full second. It is probably not worth depending on an extra library for this. We might want to yank out the whole "racy-git avoidance is costly later at runtime, so let's delay writing the index out" codepath later, but that is a separate issue and needs some testing on large trees to figure it out. After playing with the kernel tree, I have a feeling that the whole thing may not be worth it. Signed-off-by: Junio C Hamano --- read-cache.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/read-cache.c b/read-cache.c index b18f9f72d9..ec4dd5ae6c 100644 --- a/read-cache.c +++ b/read-cache.c @@ -5,7 +5,6 @@ */ #include "cache.h" #include "cache-tree.h" -#include /* Index extensions. * @@ -1033,11 +1032,8 @@ int write_cache(int newfd, struct cache_entry **cache, int entries) fprintf(stderr, "now %lu\n", now); #endif while (!fstat(newfd, &st) && st.st_mtime <= now) { - struct timespec rq, rm; off_t where = lseek(newfd, 0, SEEK_CUR); - rq.tv_sec = 0; - rq.tv_nsec = 250000000; - nanosleep(&rq, &rm); + sleep(1); if ((where == (off_t) -1) || (write(newfd, "", 1) != 1) || (lseek(newfd, -1, SEEK_CUR) != where) || From 0bef57ee44a2f924ad0066b751a3c87888633f56 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Tue, 15 Aug 2006 13:37:19 -0700 Subject: [PATCH 131/160] make inline is_null_sha1 global Replace sha1 comparisons to null_sha1 with a global inline (which previously an unused static inline in builtin-apply.c) [jc: with a fix from Jonas Fonseca.] Signed-off-by: David Rientjes Signed-off-by: Junio C Hamano --- builtin-apply.c | 7 +------ builtin-diff.c | 3 +-- cache.h | 4 ++++ combine-diff.c | 4 ++-- diff.c | 2 +- fsck-objects.c | 2 +- sha1_name.c | 2 +- 7 files changed, 11 insertions(+), 13 deletions(-) diff --git a/builtin-apply.c b/builtin-apply.c index 4573c9abb2..1c1d16f756 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -1684,7 +1684,7 @@ static int apply_binary(struct buffer_desc *desc, struct patch *patch) } get_sha1_hex(patch->new_sha1_prefix, sha1); - if (!memcmp(sha1, null_sha1, 20)) { + if (is_null_sha1(sha1)) { free(desc->buffer); desc->alloc = desc->size = 0; desc->buffer = NULL; @@ -1916,11 +1916,6 @@ static int check_patch_list(struct patch *patch) return error; } -static inline int is_null_sha1(const unsigned char *sha1) -{ - return !memcmp(sha1, null_sha1, 20); -} - static void show_index_list(struct patch *list) { struct patch *patch; diff --git a/builtin-diff.c b/builtin-diff.c index 82afce782d..40e5c96f30 100644 --- a/builtin-diff.c +++ b/builtin-diff.c @@ -68,8 +68,7 @@ static void stuff_change(struct diff_options *opt, { struct diff_filespec *one, *two; - if (memcmp(null_sha1, old_sha1, 20) && - memcmp(null_sha1, new_sha1, 20) && + if (!is_null_sha1(old_sha1) && !is_null_sha1(new_sha1) && !memcmp(old_sha1, new_sha1, 20)) return; diff --git a/cache.h b/cache.h index af7740258d..c7382996f6 100644 --- a/cache.h +++ b/cache.h @@ -210,6 +210,10 @@ extern char *sha1_pack_name(const unsigned char *sha1); extern char *sha1_pack_index_name(const unsigned char *sha1); extern const char *find_unique_abbrev(const unsigned char *sha1, int); extern const unsigned char null_sha1[20]; +static inline int is_null_sha1(const unsigned char *sha1) +{ + return !memcmp(sha1, null_sha1, 20); +} int git_mkstemp(char *path, size_t n, const char *template); diff --git a/combine-diff.c b/combine-diff.c index 4c6bfed56e..ce063b4ffa 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -94,7 +94,7 @@ static char *grab_blob(const unsigned char *sha1, unsigned long *size) { char *blob; char type[20]; - if (!memcmp(sha1, null_sha1, 20)) { + if (is_null_sha1(sha1)) { /* deleted blob */ *size = 0; return xcalloc(1, 1); @@ -611,7 +611,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, struct sline *sline; /* survived lines */ int mode_differs = 0; int i, show_hunks; - int working_tree_file = !memcmp(elem->sha1, null_sha1, 20); + int working_tree_file = is_null_sha1(elem->sha1); int abbrev = opt->full_index ? 40 : DEFAULT_ABBREV; mmfile_t result_file; diff --git a/diff.c b/diff.c index 2327e6065b..6a8c0c9c01 100644 --- a/diff.c +++ b/diff.c @@ -1102,7 +1102,7 @@ void fill_filespec(struct diff_filespec *spec, const unsigned char *sha1, if (mode) { spec->mode = canon_mode(mode); memcpy(spec->sha1, sha1, 20); - spec->sha1_valid = !!memcmp(sha1, null_sha1, 20); + spec->sha1_valid = !is_null_sha1(sha1); } } diff --git a/fsck-objects.c b/fsck-objects.c index 4ba3377aef..b0e882a99f 100644 --- a/fsck-objects.c +++ b/fsck-objects.c @@ -452,7 +452,7 @@ static int fsck_head_link(void) if (strncmp(git_refs_heads_master + pfxlen, "refs/heads/", 11)) return error("HEAD points to something strange (%s)", git_refs_heads_master + pfxlen); - if (!memcmp(null_sha1, sha1, 20)) + if (is_null_sha1(sha1)) return error("HEAD: not a valid git pointer"); return 0; } diff --git a/sha1_name.c b/sha1_name.c index c5a05faeb6..f567454d22 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -191,7 +191,7 @@ const char *find_unique_abbrev(const unsigned char *sha1, int len) int status, is_null; static char hex[41]; - is_null = !memcmp(sha1, null_sha1, 20); + is_null = is_null_sha1(sha1); memcpy(hex, sha1_to_hex(sha1), 40); if (len == 40 || !len) return hex; From 6f002f984f1d1ddfdae990582a423dc5263697ae Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Tue, 15 Aug 2006 10:40:06 -0700 Subject: [PATCH 132/160] use appropriate typedefs Signed-off-by: David Rientjes Signed-off-by: Junio C Hamano --- fetch-clone.c | 3 +-- merge-index.c | 3 ++- run-command.c | 8 ++++---- unpack-trees.c | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/fetch-clone.c b/fetch-clone.c index 5e84c4620f..c5cf4776fa 100644 --- a/fetch-clone.c +++ b/fetch-clone.c @@ -44,9 +44,8 @@ static int finish_pack(const char *pack_tmp_name, const char *me) for (;;) { int status, code; - int retval = waitpid(pid, &status, 0); - if (retval < 0) { + if (waitpid(pid, &status, 0) < 0) { if (errno == EINTR) continue; error("waitpid failed (%s)", strerror(errno)); diff --git a/merge-index.c b/merge-index.c index 0498a6f45e..a9c8cc1f93 100644 --- a/merge-index.c +++ b/merge-index.c @@ -11,7 +11,8 @@ static int err; static void run_program(void) { - int pid = fork(), status; + pid_t pid = fork(); + int status; if (pid < 0) die("unable to fork"); diff --git a/run-command.c b/run-command.c index ca67ee9333..61908682b9 100644 --- a/run-command.c +++ b/run-command.c @@ -25,15 +25,15 @@ int run_command_v_opt(int argc, const char **argv, int flags) } for (;;) { int status, code; - int retval = waitpid(pid, &status, 0); + pid_t waiting = waitpid(pid, &status, 0); - if (retval < 0) { + if (waiting < 0) { if (errno == EINTR) continue; - error("waitpid failed (%s)", strerror(retval)); + error("waitpid failed (%s)", strerror(errno)); return -ERR_RUN_COMMAND_WAITPID; } - if (retval != pid) + if (waiting != pid) return -ERR_RUN_COMMAND_WAITPID_WRONG_PID; if (WIFSIGNALED(status)) return -ERR_RUN_COMMAND_WAITPID_SIGNAL; diff --git a/unpack-trees.c b/unpack-trees.c index a20639be70..e496d8cd31 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -278,7 +278,7 @@ static void unlink_entry(char *name) } } -static volatile int progress_update = 0; +static volatile sig_atomic_t progress_update = 0; static void progress_interval(int signum) { From 1d6249e609289940dca179b626fe4ae5433c90cc Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Wed, 16 Aug 2006 02:20:32 +0200 Subject: [PATCH 133/160] git-mv: succeed even if source is a prefix of destination As noted by Fredrik Kuivinen, without this patch, git-mv fails on git-mv README README-renamed because "README" is a prefix of "README-renamed". Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- builtin-mv.c | 5 ++++- t/t7001-mv.sh | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/builtin-mv.c b/builtin-mv.c index a731f8d9cf..e7b5eb7088 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -119,6 +119,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix) /* Checking */ for (i = 0; i < count; i++) { + int length; const char *bad = NULL; if (show_only) @@ -204,7 +205,9 @@ int cmd_mv(int argc, const char **argv, const char *prefix) } if (!bad && - !strncmp(destination[i], source[i], strlen(source[i]))) + (length = strlen(source[i])) >= 0 && + !strncmp(destination[i], source[i], length) && + (destination[i][length] == 0 || destination[i][length] == '/')) bad = "can not move directory into itself"; if (!bad && cache_name_pos(source[i], strlen(source[i])) < 0) diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh index 900ca93cde..e5e0bb9d51 100755 --- a/t/t7001-mv.sh +++ b/t/t7001-mv.sh @@ -59,6 +59,10 @@ test_expect_success \ git-diff-tree -r -M --name-status HEAD^ HEAD | \ grep -E "^R100.+path0/README.+path2/README"' +test_expect_success \ + 'succeed when source is a prefix of destination' \ + 'git-mv path2/COPYING path2/COPYING-renamed' + test_expect_success \ 'moving whole subdirectory into subdirectory' \ 'git-mv path2 path1' From 53e1a761be8d338cd957870bc1e48a8c15d7d2c0 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 15 Aug 2006 16:28:08 -0700 Subject: [PATCH 134/160] finish_connect(): thinkofix All but one callers have ignore the return value from this function, but the only caller, builtin-tar-tree.c::remote_tar(), assumed it returns non-zero on failure and zero on success. The implementation however was returning either the waited pid (which must be the same as its input) or -1 (an error). Fix this thinko, while getting rid of an assignment of return value from waitpid() into a variable of type int. Signed-off-by: Junio C Hamano --- connect.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/connect.c b/connect.c index 4422a0d8d3..b9c222085e 100644 --- a/connect.c +++ b/connect.c @@ -737,14 +737,9 @@ int git_connect(int fd[2], char *url, const char *prog) int finish_connect(pid_t pid) { - int ret; - - for (;;) { - ret = waitpid(pid, NULL, 0); - if (!ret) - break; + while (waitpid(pid, NULL, 0) < 0) { if (errno != EINTR) - break; + return -1; } - return ret; + return 0; } From 96f1e58f524fac8607cfc38896b365b6e8365b51 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Tue, 15 Aug 2006 10:23:48 -0700 Subject: [PATCH 135/160] remove unnecessary initializations [jc: I needed to hand merge the changes to the updated codebase, so the result needs to be checked.] Signed-off-by: David Rientjes Signed-off-by: Junio C Hamano --- blame.c | 6 +++--- builtin-apply.c | 28 ++++++++++++++-------------- builtin-fmt-merge-msg.c | 2 +- builtin-ls-files.c | 27 ++++++++++++++------------- builtin-ls-tree.c | 6 +++--- builtin-mailinfo.c | 6 +++--- builtin-name-rev.c | 2 +- builtin-pack-objects.c | 28 ++++++++++++++-------------- builtin-prune.c | 2 +- builtin-push.c | 8 ++++---- builtin-read-tree.c | 2 +- builtin-repo-config.c | 16 ++++++++-------- builtin-rev-list.c | 6 +++--- builtin-rev-parse.c | 10 +++++----- builtin-show-branch.c | 6 +++--- builtin-update-index.c | 2 +- commit.c | 6 +++--- connect.c | 6 +++--- daemon.c | 20 ++++++++++---------- describe.c | 6 +++--- diff.c | 4 ++-- environment.c | 10 +++++----- exec_cmd.c | 2 +- fetch-pack.c | 6 +++--- fsck-objects.c | 14 +++++++------- git.c | 2 +- help.c | 2 +- http-fetch.c | 8 ++++---- http-push.c | 16 ++++++++-------- local-fetch.c | 8 ++++---- merge-base.c | 2 +- merge-index.c | 2 +- mktree.c | 1 - pack-redundant.c | 4 ++-- read-cache.c | 12 ++++++------ receive-pack.c | 6 +++--- send-pack.c | 8 ++++---- sha1_file.c | 2 +- ssh-fetch.c | 8 ++++---- ssh-upload.c | 4 ++-- unpack-trees.c | 2 +- upload-pack.c | 8 ++++---- 42 files changed, 163 insertions(+), 163 deletions(-) diff --git a/blame.c b/blame.c index 54a43d5c54..c253b9ca45 100644 --- a/blame.c +++ b/blame.c @@ -56,9 +56,9 @@ struct patch { static void get_blob(struct commit *commit); /* Only used for statistics */ -static int num_get_patch = 0; -static int num_commits = 0; -static int patch_time = 0; +static int num_get_patch; +static int num_commits; +static int patch_time; struct blame_diff_state { struct xdiff_emit_state xm; diff --git a/builtin-apply.c b/builtin-apply.c index 1c1d16f756..4f0eef0ac3 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -28,18 +28,18 @@ static int prefix_length = -1; static int newfd = -1; static int p_value = 1; -static int allow_binary_replacement = 0; -static int check_index = 0; -static int write_index = 0; -static int cached = 0; -static int diffstat = 0; -static int numstat = 0; -static int summary = 0; -static int check = 0; +static int allow_binary_replacement; +static int check_index; +static int write_index; +static int cached; +static int diffstat; +static int numstat; +static int summary; +static int check; static int apply = 1; -static int apply_in_reverse = 0; -static int no_add = 0; -static int show_index_info = 0; +static int apply_in_reverse; +static int no_add; +static int show_index_info; static int line_termination = '\n'; static unsigned long p_context = -1; static const char apply_usage[] = @@ -51,10 +51,10 @@ static enum whitespace_eol { error_on_whitespace, strip_whitespace, } new_whitespace = warn_on_whitespace; -static int whitespace_error = 0; +static int whitespace_error; static int squelch_whitespace_errors = 5; -static int applied_after_stripping = 0; -static const char *patch_input_file = NULL; +static int applied_after_stripping; +static const char *patch_input_file; static void parse_whitespace_option(const char *option) { diff --git a/builtin-fmt-merge-msg.c b/builtin-fmt-merge-msg.c index 485ede7cad..28b5dfd054 100644 --- a/builtin-fmt-merge-msg.c +++ b/builtin-fmt-merge-msg.c @@ -8,7 +8,7 @@ static const char *fmt_merge_msg_usage = "git-fmt-merge-msg [--summary] [--no-summary] [--file ]"; -static int merge_summary = 0; +static int merge_summary; static int fmt_merge_msg_config(const char *key, const char *value) { diff --git a/builtin-ls-files.c b/builtin-ls-files.c index 11386c432b..ad8c41e731 100644 --- a/builtin-ls-files.c +++ b/builtin-ls-files.c @@ -12,21 +12,22 @@ #include "dir.h" #include "builtin.h" -static int abbrev = 0; -static int show_deleted = 0; -static int show_cached = 0; -static int show_others = 0; -static int show_stage = 0; -static int show_unmerged = 0; -static int show_modified = 0; -static int show_killed = 0; -static int show_valid_bit = 0; +static int abbrev; +static int show_deleted; +static int show_cached; +static int show_others; +static int show_stage; +static int show_unmerged; +static int show_modified; +static int show_killed; +static int show_valid_bit; static int line_terminator = '\n'; -static int prefix_len = 0, prefix_offset = 0; -static const char **pathspec = NULL; -static int error_unmatch = 0; -static char *ps_matched = NULL; +static int prefix_len; +static int prefix_offset; +static const char **pathspec; +static int error_unmatch; +static char *ps_matched; static const char *tag_cached = ""; static const char *tag_unmerged = ""; diff --git a/builtin-ls-tree.c b/builtin-ls-tree.c index 261147fdbe..201defd934 100644 --- a/builtin-ls-tree.c +++ b/builtin-ls-tree.c @@ -14,10 +14,10 @@ static int line_termination = '\n'; #define LS_TREE_ONLY 2 #define LS_SHOW_TREES 4 #define LS_NAME_ONLY 8 -static int abbrev = 0; -static int ls_options = 0; +static int abbrev; +static int ls_options; static const char **pathspec; -static int chomp_prefix = 0; +static int chomp_prefix; static const char *ls_tree_prefix; static const char ls_tree_usage[] = diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c index 24a4fc63b3..0c65f93145 100644 --- a/builtin-mailinfo.c +++ b/builtin-mailinfo.c @@ -16,8 +16,8 @@ static FILE *cmitmsg, *patchfile, *fin, *fout; -static int keep_subject = 0; -static const char *metainfo_charset = NULL; +static int keep_subject; +static const char *metainfo_charset; static char line[1000]; static char date[1000]; static char name[1000]; @@ -31,7 +31,7 @@ static char charset[256]; static char multipart_boundary[1000]; static int multipart_boundary_len; -static int patch_lines = 0; +static int patch_lines; static char *sanity_check(char *name, char *email) { diff --git a/builtin-name-rev.c b/builtin-name-rev.c index 571bba4817..d44e782c99 100644 --- a/builtin-name-rev.c +++ b/builtin-name-rev.c @@ -75,7 +75,7 @@ copy_data: } } -static int tags_only = 0; +static int tags_only; static int name_ref(const char *path, const unsigned char *sha1) { diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c index 2f9921224d..448461bc48 100644 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@ -53,17 +53,17 @@ struct object_entry { */ static unsigned char object_list_sha1[20]; -static int non_empty = 0; -static int no_reuse_delta = 0; -static int local = 0; -static int incremental = 0; +static int non_empty; +static int no_reuse_delta; +static int local; +static int incremental; static struct object_entry **sorted_by_sha, **sorted_by_type; -static struct object_entry *objects = NULL; -static int nr_objects = 0, nr_alloc = 0, nr_result = 0; +static struct object_entry *objects; +static int nr_objects, nr_alloc, nr_result; static const char *base_name; static unsigned char pack_file_sha1[20]; static int progress = 1; -static volatile sig_atomic_t progress_update = 0; +static volatile sig_atomic_t progress_update; static int window = 10; /* @@ -72,8 +72,8 @@ static int window = 10; * sorted_by_sha is also possible but this was easier to code and faster. * This hashtable is built after all the objects are seen. */ -static int *object_ix = NULL; -static int object_ix_hashsz = 0; +static int *object_ix; +static int object_ix_hashsz; /* * Pack index for existing packs give us easy access to the offsets into @@ -90,15 +90,15 @@ struct pack_revindex { struct packed_git *p; unsigned long *revindex; } *pack_revindex = NULL; -static int pack_revindex_hashsz = 0; +static int pack_revindex_hashsz; /* * stats */ -static int written = 0; -static int written_delta = 0; -static int reused = 0; -static int reused_delta = 0; +static int written; +static int written_delta; +static int reused; +static int reused_delta; static int pack_revindex_ix(struct packed_git *p) { diff --git a/builtin-prune.c b/builtin-prune.c index 89ec7f1426..fc885ce55b 100644 --- a/builtin-prune.c +++ b/builtin-prune.c @@ -11,7 +11,7 @@ #include "cache-tree.h" static const char prune_usage[] = "git-prune [-n]"; -static int show_only = 0; +static int show_only; static struct rev_info revs; static int prune_object(char *path, const char *filename, const unsigned char *sha1) diff --git a/builtin-push.c b/builtin-push.c index c09ff2f65e..2b5e6fa9ed 100644 --- a/builtin-push.c +++ b/builtin-push.c @@ -10,14 +10,14 @@ static const char push_usage[] = "git-push [--all] [--tags] [-f | --force] [...]"; -static int all = 0, tags = 0, force = 0, thin = 1; -static const char *execute = NULL; +static int all, tags, force, thin = 1; +static const char *execute; #define BUF_SIZE (2084) static char buffer[BUF_SIZE]; -static const char **refspec = NULL; -static int refspec_nr = 0; +static const char **refspec; +static int refspec_nr; static void add_refspec(const char *ref) { diff --git a/builtin-read-tree.c b/builtin-read-tree.c index 8da8acbb0a..53087faf7a 100644 --- a/builtin-read-tree.c +++ b/builtin-read-tree.c @@ -12,7 +12,7 @@ #include "unpack-trees.h" #include "builtin.h" -static struct object_list *trees = NULL; +static struct object_list *trees; static int list_tree(unsigned char *sha1) { diff --git a/builtin-repo-config.c b/builtin-repo-config.c index c821e22717..c416480208 100644 --- a/builtin-repo-config.c +++ b/builtin-repo-config.c @@ -5,14 +5,14 @@ static const char git_config_set_usage[] = "git-repo-config [ --bool | --int ] [--get | --get-all | --get-regexp | --replace-all | --unset | --unset-all] name [value [value_regex]] | --list"; -static char* key = NULL; -static regex_t* key_regexp = NULL; -static regex_t* regexp = NULL; -static int show_keys = 0; -static int use_key_regexp = 0; -static int do_all = 0; -static int do_not_match = 0; -static int seen = 0; +static char *key; +static regex_t *key_regexp; +static regex_t *regexp; +static int show_keys; +static int use_key_regexp; +static int do_all; +static int do_not_match; +static int seen; static enum { T_RAW, T_INT, T_BOOL } type = T_RAW; static int show_all_config(const char *key_, const char *value_) diff --git a/builtin-rev-list.c b/builtin-rev-list.c index 0dee1734a3..bc48a3e230 100644 --- a/builtin-rev-list.c +++ b/builtin-rev-list.c @@ -39,9 +39,9 @@ static const char rev_list_usage[] = static struct rev_info revs; -static int bisect_list = 0; -static int show_timestamp = 0; -static int hdr_termination = 0; +static int bisect_list; +static int show_timestamp; +static int hdr_termination; static const char *header_prefix; static void show_commit(struct commit *commit) diff --git a/builtin-rev-parse.c b/builtin-rev-parse.c index aca4a36032..fd3ccc8546 100644 --- a/builtin-rev-parse.c +++ b/builtin-rev-parse.c @@ -15,16 +15,16 @@ #define DO_NONFLAGS 8 static int filter = ~0; -static const char *def = NULL; +static const char *def; #define NORMAL 0 #define REVERSED 1 static int show_type = NORMAL; -static int symbolic = 0; -static int abbrev = 0; -static int output_sq = 0; +static int symbolic; +static int abbrev; +static int output_sq; -static int revs_count = 0; +static int revs_count; /* * Some arguments are relevant "revision" arguments, diff --git a/builtin-show-branch.c b/builtin-show-branch.c index 2a1b848f6c..95fbf77fad 100644 --- a/builtin-show-branch.c +++ b/builtin-show-branch.c @@ -8,9 +8,9 @@ static const char show_branch_usage[] = "git-show-branch [--sparse] [--current] [--all] [--heads] [--tags] [--topo-order] [--more=count | --list | --independent | --merge-base ] [--topics] [...]"; -static int default_num = 0; -static int default_alloc = 0; -static const char **default_arg = NULL; +static int default_num; +static int default_alloc; +static const char **default_arg; #define UNINTERESTING 01 diff --git a/builtin-update-index.c b/builtin-update-index.c index d2556f376b..9f0cf28ba2 100644 --- a/builtin-update-index.c +++ b/builtin-update-index.c @@ -23,7 +23,7 @@ static int allow_replace; static int info_only; static int force_remove; static int verbose; -static int mark_valid_only = 0; +static int mark_valid_only; #define MARK_VALID 1 #define UNMARK_VALID 2 diff --git a/commit.c b/commit.c index 77f0ca175c..972d1b70c0 100644 --- a/commit.c +++ b/commit.c @@ -727,10 +727,10 @@ struct commit *pop_commit(struct commit_list **stack) int count_parents(struct commit * commit) { - int count = 0; + int count; struct commit_list * parents = commit->parents; - for (count=0;parents; parents=parents->next,count++) - ; + for (count = 0; parents; parents = parents->next,count++) + ; return count; } diff --git a/connect.c b/connect.c index b9c222085e..7a6a73f2a3 100644 --- a/connect.c +++ b/connect.c @@ -10,7 +10,7 @@ #include #include -static char *server_capabilities = NULL; +static char *server_capabilities; static int check_ref(const char *name, int len, unsigned int flags) { @@ -493,8 +493,8 @@ static void git_tcp_connect(int fd[2], char *host) } -static char *git_proxy_command = NULL; -static const char *rhost_name = NULL; +static char *git_proxy_command; +static const char *rhost_name; static int rhost_len; static int git_proxy_command_options(const char *var, const char *value) diff --git a/daemon.c b/daemon.c index 810837f0c4..012936f3bd 100644 --- a/daemon.c +++ b/daemon.c @@ -22,24 +22,24 @@ static const char daemon_usage[] = " [--reuseaddr] [--detach] [--pid-file=file] [directory...]"; /* List of acceptable pathname prefixes */ -static char **ok_paths = NULL; -static int strict_paths = 0; +static char **ok_paths; +static int strict_paths; /* If this is set, git-daemon-export-ok is not required */ -static int export_all_trees = 0; +static int export_all_trees; /* Take all paths relative to this one if non-NULL */ -static char *base_path = NULL; +static char *base_path; /* If defined, ~user notation is allowed and the string is inserted * after ~user/. E.g. a request to git://host/~alice/frotz would * go to /home/alice/pub_git/frotz with --user-path=pub_git. */ -static const char *user_path = NULL; +static const char *user_path; /* Timeout, and initial timeout */ -static unsigned int timeout = 0; -static unsigned int init_timeout = 0; +static unsigned int timeout; +static unsigned int init_timeout; static void logreport(int priority, const char *err, va_list params) { @@ -333,12 +333,12 @@ static int execute(struct sockaddr *addr) static int max_connections = 25; /* These are updated by the signal handler */ -static volatile unsigned int children_reaped = 0; +static volatile unsigned int children_reaped; static pid_t dead_child[MAX_CHILDREN]; /* These are updated by the main loop */ -static unsigned int children_spawned = 0; -static unsigned int children_deleted = 0; +static unsigned int children_spawned; +static unsigned int children_deleted; static struct child { pid_t pid; diff --git a/describe.c b/describe.c index 324ca8965b..2b9301fc12 100644 --- a/describe.c +++ b/describe.c @@ -8,12 +8,12 @@ static const char describe_usage[] = "git-describe [--all] [--tags] [--abbrev=] *"; -static int all = 0; /* Default to annotated tags only */ -static int tags = 0; /* But allow any tags if --tags is specified */ +static int all; /* Default to annotated tags only */ +static int tags; /* But allow any tags if --tags is specified */ static int abbrev = DEFAULT_ABBREV; -static int names = 0, allocs = 0; +static int names, allocs; static struct commit_name { const struct commit *commit; int prio; /* annotated tag = 2, tag = 1, head = 0 */ diff --git a/diff.c b/diff.c index 6a8c0c9c01..7a238d0233 100644 --- a/diff.c +++ b/diff.c @@ -13,9 +13,9 @@ static int use_size_cache; -static int diff_detect_rename_default = 0; +static int diff_detect_rename_default; static int diff_rename_limit_default = -1; -static int diff_use_color_default = 0; +static int diff_use_color_default; /* "\033[1;38;5;2xx;48;5;2xxm\0" is 23 bytes */ static char diff_colors[][24] = { diff --git a/environment.c b/environment.c index 87162b2572..e6bd0033b4 100644 --- a/environment.c +++ b/environment.c @@ -13,14 +13,14 @@ char git_default_email[MAX_GITNAME]; char git_default_name[MAX_GITNAME]; int use_legacy_headers = 1; int trust_executable_bit = 1; -int assume_unchanged = 0; -int prefer_symlink_refs = 0; -int log_all_ref_updates = 0; +int assume_unchanged; +int prefer_symlink_refs; +int log_all_ref_updates; int warn_ambiguous_refs = 1; -int repository_format_version = 0; +int repository_format_version; char git_commit_encoding[MAX_ENCODING_LENGTH] = "utf-8"; int shared_repository = PERM_UMASK; -const char *apply_default_whitespace = NULL; +const char *apply_default_whitespace; int zlib_compression_level = Z_DEFAULT_COMPRESSION; int pager_in_use; int pager_use_color = 1; diff --git a/exec_cmd.c b/exec_cmd.c index 62f51fcd6e..e30936d72c 100644 --- a/exec_cmd.c +++ b/exec_cmd.c @@ -5,7 +5,7 @@ extern char **environ; static const char *builtin_exec_path = GIT_EXEC_PATH; -static const char *current_exec_path = NULL; +static const char *current_exec_path; void git_set_exec_path(const char *exec_path) { diff --git a/fetch-pack.c b/fetch-pack.c index b7824dbed4..e18c1489a1 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -24,8 +24,8 @@ static const char *exec = "git-upload-pack"; */ #define MAX_IN_VAIN 256 -static struct commit_list *rev_list = NULL; -static int non_common_revs = 0, multi_ack = 0, use_thin_pack = 0, use_sideband; +static struct commit_list *rev_list; +static int non_common_revs, multi_ack, use_thin_pack, use_sideband; static void rev_list_push(struct commit *commit, int mark) { @@ -250,7 +250,7 @@ done: return retval; } -static struct commit_list *complete = NULL; +static struct commit_list *complete; static int mark_complete(const char *path, const unsigned char *sha1) { diff --git a/fsck-objects.c b/fsck-objects.c index b0e882a99f..31e00d84b3 100644 --- a/fsck-objects.c +++ b/fsck-objects.c @@ -14,12 +14,12 @@ #define REACHABLE 0x0001 #define SEEN 0x0002 -static int show_root = 0; -static int show_tags = 0; -static int show_unreachable = 0; -static int check_full = 0; -static int check_strict = 0; -static int keep_cache_objects = 0; +static int show_root; +static int show_tags; +static int show_unreachable; +static int check_full; +static int check_strict; +static int keep_cache_objects; static unsigned char head_sha1[20]; #ifdef NO_D_INO_IN_DIRENT @@ -400,7 +400,7 @@ static void fsck_dir(int i, char *path) closedir(dir); } -static int default_refs = 0; +static int default_refs; static int fsck_handle_ref(const char *refname, const unsigned char *sha1) { diff --git a/git.c b/git.c index 5da7787d86..930998bbe5 100644 --- a/git.c +++ b/git.c @@ -92,7 +92,7 @@ static int handle_options(const char*** argv, int* argc) } static const char *alias_command; -static char *alias_string = NULL; +static char *alias_string; static int git_alias_config(const char *var, const char *value) { diff --git a/help.c b/help.c index 6484cb9df2..9ecdefdb03 100644 --- a/help.c +++ b/help.c @@ -14,7 +14,7 @@ static int term_columns(void) { char *col_string = getenv("COLUMNS"); - int n_cols = 0; + int n_cols; if (col_string && (n_cols = atoi(col_string)) > 0) return n_cols; diff --git a/http-fetch.c b/http-fetch.c index de5fc44e66..7f07d2a967 100644 --- a/http-fetch.c +++ b/http-fetch.c @@ -36,10 +36,10 @@ enum XML_Status { #define PREV_BUF_SIZE 4096 #define RANGE_HEADER_SIZE 30 -static int commits_on_stdin = 0; +static int commits_on_stdin; static int got_alternates = -1; -static int corrupt_object_found = 0; +static int corrupt_object_found; static struct curl_slist *no_pragma_header; @@ -52,7 +52,7 @@ struct alt_base struct alt_base *next; }; -static struct alt_base *alt = NULL; +static struct alt_base *alt; enum object_request_state { WAITING, @@ -114,7 +114,7 @@ struct remote_ls_ctx }; #endif -static struct object_request *object_queue_head = NULL; +static struct object_request *object_queue_head; static size_t fwrite_sha1_file(void *ptr, size_t eltsize, size_t nmemb, void *data) diff --git a/http-push.c b/http-push.c index 22a3e2bc0a..2bd9845765 100644 --- a/http-push.c +++ b/http-push.c @@ -70,18 +70,18 @@ enum XML_Status { /* We allow "recursive" symbolic refs. Only within reason, though */ #define MAXDEPTH 5 -static int pushing = 0; -static int aborted = 0; +static int pushing; +static int aborted; static signed char remote_dir_exists[256]; static struct curl_slist *no_pragma_header; static struct curl_slist *default_headers; -static int push_verbosely = 0; -static int push_all = 0; -static int force_all = 0; +static int push_verbosely; +static int push_all; +static int force_all; -static struct object_list *objects = NULL; +static struct object_list *objects; struct repo { @@ -94,7 +94,7 @@ struct repo struct remote_lock *locks; }; -static struct repo *remote = NULL; +static struct repo *remote; enum transfer_state { NEED_FETCH, @@ -134,7 +134,7 @@ struct transfer_request struct transfer_request *next; }; -static struct transfer_request *request_queue_head = NULL; +static struct transfer_request *request_queue_head; struct xml_ctx { diff --git a/local-fetch.c b/local-fetch.c index 7d01845d39..7b6875cce6 100644 --- a/local-fetch.c +++ b/local-fetch.c @@ -5,10 +5,10 @@ #include "commit.h" #include "fetch.h" -static int use_link = 0; -static int use_symlink = 0; +static int use_link; +static int use_symlink; static int use_filecopy = 1; -static int commits_on_stdin = 0; +static int commits_on_stdin; static const char *path; /* "Remote" git repository */ @@ -16,7 +16,7 @@ void prefetch(unsigned char *sha1) { } -static struct packed_git *packs = NULL; +static struct packed_git *packs; static void setup_index(unsigned char *sha1) { diff --git a/merge-base.c b/merge-base.c index 59f723f404..009caf804b 100644 --- a/merge-base.c +++ b/merge-base.c @@ -2,7 +2,7 @@ #include "cache.h" #include "commit.h" -static int show_all = 0; +static int show_all; static int merge_base(struct commit *rev1, struct commit *rev2) { diff --git a/merge-index.c b/merge-index.c index a9c8cc1f93..646d090c58 100644 --- a/merge-index.c +++ b/merge-index.c @@ -4,7 +4,7 @@ #include "cache.h" -static const char *pgm = NULL; +static const char *pgm; static const char *arguments[8]; static int one_shot, quiet; static int err; diff --git a/mktree.c b/mktree.c index 9a6f0d2f6b..93241385e4 100644 --- a/mktree.c +++ b/mktree.c @@ -49,7 +49,6 @@ static void write_tree(unsigned char *sha1) int i; qsort(entries, used, sizeof(*entries), ent_compare); - size = 100; for (size = i = 0; i < used; i++) size += 32 + entries[i]->len; buffer = xmalloc(size); diff --git a/pack-redundant.c b/pack-redundant.c index 41fb960569..92a09ed362 100644 --- a/pack-redundant.c +++ b/pack-redundant.c @@ -13,7 +13,7 @@ static const char pack_redundant_usage[] = "git-pack-redundant [ --verbose ] [ --alt-odb ] < --all | <.pack filename> ...>"; -static int load_all_packs = 0, verbose = 0, alt_odb = 0; +static int load_all_packs, verbose, alt_odb; struct llist_item { struct llist_item *next; @@ -37,7 +37,7 @@ struct pll { struct pack_list *pl; }; -static struct llist_item *free_nodes = NULL; +static struct llist_item *free_nodes; static inline void llist_item_put(struct llist_item *item) { diff --git a/read-cache.c b/read-cache.c index b18f9f72d9..3228ffb300 100644 --- a/read-cache.c +++ b/read-cache.c @@ -19,16 +19,16 @@ #define CACHE_EXT(s) ( (s[0]<<24)|(s[1]<<16)|(s[2]<<8)|(s[3]) ) #define CACHE_EXT_TREE 0x54524545 /* "TREE" */ -struct cache_entry **active_cache = NULL; +struct cache_entry **active_cache; static time_t index_file_timestamp; -unsigned int active_nr = 0, active_alloc = 0, active_cache_changed = 0; +unsigned int active_nr, active_alloc, active_cache_changed; -struct cache_tree *active_cache_tree = NULL; +struct cache_tree *active_cache_tree; -int cache_errno = 0; +int cache_errno; -static void *cache_mmap = NULL; -static size_t cache_mmap_size = 0; +static void *cache_mmap; +static size_t cache_mmap_size; /* * This only updates the "non-critical" parts of the directory diff --git a/receive-pack.c b/receive-pack.c index 93929b5371..81e91909b8 100644 --- a/receive-pack.c +++ b/receive-pack.c @@ -8,10 +8,10 @@ static const char receive_pack_usage[] = "git-receive-pack "; static const char *unpacker[] = { "unpack-objects", NULL }; -static int report_status = 0; +static int report_status; static char capabilities[] = "report-status"; -static int capabilities_sent = 0; +static int capabilities_sent; static int show_ref(const char *path, const unsigned char *sha1) { @@ -40,7 +40,7 @@ struct command { char ref_name[FLEX_ARRAY]; /* more */ }; -static struct command *commands = NULL; +static struct command *commands; static int is_all_zeroes(const char *hex) { diff --git a/send-pack.c b/send-pack.c index b7cc1a9089..43e10b0a62 100644 --- a/send-pack.c +++ b/send-pack.c @@ -9,10 +9,10 @@ static const char send_pack_usage[] = "git-send-pack [--all] [--exec=git-receive-pack] [...]\n" " --all and explicit specification are mutually exclusive."; static const char *exec = "git-receive-pack"; -static int verbose = 0; -static int send_all = 0; -static int force_update = 0; -static int use_thin_pack = 0; +static int verbose; +static int send_all; +static int force_update; +static int use_thin_pack; static int is_zero_sha1(const unsigned char *sha1) { diff --git a/sha1_file.c b/sha1_file.c index 842a6f3ae8..18dece46b1 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -22,7 +22,7 @@ #endif #endif -const unsigned char null_sha1[20] = { 0, }; +const unsigned char null_sha1[20]; static unsigned int sha1_file_open_flag = O_NOATIME; diff --git a/ssh-fetch.c b/ssh-fetch.c index c7d8fa80e4..0b89df6dda 100644 --- a/ssh-fetch.c +++ b/ssh-fetch.c @@ -17,7 +17,7 @@ static int fd_in; static int fd_out; -static unsigned char remote_version = 0; +static unsigned char remote_version; static unsigned char local_version = 1; static ssize_t force_write(int fd, void *buffer, size_t length) @@ -36,9 +36,9 @@ static ssize_t force_write(int fd, void *buffer, size_t length) return ret; } -static int prefetches = 0; +static int prefetches; -static struct object_list *in_transit = NULL; +static struct object_list *in_transit; static struct object_list **end_of_transit = &in_transit; void prefetch(unsigned char *sha1) @@ -59,7 +59,7 @@ void prefetch(unsigned char *sha1) } static char conn_buf[4096]; -static size_t conn_buf_posn = 0; +static size_t conn_buf_posn; int fetch(unsigned char *sha1) { diff --git a/ssh-upload.c b/ssh-upload.c index 2da66618fc..20b15eab57 100644 --- a/ssh-upload.c +++ b/ssh-upload.c @@ -15,9 +15,9 @@ #include static unsigned char local_version = 1; -static unsigned char remote_version = 0; +static unsigned char remote_version; -static int verbose = 0; +static int verbose; static int serve_object(int fd_in, int fd_out) { ssize_t size; diff --git a/unpack-trees.c b/unpack-trees.c index e496d8cd31..43ed12484f 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -278,7 +278,7 @@ static void unlink_entry(char *name) } } -static volatile sig_atomic_t progress_update = 0; +static volatile sig_atomic_t progress_update; static void progress_interval(int signum) { diff --git a/upload-pack.c b/upload-pack.c index 27e2abe36c..fcf279843a 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -14,12 +14,12 @@ static const char upload_pack_usage[] = "git-upload-pack [--strict] [--timeout=n #define THEY_HAVE (1U << 0) #define OUR_REF (1U << 1) #define WANTED (1U << 2) -static int multi_ack = 0, nr_our_refs = 0; -static int use_thin_pack = 0; +static int multi_ack, nr_our_refs; +static int use_thin_pack; static struct object_array have_obj; static struct object_array want_obj; -static unsigned int timeout = 0; -static int use_sideband = 0; +static unsigned int timeout; +static int use_sideband; static void reset_timeout(void) { From 520cd3eca5743bebd217423e1fd0721f32613bb1 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 15 Aug 2006 13:09:49 -0700 Subject: [PATCH 136/160] Documentation/technical/racy-git.txt Signed-off-by: Junio C Hamano --- Documentation/technical/racy-git.txt | 193 +++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 Documentation/technical/racy-git.txt diff --git a/Documentation/technical/racy-git.txt b/Documentation/technical/racy-git.txt new file mode 100644 index 0000000000..7597d04142 --- /dev/null +++ b/Documentation/technical/racy-git.txt @@ -0,0 +1,193 @@ +Use of index and Racy git problem +================================= + +Background +---------- + +The index is one of the most important data structure in git. +It represents a virtual working tree state by recording list of +paths and their object names and serves as a staging area to +write out the next tree object to be committed. The state is +"virtual" in the sense that it does not necessarily have to, and +often does not, match the files in the working tree. + +There are cases git needs to examine the differences between the +virtual working tree state in the index and the files in the +working tree. The most obvious case is when the user asks `git +diff` (or its low level implementation, `git diff-files`) or +`git-ls-files --modified`. In addition, git internally checks +if the files in the working tree is different from what are +recorded in the index to avoid stomping on local changes in them +during patch application, switching branches, and merging. + +In order to speed up this comparison between the files in the +working tree and the index entries, the index entries record the +information obtained from the filesystem via `lstat(2)` system +call when they were last updated. When checking if they differ, +git first runs `lstat(2)` on the files and compare the result +with this information (this is what was originally done by the +`ce_match_stat()` function, which the current code does in +`ce_match_stat_basic()` function). If some of these "cached +stat information" fields do not match, git can tell that the +files are modified without even looking at their contents. + +Note: not all members in `struct stat` obtained via `lstat(2)` +are used for this comparison. For example, `st_atime` obviously +is not useful. Currently, git compares the file type (regular +files vs symbolic links) and executable bits (only for regular +files) from `st_mode` member, `st_mtime` and `st_ctime` +timestamps, `st_uid`, `st_gid`, `st_ino`, and `st_size` members. +With a `USE_STDEV` compile-time option, `st_dev` is also +compared, but this is not enabled by default because this member +is not stable on network filesystems. With `USE_NSEC` +compile-time option, `st_mtim.tv_nsec` and `st_ctim.tv_nsec` +members are also compared, but this is not enabled by default +because the value of this member becomes meaningless once the +inode is evicted from the inode cache on filesystems that do not +store it on disk. + + +Racy git +-------- + +There is one slight problem with the optimization based on the +cached stat information. Consider this sequence: + + $ git update-index 'foo' + : modify 'foo' in-place without changing its size + +The first `update-index` computes the object name of the +contents of file `foo` and updates the index entry for `foo` +along with the `struct stat` information. If the modification +that follows it happens very fast so that the file's `st_mtime` +timestamp does not change, after this sequence, the cached stat +information the index entry records still exactly match what you +can obtain from the filesystem, but the file `foo` is modified. +This way, git can incorrectly think files in the working tree +are unmodified even though they actually are. This is called +the "racy git" problem (discovered by Pasky), and the entries +that appear clean when they may not be because of this problem +are called "racily clean". + +To avoid this problem, git does two things: + +. When the cached stat information says the file has not been + modified, and the `st_mtime` is the same as (or newer than) + the timestamp of the index file itself (which is the time `git + update-index foo` finished running in the above example), it + also compares the contents with the object registered in the + index entry to make sure they match. + +. When the index file is updated that contains racily clean + entries, cached `st_size` information is truncated to zero + before writing a new version of the index file. + +Because the index file itself is written after collecting all +the stat information from updated paths, `st_mtime` timestamp of +it is usually the same as or newer than any of the paths the +index contains. And no matter how quick the modification that +follows `git update-index foo` finishes, the resulting +`st_mtime` timestamp on `foo` cannot get the timestamp earlier +than the index file. Therefore, index entries that can be +racily clean are limited to the ones that have the same +timestamp as the index file itself. + +The callers that want to check if an index entry matches the +corresponding file in the working tree continue to call +`ce_match_stat()`, but with this change, `ce_match_stat()` uses +`ce_modified_check_fs()` to see if racily clean ones are +actually clean after comparing the cached stat information using +`ce_match_stat_basic()`. + +The problem the latter solves is this sequence: + + $ git update-index 'foo' + : modify 'foo' in-place without changing its size + : wait for enough time + $ git update-index 'bar' + +Without the latter, the timestamp of the index file gets a newer +value, and falsely clean entry `foo` would not be caught by the +timestamp comparison check done with the former logic anymore. +The latter makes sure that the cached stat information for `foo` +would never match with the file in the working tree, so later +checks by `ce_match_stat_basic()` would report the index entry +does not match the file and git does not have to fall back on more +expensive `ce_modified_check_fs()`. + + +Runtime penalty +--------------- + +The runtime penalty of falling back to `ce_modified_check_fs()` +from `ce_match_stat()` can be very expensive when there are many +racily clean entries. An obvious way to artificially create +this situation is to give the same timestamp to all the files in +the working tree in a large project, run `git update-index` on +them, and give the same timestamp to the index file: + + $ date >.datestamp + $ git ls-files | xargs touch -r .datestamp + $ git ls-files | git update-index --stdin + $ touch -r .datestamp .git/index + +This will make all index entries racily clean. The linux-2.6 +project, for example, there are over 20,000 files in the working +tree. On my Athron 64X2 3800+, after the above: + + $ /usr/bin/time git diff-files + 1.68user 0.54system 0:02.22elapsed 100%CPU (0avgtext+0avgdata 0maxresident)k + 0inputs+0outputs (0major+67111minor)pagefaults 0swaps + $ git update-index MAINTAINERS + $ /usr/bin/time git diff-files + 0.02user 0.12system 0:00.14elapsed 100%CPU (0avgtext+0avgdata 0maxresident)k + 0inputs+0outputs (0major+935minor)pagefaults 0swaps + +Running `git update-index` in the middle checked the racily +clean entries, and left the cached `st_mtime` for all the paths +intact because they were actually clean (so this step took about +the same amount of time as the first `git diff-files`). After +that, they are not racily clean anymore but are truly clean, so +the second invocation of `git diff-files` fully took advantage +of the cached stat information. + + +Avoiding runtime penalty +------------------------ + +In order to avoid the above runtime penalty, the recent "master" +branch (post 1.4.2) has a code that makes sure the index file +gets timestamp newer than the youngest files in the index when +there are many young files with the same timestamp as the +resulting index file would otherwise would have by waiting +before finishing writing the index file out. + +I suspect that in practice the situation where many paths in the +index are all racily clean is quite rare. The only code paths +that can record recent timestamp for large number of paths I +know of are: + +. Initial `git add .` of a large project. + +. `git checkout` of a large project from an empty index into an + unpopulated working tree. + +Note: switching branches with `git checkout` keeps the cached +stat information of existing working tree files that are the +same between the current branch and the new branch, which are +all older than the resulting index file, and they will not +become racily clean. Only the files that are actually checked +out can become racily clean. + +In a large project where raciness avoidance cost really matters, +however, the initial computation of all object names in the +index takes more than one second, and the index file is written +out after all that happens. Therefore the timestamp of the +index file will be more than one seconds later than the the +youngest file in the working tree. This means that in these +cases there actually will not be any racily clean entry in +the resulting index. + +So in summary I think we should not worry about avoiding the +runtime penalty and get rid of the "wait before finishing +writing" code out. From 42f774063db1442fc3815f596d263f90dcd8380b Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 15 Aug 2006 21:38:07 -0700 Subject: [PATCH 137/160] Add check program "git-check-racy" This will help counting the racily clean paths, but it should be useless for daily use. Do not even enable it in the makefile. Signed-off-by: Junio C Hamano --- Makefile | 6 +++++- check-racy.c | 28 ++++++++++++++++++++++++++++ read-cache.c | 12 +++++++++--- 3 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 check-racy.c diff --git a/Makefile b/Makefile index b86de761ff..04ed84d094 100644 --- a/Makefile +++ b/Makefile @@ -194,7 +194,11 @@ PROGRAMS = \ git-update-server-info$X \ git-upload-pack$X git-verify-pack$X \ git-pack-redundant$X git-var$X \ - git-describe$X git-merge-tree$X git-blame$X git-imap-send$X + git-describe$X git-merge-tree$X git-blame$X git-imap-send$X \ + $(EXTRA_PROGRAMS) + +# Empty... +EXTRA_PROGRAMS = BUILT_INS = \ git-format-patch$X git-show$X git-whatchanged$X \ diff --git a/check-racy.c b/check-racy.c new file mode 100644 index 0000000000..d6a08b4a55 --- /dev/null +++ b/check-racy.c @@ -0,0 +1,28 @@ +#include "cache.h" + +int main(int ac, char **av) +{ + int i; + int dirty, clean, racy; + + dirty = clean = racy = 0; + read_cache(); + for (i = 0; i < active_nr; i++) { + struct cache_entry *ce = active_cache[i]; + struct stat st; + + if (lstat(ce->name, &st)) { + error("lstat(%s): %s", ce->name, strerror(errno)); + continue; + } + + if (ce_match_stat(ce, &st, 0)) + dirty++; + else if (ce_match_stat(ce, &st, 2)) + racy++; + else + clean++; + } + printf("dirty %d, clean %d, racy %d\n", dirty, clean, racy); + return 0; +} diff --git a/read-cache.c b/read-cache.c index ec4dd5ae6c..4d621ef444 100644 --- a/read-cache.c +++ b/read-cache.c @@ -169,9 +169,11 @@ static int ce_match_stat_basic(struct cache_entry *ce, struct stat *st) return changed; } -int ce_match_stat(struct cache_entry *ce, struct stat *st, int ignore_valid) +int ce_match_stat(struct cache_entry *ce, struct stat *st, int options) { unsigned int changed; + int ignore_valid = options & 01; + int assume_racy_is_modified = options & 02; /* * If it's marked as always valid in the index, it's @@ -200,8 +202,12 @@ int ce_match_stat(struct cache_entry *ce, struct stat *st, int ignore_valid) */ if (!changed && index_file_timestamp && - index_file_timestamp <= ntohl(ce->ce_mtime.sec)) - changed |= ce_modified_check_fs(ce, st); + index_file_timestamp <= ntohl(ce->ce_mtime.sec)) { + if (assume_racy_is_modified) + changed |= DATA_CHANGED; + else + changed |= ce_modified_check_fs(ce, st); + } return changed; } From 19a8721ef8f82153fee93c62bd050659cf718d6d Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Tue, 15 Aug 2006 23:03:17 +0200 Subject: [PATCH 138/160] gitweb: Show project's git URL on summary page From 31e4de9f22a3b17d4ad0ac800132e4e1a0a15006 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Tue, 15 Aug 2006 11:43:04 -0700 Subject: [PATCH] gitweb: Show project's git URL on summary page Add support for showing multiple clone/fetch git URLs for project on a summary page. URL for project is created from base URL and project name. For example for XMMS2 project (xmms.se) the git base URL would be git://git.xmms.se/xmms2. With corrections from David Rientjes Signed-off-by: Jakub Narebski Signed-off-by: David Rientjes Signed-off-by: Junio C Hamano --- Makefile | 2 ++ gitweb/gitweb.perl | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 399d2333d0..56a915e13f 100644 --- a/Makefile +++ b/Makefile @@ -126,6 +126,7 @@ GITWEB_CONFIG = gitweb_config.perl GITWEB_HOME_LINK_STR = projects GITWEB_SITENAME = GITWEB_PROJECTROOT = /pub/git +GITWEB_BASE_URL = GITWEB_LIST = GITWEB_HOMETEXT = indextext.html GITWEB_CSS = gitweb.css @@ -622,6 +623,7 @@ gitweb/gitweb.cgi: gitweb/gitweb.perl -e 's|++GITWEB_HOME_LINK_STR++|$(GITWEB_HOME_LINK_STR)|g' \ -e 's|++GITWEB_SITENAME++|$(GITWEB_SITENAME)|g' \ -e 's|++GITWEB_PROJECTROOT++|$(GITWEB_PROJECTROOT)|g' \ + -e 's|++GITWEB_BASE_URL++|$(GITWEB_BASE_URL)|g' \ -e 's|++GITWEB_LIST++|$(GITWEB_LIST)|g' \ -e 's|++GITWEB_HOMETEXT++|$(GITWEB_HOMETEXT)|g' \ -e 's|++GITWEB_CSS++|$(GITWEB_CSS)|g' \ diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index b5b89de91b..0e1de297e9 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -54,6 +54,10 @@ our $logo = "++GITWEB_LOGO++"; # source of projects list our $projects_list = "++GITWEB_LIST++"; +# list of git base URLs used for URL to where fetch project from, +# i.e. full URL is "$git_base_url/$project" +our @git_base_url_list = ("++GITWEB_BASE_URL++"); + # default blob_plain mimetype and default charset for text/plain blob our $default_blob_plain_mimetype = 'text/plain'; our $default_text_plain_charset = undef; @@ -1668,8 +1672,14 @@ sub git_summary { print "\n" . "\n" . "\n" . - "\n" . - "
description" . esc_html($descr) . "
owner$owner
last change$cd{'rfc2822'}
\n"; + "last change$cd{'rfc2822'}\n"; + my $url_tag = "URL"; + foreach my $git_base_url (@git_base_url_list) { + next unless $git_base_url; + print "$url_tag$git_base_url/$project\n"; + $url_tag = ""; + } + print "\n"; open my $fd, "-|", $GIT, "rev-list", "--max-count=17", git_get_head_hash($project) or die_error(undef, "Open git-rev-list failed"); From 06a9d86b49b826562e2b12b5c7e831e20b8f7dce Mon Sep 17 00:00:00 2001 From: Martin Waitz Date: Wed, 16 Aug 2006 00:23:50 +0200 Subject: [PATCH 139/160] gitweb: provide function to format the URL for an action link. Provide a new function which can be used to generate an URL for the CGI. This makes it possible to consolidate the URL generation in order to make it easier to change the encoding of actions into URLs. Signed-off-by: Martin Waitz Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 0e1de297e9..1471d4dadb 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -184,6 +184,33 @@ if (!defined($actions{$action})) { $actions{$action}->(); exit; +## ====================================================================== +## action links + +sub href(%) { + my %mapping = ( + action => "a", + project => "p", + file_name => "f", + hash => "h", + hash_parent => "hp", + hash_base => "hb", + page => "pg", + searchtext => "s", + ); + + my %params = @_; + $params{"project"} ||= $project; + + my $href = "$my_uri?"; + $href .= esc_param( join(";", + map { "$mapping{$_}=$params{$_}" } keys %params + ) ); + + return $href; +} + + ## ====================================================================== ## validation, quoting/unquoting and escaping From 1c2a4f5addce479c619057c6cdc841802139982f Mon Sep 17 00:00:00 2001 From: Martin Waitz Date: Wed, 16 Aug 2006 00:24:30 +0200 Subject: [PATCH 140/160] gitweb: consolidate action URL generation. Use the href() function instead of string concatenation to generate most URLs to our own CGI. This is a work in progress, not everything has been converted yet. Signed-off-by: Martin Waitz Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 171 ++++++++++++++++++++++----------------------- 1 file changed, 84 insertions(+), 87 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 1471d4dadb..37a6284fc4 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -388,7 +388,7 @@ sub format_log_line_html { if ($line =~ m/([0-9a-fA-F]{40})/) { my $hash_text = $1; if (git_get_type($hash_text) eq "commit") { - my $link = $cgi->a({-class => "text", -href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_text")}, $hash_text); + my $link = $cgi->a({-class => "text", -href => href(action=>"commit", hash=>$hash_text)}, $hash_text); $line =~ s/$hash_text/$link/; } } @@ -425,16 +425,15 @@ sub format_ref_marker { # format, perhaps shortened and with markers, title line sub format_subject_html { - my ($long, $short, $query, $extra) = @_; + my ($long, $short, $href, $extra) = @_; $extra = '' unless defined($extra); if (length($short) < length($long)) { - return $cgi->a({-href => "$my_uri?" . esc_param($query), - -class => "list", -title => $long}, + return $cgi->a({-href => $href, -class => "list", + -title => $long}, esc_html($short) . $extra); } else { - return $cgi->a({-href => "$my_uri?" . esc_param($query), - -class => "list"}, + return $cgi->a({-href => $href, -class => "list"}, esc_html($long) . $extra); } } @@ -998,8 +997,7 @@ EOF if (defined $project) { printf(''."\n", - esc_param($project), - esc_param("$my_uri?p=$project;a=rss")); + esc_param($project), href(action=>"rss")); } print "\n" . @@ -1010,7 +1008,7 @@ EOF "\n"; print $cgi->a({-href => esc_param($home_link)}, $home_link_str) . " / "; if (defined $project) { - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary")}, esc_html($project)); + print $cgi->a({-href => href(action=>"summary")}, esc_html($project)); if (defined $action) { print " / $action"; } @@ -1047,7 +1045,7 @@ sub git_footer_html { if (defined $descr) { print "\n"; } - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=rss"), -class => "rss_logo"}, "RSS") . "\n"; + print $cgi->a({-href => href(action=>"rss"), -class => "rss_logo"}, "RSS") . "\n"; } else { print $cgi->a({-href => "$my_uri?" . esc_param("a=opml"), -class => "rss_logo"}, "OPML") . "\n"; } @@ -1082,27 +1080,25 @@ sub git_print_page_nav { @navs = grep { $_ ne $suppress } @navs; } - my %arg = map { $_, ''} @navs; + my %arg = map { $_ => {action=>$_} } @navs; if (defined $head) { for (qw(commit commitdiff)) { - $arg{$_} = ";h=$head"; + $arg{$_}{hash} = $head; } if ($current =~ m/^(tree | log | shortlog | commit | commitdiff | search)$/x) { for (qw(shortlog log)) { - $arg{$_} = ";h=$head"; + $arg{$_}{hash} = $head; } } } - $arg{tree} .= ";h=$treehead" if defined $treehead; - $arg{tree} .= ";hb=$treebase" if defined $treebase; + $arg{tree}{hash} = $treehead if defined $treehead; + $arg{tree}{hash_base} = $treebase if defined $treebase; print "
\n" . (join " | ", - map { $_ eq $current - ? $_ - : $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$_$arg{$_}")}, "$_") - } - @navs); + map { $_ eq $current ? + $_ : $cgi->a({-href => href(%{$arg{$_}})}, "$_") + } @navs); print "
\n$extra
\n" . "
\n"; } @@ -1113,14 +1109,14 @@ sub format_paging_nav { if ($hash ne $head || $page) { - $paging_nav .= $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$action")}, "HEAD"); + $paging_nav .= $cgi->a({-href => href(action=>$action)}, "HEAD"); } else { $paging_nav .= "HEAD"; } if ($page > 0) { $paging_nav .= " ⋅ " . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$action;h=$hash;pg=" . ($page-1)), + $cgi->a({-href => href(action=>$action, hash=>$hash, page=>$page-1), -accesskey => "p", -title => "Alt-p"}, "prev"); } else { $paging_nav .= " ⋅ prev"; @@ -1128,7 +1124,7 @@ sub format_paging_nav { if ($nrevs >= (100 * ($page+1)-1)) { $paging_nav .= " ⋅ " . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$action;h=$hash;pg=" . ($page+1)), + $cgi->a({-href => href(action=>$action, hash=>$hash, page=>$page+1), -accesskey => "n", -title => "Alt-n"}, "next"); } else { $paging_nav .= " ⋅ next"; @@ -1142,15 +1138,16 @@ sub format_paging_nav { sub git_print_header_div { my ($action, $title, $hash, $hash_base) = @_; - my $rest = ''; + my %args = (); - $rest .= ";h=$hash" if $hash; - $rest .= ";hb=$hash_base" if $hash_base; + $args{action} = $action; + $args{hash} = $hash if $hash; + $args{hash_base} = $hash_base if $hash_base; print "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$action$rest"), - -class => "title"}, $title ? $title : $action) . "\n" . - "
\n"; + $cgi->a({-href => href(%args), -class => "title"}, + $title ? $title : $action) . + "\n
\n"; } sub git_print_page_path { @@ -1161,7 +1158,7 @@ sub git_print_page_path { print "
/
\n"; } elsif (defined $type && $type eq 'blob') { print "
" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;f=$file_name")}, esc_html($name)) . "
\n"; + $cgi->a({-href => href(action=>"blob_plain", file_name=>$file_name)}, esc_html($name)) . "
\n"; } else { print "
" . esc_html($name) . "
\n"; } @@ -1208,22 +1205,22 @@ sub git_difftree_body { $mode_chng = sprintf(" with mode: %04o", (oct $to_mode) & 0777); } print "" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$file"), + $cgi->a({-href => href(action=>"blob", hash=>$to_id, hash_base=>$hash, file_name=>$file), -class => "list"}, esc_html($file)) . "\n" . "[new " . file_type($to_mode) . "$mode_chng]\n" . "" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$file")}, "blob") . + $cgi->a({-href => href(action=>"blob", hash=>$to_id, hash_base=>$hash, file_name=>$file)}, "blob") . "\n"; } elsif ($status eq "D") { # deleted print "" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$parent;f=$file"), + $cgi->a({-href => href(action=>"blob", hash=>$from_id, hash_base=>$parent, file_name=>$file), -class => "list"}, esc_html($file)) . "\n" . "[deleted " . file_type($from_mode). "]\n" . "" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$parent;f=$file")}, "blob") . " | " . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;hb=$parent;f=$file")}, "history") . + $cgi->a({-href => href(action=>"blob", hash=>$from_id, hash_base=>$parent, file_name=>$file)}, "blob") . " | " . + $cgi->a({-href => href(action=>"history", hash_base=>$parent, file_name=>$file)}, "history") . "\n" } elsif ($status eq "M" || $status eq "T") { # modified, or type changed @@ -1244,20 +1241,20 @@ sub git_difftree_body { } print ""; if ($to_id ne $from_id) { # modified - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blobdiff;h=$to_id;hp=$from_id;hb=$hash;f=$file"), + print $cgi->a({-href => href(action=>"blobdiff", hash=>$to_id, hash_parent=>$from_id, hash_base=>$hash, file_name=>$file), -class => "list"}, esc_html($file)); } else { # mode changed - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$file"), + print $cgi->a({-href => href(action=>"blob", hash=>$to_id, hash_base=>$hash, file_name=>$file), -class => "list"}, esc_html($file)); } print "\n" . "$mode_chnge\n" . "" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$file")}, "blob"); + $cgi->a({-href => href(action=>"blob", hash=>$to_id, hash_base=>$hash, file_name=>$file)}, "blob"); if ($to_id ne $from_id) { # modified - print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blobdiff;h=$to_id;hp=$from_id;hb=$hash;f=$file")}, "diff"); + print $cgi->a({-href => href(action=>"blobdiff", hash=>$to_id, hash_parent=>$from_id, hash_base=>$hash, file_name=>$file)}, "diff"); } - print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;hb=$hash;f=$file")}, "history") . "\n"; + print " | " . $cgi->a({-href => href(action=>"history", hash_base=>$hash, file_name=>$file)}, "history") . "\n"; print "\n"; } elsif ($status eq "R") { # renamed @@ -1267,14 +1264,14 @@ sub git_difftree_body { $mode_chng = sprintf(", mode: %04o", (oct $to_mode) & 0777); } print "" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$to_file"), + $cgi->a({-href => href(action=>"blob", hash=>$to_id, hash_base=>$hash, file_name=>$to_file), -class => "list"}, esc_html($to_file)) . "\n" . "[moved from " . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$parent;f=$from_file"), + $cgi->a({-href => href(action=>"blob", hash=>$from_id, hash_base=>$parent, file_name=>$from_file), -class => "list"}, esc_html($from_file)) . " with " . (int $similarity) . "% similarity$mode_chng]\n" . "" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$to_file")}, "blob"); + $cgi->a({-href => href(action=>"blob", hash=>$to_id, hash_base=>$hash, file_name=>$to_file)}, "blob"); if ($to_id ne $from_id) { print " | " . $cgi->a({-href => "$my_uri?" . @@ -1289,14 +1286,14 @@ sub git_difftree_body { $mode_chng = sprintf(", mode: %04o", (oct $to_mode) & 0777); } print "" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$to_file"), + $cgi->a({-href => href(action=>"blob", hash=>$to_id, hash_base=>$hash, file_name=>$to_file), -class => "list"}, esc_html($to_file)) . "\n" . "[copied from " . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$parent;f=$from_file"), + $cgi->a({-href => href(action=>"blob", hash=>$from_id, hash_base=>$parent, file_name=>$from_file), -class => "list"}, esc_html($from_file)) . " with " . (int $similarity) . "% similarity$mode_chng]\n" . "" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$to_id;hb=$hash;f=$to_file")}, "blob"); + $cgi->a({-href => href(action=>"blob", hash=>$to_id, hash_base=>$hash, file_name=>$to_file)}, "blob"); if ($to_id ne $from_id) { print " | " . $cgi->a({-href => "$my_uri?" . @@ -1332,11 +1329,11 @@ sub git_shortlog_body { print "$co{'age_string_date'}\n" . "" . esc_html(chop_str($co{'author_name'}, 10)) . "\n" . ""; - print format_subject_html($co{'title'}, $co{'title_short'}, "p=$project;a=commit;h=$commit", $ref); + print format_subject_html($co{'title'}, $co{'title_short'}, href(action=>"commit", hash=>$commit), $ref); print "\n" . "" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit")}, "commit") . " | " . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$commit")}, "commitdiff") . + $cgi->a({-href => href(action=>"commit", hash=>$commit)}, "commit") . " | " . + $cgi->a({-href => href(action=>"commitdiff", hash=>$commit)}, "commitdiff") . "\n" . "\n"; } @@ -1378,12 +1375,12 @@ sub git_history_body { "" . esc_html(chop_str($co{'author_name'}, 15, 3)) . "\n" . ""; # originally git_history used chop_str($co{'title'}, 50) - print format_subject_html($co{'title'}, $co{'title_short'}, "p=$project;a=commit;h=$commit", $ref); + print format_subject_html($co{'title'}, $co{'title_short'}, href(action=>"commit", hash=>$commit), $ref); print "\n" . "" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit")}, "commit") . " | " . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$commit")}, "commitdiff") . " | " . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$ftype;hb=$commit;f=$file_name")}, $ftype); + $cgi->a({-href => href(action=>"commit", hash=>$commit)}, "commit") . " | " . + $cgi->a({-href => href(action=>"commitdiff", hash=>$commit)}, "commitdiff") . " | " . + $cgi->a({-href => href(action=>$ftype, hash_base=>$commit, file_name=>$file_name)}, $ftype); if ($ftype eq 'blob') { my $blob_current = git_get_hash_by_path($hash_base, $file_name); @@ -1391,7 +1388,7 @@ sub git_history_body { if (defined $blob_current && defined $blob_parent && $blob_current ne $blob_parent) { print " | " . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blobdiff;h=$blob_current;hp=$blob_parent;hb=$commit;f=$file_name")}, + $cgi->a({-href => href(action=>"blobdiff", hash=>$blob_current, hash_parent=>$blob_parent, hash_base=>$commit, file_name=>$file_name)}, "diff to current"); } } @@ -1431,28 +1428,28 @@ sub git_tags_body { $alternate ^= 1; print "$tag{'age'}\n" . "" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$tag{'reftype'};h=$tag{'refid'}"), + $cgi->a({-href => href(action=>$tag{'reftype'}, hash=>$tag{'refid'}), -class => "list"}, "" . esc_html($tag{'name'}) . "") . "\n" . ""; if (defined $comment) { - print format_subject_html($comment, $comment_short, "p=$project;a=tag;h=$tag{'id'}"); + print format_subject_html($comment, $comment_short, href(action=>"tag", hash=>$tag{'id'})); } print "\n" . ""; if ($tag{'type'} eq "tag") { - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}")}, "tag"); + print $cgi->a({-href => href(action=>"tag", hash=>$tag{'id'})}, "tag"); } else { print " "; } print "\n" . "" . " | " . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$tag{'reftype'};h=$tag{'refid'}")}, $tag{'reftype'}); + $cgi->a({-href => href(action=>$tag{'reftype'}, hash=>$tag{'refid'})}, $tag{'reftype'}); if ($tag{'reftype'} eq "commit") { - print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog;h=$tag{'name'}")}, "shortlog") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log;h=$tag{'refid'}")}, "log"); + print " | " . $cgi->a({-href => href(action=>"shortlog", hash=>$tag{'name'})}, "shortlog") . + " | " . $cgi->a({-href => href(action=>"log", hash=>$tag{'refid'})}, "log"); } elsif ($tag{'reftype'} eq "blob") { - print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;h=$tag{'refid'}")}, "raw"); + print " | " . $cgi->a({-href => href(action=>"blob_plain", hash=>$tag{'refid'})}, "raw"); } print "\n" . ""; @@ -1485,12 +1482,12 @@ sub git_heads_body { $alternate ^= 1; print "$tag{'age'}\n" . ($tag{'id'} eq $head ? "" : "") . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog;h=$tag{'name'}"), + $cgi->a({-href => href(action=>"shortlog", hash=>$tag{'name'}), -class => "list"}, "" . esc_html($tag{'name'}) . "") . "\n" . "" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog;h=$tag{'name'}")}, "shortlog") . " | " . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log;h=$tag{'name'}")}, "log") . + $cgi->a({-href => href(action=>"shortlog", hash=>$tag{'name'})}, "shortlog") . " | " . + $cgi->a({-href => href(action=>"log", hash=>$tag{'name'})}, "log") . "\n" . ""; } @@ -1714,20 +1711,20 @@ sub git_summary { close $fd; git_print_header_div('shortlog'); git_shortlog_body(\@revlist, 0, 15, $refs, - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog")}, "...")); + $cgi->a({-href => href(action=>"shortlog")}, "...")); my $taglist = git_get_refs_list("refs/tags"); if (defined @$taglist) { git_print_header_div('tags'); git_tags_body($taglist, 0, 15, - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tags")}, "...")); + $cgi->a({-href => href(action=>"tags")}, "...")); } my $headlist = git_get_refs_list("refs/heads"); if (defined @$headlist) { git_print_header_div('heads'); git_heads_body($headlist, $head, 0, 15, - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=heads")}, "...")); + $cgi->a({-href => href(action=>"heads")}, "...")); } git_footer_html(); @@ -1743,8 +1740,8 @@ sub git_tag { "\n" . "\n" . "\n" . - "\n" . - "\n" . + "\n" . + "\n" . "\n"; if (defined($tag{'author'})) { my %ad = parse_date($tag{'epoch'}, $tag{'tz'}); @@ -1783,8 +1780,8 @@ sub git_blame2 { or die_error(undef, "Open git-blame failed"); git_header_html(); my $formats_nav = - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$hash;hb=$hash_base;f=$file_name")}, "blob") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;f=$file_name")}, "head"); + $cgi->a({-href => href(action=>"blobl", hash=>$hash, hash_base=>$hash_base, file_name=>$file_name)}, "blob") . + " | " . $cgi->a({-href => href(action=>"blame", file_name=>$file_name)}, "head"); git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); git_print_header_div('commit', esc_html($co{'title'}), $hash_base); git_print_page_path($file_name, $ftype); @@ -1810,7 +1807,7 @@ sub git_blame2 { } print "\n"; print "\n"; + $cgi->a({-href => href(action=>"commit", hash=>$full_rev, file_name=>$file_name)}, esc_html($rev)) . "\n"; print "\n"; print "\n"; print "\n"; @@ -1837,8 +1834,8 @@ sub git_blame { or die_error(undef, "Open git-annotate failed"); git_header_html(); my $formats_nav = - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$hash;hb=$hash_base;f=$file_name")}, "blob") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;f=$file_name")}, "head"); + $cgi->a({-href => href(action=>"blobl", hash=>$hash, hash_base=>$hash_base, file_name=>$file_name)}, "blob") . + " | " . $cgi->a({-href => href(action=>"blame", file_name=>$file_name)}, "head"); git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); git_print_header_div('commit', esc_html($co{'title'}), $hash_base); git_print_page_path($file_name, 'blob'); @@ -1893,7 +1890,7 @@ HTML print < - + @@ -1989,13 +1986,13 @@ sub git_blob { if (defined $hash_base && (my %co = parse_commit($hash_base))) { if (defined $file_name) { if ($have_blame) { - $formats_nav .= $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;h=$hash;hb=$hash_base;f=$file_name")}, "blame") . " | "; + $formats_nav .= $cgi->a({-href => href(action=>"blame", hash=>$hash, hash_base=>$hash_base, file_name=>$file_name)}, "blame") . " | "; } $formats_nav .= - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;h=$hash;f=$file_name")}, "plain") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;hb=HEAD;f=$file_name")}, "head"); + $cgi->a({-href => href(action=>"blob_plain", hash=>$hash, file_name=>$file_name)}, "plain") . + " | " . $cgi->a({-href => href(action=>"blob", hash_base=>"HEAD", file_name=>$file_name)}, "head"); } else { - $formats_nav .= $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;h=$hash")}, "plain"); + $formats_nav .= $cgi->a({-href => href(action=>"blob_plain", hash=>$hash)}, "plain"); } git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); git_print_header_div('commit', esc_html($co{'title'}), $hash_base); @@ -2139,8 +2136,8 @@ sub git_log { $commit); print "
\n" . "
\n" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit")}, "commit") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$commit")}, "commitdiff") . + $cgi->a({-href => href(action=>"commit", hash=>$commit)}, "commit") . + " | " . $cgi->a({-href => href(action=>"commitdiff", hash=>$commit)}, "commitdiff") . "
\n" . "
\n" . "" . esc_html($co{'author_name'}) . " [$ad{'rfc2822'}]
\n" . @@ -2197,7 +2194,7 @@ sub git_commit { my $formats_nav = ''; if (defined $file_name && defined $co{'parent'}) { my $parent = $co{'parent'}; - $formats_nav .= $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;hb=$parent;f=$file_name")}, "blame"); + $formats_nav .= $cgi->a({-href => href(action=>"blame", hash_parent=>$parent, file_name=>$file_name)}, "blame"); } git_header_html(undef, $expires); git_print_page_nav('commit', defined $co{'parent'} ? '' : 'commitdiff', @@ -2227,19 +2224,19 @@ sub git_commit { print "
" . "" . "" . - "" . "\n"; my $parents = $co{'parents'}; foreach my $par (@$parents) { print "" . "" . - "" . + "" . "" . "\n"; } From 0fc82cff12a887c1e0e7e69937dbd8a82843c081 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 15 Aug 2006 21:40:43 -0700 Subject: [PATCH 141/160] Remove the "delay writing to avoid runtime penalty of racy-git avoidance" The work-around should not be needed. Even if it turns out we would want it later, git will remember the patch for us ;-). Signed-off-by: Junio C Hamano --- read-cache.c | 53 +--------------------------------------------------- 1 file changed, 1 insertion(+), 52 deletions(-) diff --git a/read-cache.c b/read-cache.c index 4d621ef444..be81ac2d2b 100644 --- a/read-cache.c +++ b/read-cache.c @@ -959,9 +959,7 @@ int write_cache(int newfd, struct cache_entry **cache, int entries) { SHA_CTX c; struct cache_header hdr; - int i, removed, recent; - struct stat st; - time_t now; + int i, removed; for (i = removed = 0; i < entries; i++) if (!cache[i]->ce_mode) @@ -999,54 +997,5 @@ int write_cache(int newfd, struct cache_entry **cache, int entries) return -1; } } - - /* - * To prevent later ce_match_stat() from always falling into - * check_fs(), if we have too many entries that can trigger - * racily clean check, we are better off delaying the return. - * We arbitrarily say if more than 20 paths or 25% of total - * paths are very new, we delay the return until the index - * file gets a new timestamp. - * - * NOTE! NOTE! NOTE! - * - * This assumes that nobody is touching the working tree while - * we are updating the index. - */ - - /* Make sure that the new index file has st_mtime - * that is current enough -- ce_write() batches the data - * so it might not have written anything yet. - */ - ce_write_flush(&c, newfd); - - now = fstat(newfd, &st) ? 0 : st.st_mtime; - if (now) { - recent = 0; - for (i = 0; i < entries; i++) { - struct cache_entry *ce = cache[i]; - time_t entry_time = (time_t) ntohl(ce->ce_mtime.sec); - if (!ce->ce_mode) - continue; - if (now && now <= entry_time) - recent++; - } - if (20 < recent && entries <= recent * 4) { -#if 0 - fprintf(stderr, "entries %d\n", entries); - fprintf(stderr, "recent %d\n", recent); - fprintf(stderr, "now %lu\n", now); -#endif - while (!fstat(newfd, &st) && st.st_mtime <= now) { - off_t where = lseek(newfd, 0, SEEK_CUR); - sleep(1); - if ((where == (off_t) -1) || - (write(newfd, "", 1) != 1) || - (lseek(newfd, -1, SEEK_CUR) != where) || - ftruncate(newfd, where)) - break; - } - } - } return ce_flush(&c, newfd); } From d78b0f3d6aa04510dd0c22c3853d3954c5f5b531 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Wed, 16 Aug 2006 10:44:02 +0200 Subject: [PATCH 142/160] [PATCH] git-mv: add more path normalization We already use the normalization from get_pathspec(), but now we also remove a trailing slash. So, git mv some_path/ into_some_path/ works now. Also, move the "can not move directory into itself" test before the subdirectory expansion. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- builtin-mv.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/builtin-mv.c b/builtin-mv.c index e7b5eb7088..c0c8764f7f 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -17,12 +17,19 @@ static const char builtin_mv_usage[] = static const char **copy_pathspec(const char *prefix, const char **pathspec, int count, int base_name) { + int i; const char **result = xmalloc((count + 1) * sizeof(const char *)); memcpy(result, pathspec, count * sizeof(const char *)); result[count] = NULL; - if (base_name) { - int i; - for (i = 0; i < count; i++) { + for (i = 0; i < count; i++) { + int length = strlen(result[i]); + if (length > 0 && result[i][length - 1] == '/') { + char *without_slash = xmalloc(length); + memcpy(without_slash, result[i], length - 1); + without_slash[length] = '\0'; + result[i] = without_slash; + } + if (base_name) { const char *last_slash = strrchr(result[i], '/'); if (last_slash) result[i] = last_slash + 1; @@ -129,6 +136,12 @@ int cmd_mv(int argc, const char **argv, const char *prefix) if (lstat(source[i], &st) < 0) bad = "bad source"; + if (!bad && + (length = strlen(source[i])) >= 0 && + !strncmp(destination[i], source[i], length) && + (destination[i][length] == 0 || destination[i][length] == '/')) + bad = "can not move directory into itself"; + if (S_ISDIR(st.st_mode)) { const char *dir = source[i], *dest_dir = destination[i]; int first, last, len = strlen(dir); @@ -204,12 +217,6 @@ int cmd_mv(int argc, const char **argv, const char *prefix) } } - if (!bad && - (length = strlen(source[i])) >= 0 && - !strncmp(destination[i], source[i], length) && - (destination[i][length] == 0 || destination[i][length] == '/')) - bad = "can not move directory into itself"; - if (!bad && cache_name_pos(source[i], strlen(source[i])) < 0) bad = "not under version control"; From e79ca7cc25755ac1a3be921f30630f4f064bf862 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Wed, 16 Aug 2006 14:50:34 +0200 Subject: [PATCH 143/160] gitweb: Add support for per project git URLs It is now possible for project to have individual clone/fetch URLs. They are provided in new file 'cloneurl' added below project's $GIT_DIR directory. If there is no cloneurl file, concatenation of git base URLs with project name is used. This is merge of Jakub Narebski and David Rientjes gitweb: Show project's git URL on summary page with Aneesh Kumar gitweb: Add support for cloneurl. gitweb: Support multiple clone urls patches. Signed-off-by: Jakub Narebski Signed-off-by: Aneesh Kumar K.V Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 37a6284fc4..7c92ac30ce 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -533,6 +533,16 @@ sub git_get_project_description { return $descr; } +sub git_get_project_url_list { + my $path = shift; + + open my $fd, "$projectroot/$path/cloneurl" or return undef; + my @git_project_url_list = map { chomp; $_ } <$fd>; + close $fd; + + return wantarray ? @git_project_url_list : \@git_project_url_list; +} + sub git_get_projects_list { my @list; @@ -1697,10 +1707,14 @@ sub git_summary { "\n" . "\n" . "\n"; + # use per project git URL list in $projectroot/$project/cloneurl + # or make project git URL from git base URL and project name my $url_tag = "URL"; - foreach my $git_base_url (@git_base_url_list) { - next unless $git_base_url; - print "\n"; + my @url_list = git_get_project_url_list($project); + @url_list = map { "$_/$project" } @git_base_url_list unless @url_list; + foreach my $git_url (@url_list) { + next unless $git_url; + print "\n"; $url_tag = ""; } print "
object" . $cgi->a({-class => "list", -href => "$my_uri?" . esc_param("p=$project;a=$tag{'type'};h=$tag{'object'}")}, $tag{'object'}) . "" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$tag{'type'};h=$tag{'object'}")}, $tag{'type'}) . "" . $cgi->a({-class => "list", -href => href(action=>$tag{'type'}, hash=>$tag{'object'})}, $tag{'object'}) . "" . $cgi->a({-href => href(action=>$tag{'type'}, hash=>$tag{'object'})}, $tag{'type'}) . "
" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$full_rev;f=$file_name")}, esc_html($rev)) . "" . esc_html($lineno) . "" . esc_html($data) . "
$short_rev..$long_rev)}" class="text">$short_rev.. $age_str $author $lineno
tree" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$co{'tree'};hb=$hash"), class => "list"}, $co{'tree'}) . + $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, hash_base=>$hash), class => "list"}, $co{'tree'}) . "" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$co{'tree'};hb=$hash")}, "tree") . + "" . $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, hash_base=>$hash)}, "tree") . "
parent" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$par"), class => "list"}, $par) . "" . $cgi->a({-href => href(action=>"commit", hash=>$par), class => "list"}, $par) . "" . - $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$par")}, "commit") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$hash;hp=$par")}, "commitdiff") . + $cgi->a({-href => href(action=>"commit", hash=>$par)}, "commit") . + " | " . $cgi->a({-href => href(action=>"commitdiff", hash=>$hash, hash_parent=>$par)}, "commitdiff") . "
description" . esc_html($descr) . "
owner$owner
last change$cd{'rfc2822'}
$url_tag$git_base_url/$project
$url_tag$git_url
\n"; From 6493cc09c2aa626ffbe6024dd705e1495c2d87e4 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 16 Aug 2006 13:58:32 -0700 Subject: [PATCH 144/160] builtin-grep: remove unused debugging cruft. Signed-off-by: Junio C Hamano --- builtin-grep.c | 57 -------------------------------------------------- 1 file changed, 57 deletions(-) diff --git a/builtin-grep.c b/builtin-grep.c index 3ec99b7010..0bd517b264 100644 --- a/builtin-grep.c +++ b/builtin-grep.c @@ -175,61 +175,12 @@ static void compile_regexp(struct grep_pat *p, struct grep_opt *opt) } } -#if DEBUG -static inline void indent(int in) -{ - int i; - for (i = 0; i < in; i++) putchar(' '); -} - -static void dump_pattern_exp(struct grep_expr *x, int in) -{ - switch (x->node) { - case GREP_NODE_ATOM: - indent(in); - puts(x->u.atom->pattern); - break; - case GREP_NODE_NOT: - indent(in); - puts("--not"); - dump_pattern_exp(x->u.unary, in+1); - break; - case GREP_NODE_AND: - dump_pattern_exp(x->u.binary.left, in+1); - indent(in); - puts("--and"); - dump_pattern_exp(x->u.binary.right, in+1); - break; - case GREP_NODE_OR: - dump_pattern_exp(x->u.binary.left, in+1); - indent(in); - puts("--or"); - dump_pattern_exp(x->u.binary.right, in+1); - break; - } -} - -static void looking_at(const char *msg, struct grep_pat **list) -{ - struct grep_pat *p = *list; - fprintf(stderr, "%s: looking at ", msg); - if (!p) - fprintf(stderr, "empty\n"); - else - fprintf(stderr, "<%s>\n", p->pattern); -} -#else -#define looking_at(a,b) do {} while(0) -#endif - static struct grep_expr *compile_pattern_expr(struct grep_pat **); static struct grep_expr *compile_pattern_atom(struct grep_pat **list) { struct grep_pat *p; struct grep_expr *x; - looking_at("atom", list); - p = *list; switch (p->token) { case GREP_PATTERN: /* atom */ @@ -257,8 +208,6 @@ static struct grep_expr *compile_pattern_not(struct grep_pat **list) struct grep_pat *p; struct grep_expr *x; - looking_at("not", list); - p = *list; switch (p->token) { case GREP_NOT: @@ -281,8 +230,6 @@ static struct grep_expr *compile_pattern_and(struct grep_pat **list) struct grep_pat *p; struct grep_expr *x, *y, *z; - looking_at("and", list); - x = compile_pattern_not(list); p = *list; if (p && p->token == GREP_AND) { @@ -306,8 +253,6 @@ static struct grep_expr *compile_pattern_or(struct grep_pat **list) struct grep_pat *p; struct grep_expr *x, *y, *z; - looking_at("or", list); - x = compile_pattern_and(list); p = *list; if (x && p && p->token != GREP_CLOSE_PAREN) { @@ -325,8 +270,6 @@ static struct grep_expr *compile_pattern_or(struct grep_pat **list) static struct grep_expr *compile_pattern_expr(struct grep_pat **list) { - looking_at("expr", list); - return compile_pattern_or(list); } From 076a10c7282a08f783a28c1b64d0e114a3fe3d39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= Date: Wed, 16 Aug 2006 23:12:26 +0300 Subject: [PATCH 145/160] Be nicer if git executable is not installed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch avoids problems if vc-git.el is installed and activated, but the git executable is not available, for example http://list-archive.xemacs.org/xemacs-beta/200608/msg00062.html Signed-off-by: Ville Skyttä Signed-off-by: Junio C Hamano --- contrib/emacs/vc-git.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/emacs/vc-git.el b/contrib/emacs/vc-git.el index 3f6ed699f0..4a8f79092d 100644 --- a/contrib/emacs/vc-git.el +++ b/contrib/emacs/vc-git.el @@ -54,7 +54,7 @@ (let* ((dir (file-name-directory file)) (name (file-relative-name file dir))) (when dir (cd dir)) - (and (eq 0 (call-process "git" nil '(t nil) nil "ls-files" "-c" "-z" "--" name)) + (and (ignore-errors (eq 0 (call-process "git" nil '(t nil) nil "ls-files" "-c" "-z" "--" name))) (let ((str (buffer-string))) (and (> (length str) (length name)) (string= (substring str 0 (1+ (length name))) (concat name "\0")))))))) From d4baf9eaf47ea1ba204f1ab5ecd22326913dd081 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Thu, 17 Aug 2006 11:21:28 +0200 Subject: [PATCH 146/160] gitweb: Uniquify version info output, add meta generator in page header Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 7c92ac30ce..04282fa5e3 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -996,10 +996,11 @@ sub git_header_html { - + + $title From a89fccd28197fa179828c8596791ff16e2268d20 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Thu, 17 Aug 2006 11:54:57 -0700 Subject: [PATCH 147/160] Do not use memcmp(sha1_1, sha1_2, 20) with hardcoded length. Introduces global inline: hashcmp(const unsigned char *sha1, const unsigned char *sha2) Uses memcmp for comparison and returns the result based on the length of the hash name (a future runtime decision). Acked-by: Alex Riesen Signed-off-by: David Rientjes Signed-off-by: Junio C Hamano --- builtin-commit-tree.c | 2 +- builtin-diff-stages.c | 2 +- builtin-diff.c | 2 +- builtin-pack-objects.c | 8 ++++---- builtin-show-branch.c | 4 ++-- builtin-unpack-objects.c | 4 ++-- builtin-update-index.c | 4 ++-- cache.h | 4 ++++ combine-diff.c | 4 ++-- commit.c | 2 +- convert-objects.c | 2 +- diff-lib.c | 2 +- diff.c | 10 +++++----- diffcore-break.c | 2 +- diffcore-rename.c | 2 +- dump-cache-tree.c | 2 +- http-fetch.c | 6 +++--- http-push.c | 4 ++-- index-pack.c | 12 ++++++------ merge-tree.c | 2 +- object.c | 2 +- pack-check.c | 6 +++--- pack-redundant.c | 14 +++++++------- read-cache.c | 4 ++-- refs.c | 8 ++++---- send-pack.c | 2 +- sha1_file.c | 16 ++++++++-------- sha1_name.c | 6 +++--- ssh-fetch.c | 2 +- tree-diff.c | 3 +-- unpack-trees.c | 2 +- 31 files changed, 74 insertions(+), 71 deletions(-) diff --git a/builtin-commit-tree.c b/builtin-commit-tree.c index 9c98796671..e2e690a1ae 100644 --- a/builtin-commit-tree.c +++ b/builtin-commit-tree.c @@ -69,7 +69,7 @@ static int new_parent(int idx) int i; unsigned char *sha1 = parent_sha1[idx]; for (i = 0; i < idx; i++) { - if (!memcmp(parent_sha1[i], sha1, 20)) { + if (!hashcmp(parent_sha1[i], sha1)) { error("duplicate parent %s ignored", sha1_to_hex(sha1)); return 0; } diff --git a/builtin-diff-stages.c b/builtin-diff-stages.c index 5960e08997..70bb89808d 100644 --- a/builtin-diff-stages.c +++ b/builtin-diff-stages.c @@ -46,7 +46,7 @@ static void diff_stages(int stage1, int stage2, const char **pathspec) else if (!two) diff_addremove(&diff_options, '-', ntohl(one->ce_mode), one->sha1, name, NULL); - else if (memcmp(one->sha1, two->sha1, 20) || + else if (hashcmp(one->sha1, two->sha1) || (one->ce_mode != two->ce_mode) || diff_options.find_copies_harder) diff_change(&diff_options, diff --git a/builtin-diff.c b/builtin-diff.c index 40e5c96f30..874f773421 100644 --- a/builtin-diff.c +++ b/builtin-diff.c @@ -69,7 +69,7 @@ static void stuff_change(struct diff_options *opt, struct diff_filespec *one, *two; if (!is_null_sha1(old_sha1) && !is_null_sha1(new_sha1) && - !memcmp(old_sha1, new_sha1, 20)) + !hashcmp(old_sha1, new_sha1)) return; if (opt->reverse_diff) { diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c index 448461bc48..f19f0d6046 100644 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@ -441,7 +441,7 @@ static int locate_object_entry_hash(const unsigned char *sha1) memcpy(&ui, sha1, sizeof(unsigned int)); i = ui % object_ix_hashsz; while (0 < object_ix[i]) { - if (!memcmp(sha1, objects[object_ix[i]-1].sha1, 20)) + if (!hashcmp(sha1, objects[object_ix[i] - 1].sha1)) return i; if (++i == object_ix_hashsz) i = 0; @@ -607,7 +607,7 @@ static struct pbase_tree_cache *pbase_tree_get(const unsigned char *sha1) */ for (neigh = 0; neigh < 8; neigh++) { ent = pbase_tree_cache[my_ix]; - if (ent && !memcmp(ent->sha1, sha1, 20)) { + if (ent && !hashcmp(ent->sha1, sha1)) { ent->ref++; return ent; } @@ -789,7 +789,7 @@ static void add_preferred_base(unsigned char *sha1) return; for (it = pbase_tree; it; it = it->next) { - if (!memcmp(it->pcache.sha1, tree_sha1, 20)) { + if (!hashcmp(it->pcache.sha1, tree_sha1)) { free(data); return; } @@ -931,7 +931,7 @@ static struct object_entry **create_sorted_list(entry_sort_t sort) static int sha1_sort(const struct object_entry *a, const struct object_entry *b) { - return memcmp(a->sha1, b->sha1, 20); + return hashcmp(a->sha1, b->sha1); } static struct object_entry **create_final_object_list(void) diff --git a/builtin-show-branch.c b/builtin-show-branch.c index 95fbf77fad..18786f88e3 100644 --- a/builtin-show-branch.c +++ b/builtin-show-branch.c @@ -378,7 +378,7 @@ static int append_head_ref(const char *refname, const unsigned char *sha1) /* If both heads/foo and tags/foo exists, get_sha1 would * get confused. */ - if (get_sha1(refname + ofs, tmp) || memcmp(tmp, sha1, 20)) + if (get_sha1(refname + ofs, tmp) || hashcmp(tmp, sha1)) ofs = 5; return append_ref(refname + ofs, sha1); } @@ -442,7 +442,7 @@ static int rev_is_head(char *head_path, int headlen, char *name, { int namelen; if ((!head_path[0]) || - (head_sha1 && sha1 && memcmp(head_sha1, sha1, 20))) + (head_sha1 && sha1 && hashcmp(head_sha1, sha1))) return 0; namelen = strlen(name); if ((headlen < namelen) || diff --git a/builtin-unpack-objects.c b/builtin-unpack-objects.c index 63f4b8e45d..f0ae5c987a 100644 --- a/builtin-unpack-objects.c +++ b/builtin-unpack-objects.c @@ -136,7 +136,7 @@ static void added_object(unsigned char *sha1, const char *type, void *data, unsi struct delta_info *info; while ((info = *p) != NULL) { - if (!memcmp(info->base_sha1, sha1, 20)) { + if (!hashcmp(info->base_sha1, sha1)) { *p = info->next; p = &delta_list; resolve_delta(type, data, size, info->delta, info->size); @@ -292,7 +292,7 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix) unpack_all(); SHA1_Update(&ctx, buffer, offset); SHA1_Final(sha1, &ctx); - if (memcmp(fill(20), sha1, 20)) + if (hashcmp(fill(20), sha1)) die("final sha1 did not match"); use(20); diff --git a/builtin-update-index.c b/builtin-update-index.c index 9f0cf28ba2..5dd91af180 100644 --- a/builtin-update-index.c +++ b/builtin-update-index.c @@ -378,7 +378,7 @@ static int unresolve_one(const char *path) ret = -1; goto free_return; } - if (!memcmp(ce_2->sha1, ce_3->sha1, 20) && + if (!hashcmp(ce_2->sha1, ce_3->sha1) && ce_2->ce_mode == ce_3->ce_mode) { fprintf(stderr, "%s: identical in both, skipping.\n", path); @@ -460,7 +460,7 @@ static int do_reupdate(int ac, const char **av, old = read_one_ent(NULL, head_sha1, ce->name, ce_namelen(ce), 0); if (old && ce->ce_mode == old->ce_mode && - !memcmp(ce->sha1, old->sha1, 20)) { + !hashcmp(ce->sha1, old->sha1)) { free(old); continue; /* unchanged */ } diff --git a/cache.h b/cache.h index c7382996f6..f99254bf99 100644 --- a/cache.h +++ b/cache.h @@ -214,6 +214,10 @@ static inline int is_null_sha1(const unsigned char *sha1) { return !memcmp(sha1, null_sha1, 20); } +static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2) +{ + return memcmp(sha1, sha2, 20); +} int git_mkstemp(char *path, size_t n, const char *template); diff --git a/combine-diff.c b/combine-diff.c index ce063b4ffa..0682acd50d 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -688,8 +688,8 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, for (i = 0; i < num_parent; i++) { int j; for (j = 0; j < i; j++) { - if (!memcmp(elem->parent[i].sha1, - elem->parent[j].sha1, 20)) { + if (!hashcmp(elem->parent[i].sha1, + elem->parent[j].sha1)) { reuse_combine_diff(sline, cnt, i, j); break; } diff --git a/commit.c b/commit.c index 972d1b70c0..d17451fbff 100644 --- a/commit.c +++ b/commit.c @@ -123,7 +123,7 @@ static int commit_graft_pos(const unsigned char *sha1) while (lo < hi) { int mi = (lo + hi) / 2; struct commit_graft *graft = commit_graft[mi]; - int cmp = memcmp(sha1, graft->sha1, 20); + int cmp = hashcmp(sha1, graft->sha1); if (!cmp) return mi; if (cmp < 0) diff --git a/convert-objects.c b/convert-objects.c index 168771ed85..4e7ff7517f 100644 --- a/convert-objects.c +++ b/convert-objects.c @@ -39,7 +39,7 @@ static struct entry *lookup_entry(unsigned char *sha1) while (low < high) { int next = (low + high) / 2; struct entry *n = convert[next]; - int cmp = memcmp(sha1, n->old_sha1, 20); + int cmp = hashcmp(sha1, n->old_sha1); if (!cmp) return n; if (cmp < 0) { diff --git a/diff-lib.c b/diff-lib.c index 116b5a9d68..3e4b3b96b7 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -215,7 +215,7 @@ static int show_modified(struct rev_info *revs, } oldmode = old->ce_mode; - if (mode == oldmode && !memcmp(sha1, old->sha1, 20) && + if (mode == oldmode && !hashcmp(sha1, old->sha1) && !revs->diffopt.find_copies_harder) return 0; diff --git a/diff.c b/diff.c index 7a238d0233..da7cca1952 100644 --- a/diff.c +++ b/diff.c @@ -1140,7 +1140,7 @@ static int work_tree_matches(const char *name, const unsigned char *sha1) if ((lstat(name, &st) < 0) || !S_ISREG(st.st_mode) || /* careful! */ ce_match_stat(ce, &st, 0) || - memcmp(sha1, ce->sha1, 20)) + hashcmp(sha1, ce->sha1)) return 0; /* we return 1 only when we can stat, it is a regular file, * stat information matches, and sha1 recorded in the cache @@ -1168,7 +1168,7 @@ static struct sha1_size_cache *locate_size_cache(unsigned char *sha1, while (last > first) { int cmp, next = (last + first) >> 1; e = sha1_size_cache[next]; - cmp = memcmp(e->sha1, sha1, 20); + cmp = hashcmp(e->sha1, sha1); if (!cmp) return e; if (cmp < 0) { @@ -1579,7 +1579,7 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o) ; } - if (memcmp(one->sha1, two->sha1, 20)) { + if (hashcmp(one->sha1, two->sha1)) { int abbrev = o->full_index ? 40 : DEFAULT_ABBREV; len += snprintf(msg + len, sizeof(msg) - len, @@ -2098,7 +2098,7 @@ int diff_unmodified_pair(struct diff_filepair *p) * dealing with a change. */ if (one->sha1_valid && two->sha1_valid && - !memcmp(one->sha1, two->sha1, sizeof(one->sha1))) + !hashcmp(one->sha1, two->sha1)) return 1; /* no change */ if (!one->sha1_valid && !two->sha1_valid) return 1; /* both look at the same file on the filesystem. */ @@ -2237,7 +2237,7 @@ static void diff_resolve_rename_copy(void) if (!p->status) p->status = DIFF_STATUS_RENAMED; } - else if (memcmp(p->one->sha1, p->two->sha1, 20) || + else if (hashcmp(p->one->sha1, p->two->sha1) || p->one->mode != p->two->mode) p->status = DIFF_STATUS_MODIFIED; else { diff --git a/diffcore-break.c b/diffcore-break.c index ed0e14c6d8..acb18db1db 100644 --- a/diffcore-break.c +++ b/diffcore-break.c @@ -56,7 +56,7 @@ static int should_break(struct diff_filespec *src, return 0; /* leave symlink rename alone */ if (src->sha1_valid && dst->sha1_valid && - !memcmp(src->sha1, dst->sha1, 20)) + !hashcmp(src->sha1, dst->sha1)) return 0; /* they are the same */ if (diff_populate_filespec(src, 0) || diff_populate_filespec(dst, 0)) diff --git a/diffcore-rename.c b/diffcore-rename.c index 0ec488a903..ef239012b6 100644 --- a/diffcore-rename.c +++ b/diffcore-rename.c @@ -101,7 +101,7 @@ static int is_exact_match(struct diff_filespec *src, int contents_too) { if (src->sha1_valid && dst->sha1_valid && - !memcmp(src->sha1, dst->sha1, 20)) + !hashcmp(src->sha1, dst->sha1)) return 1; if (!contents_too) return 0; diff --git a/dump-cache-tree.c b/dump-cache-tree.c index 1ccaf51773..1f73f1ea7d 100644 --- a/dump-cache-tree.c +++ b/dump-cache-tree.c @@ -33,7 +33,7 @@ static int dump_cache_tree(struct cache_tree *it, } else { dump_one(it, pfx, ""); - if (memcmp(it->sha1, ref->sha1, 20) || + if (hashcmp(it->sha1, ref->sha1) || ref->entry_count != it->entry_count || ref->subtree_nr != it->subtree_nr) { dump_one(ref, pfx, "#(ref) "); diff --git a/http-fetch.c b/http-fetch.c index 7f07d2a967..d1f74b443b 100644 --- a/http-fetch.c +++ b/http-fetch.c @@ -301,7 +301,7 @@ static void finish_object_request(struct object_request *obj_req) unlink(obj_req->tmpfile); return; } - if (memcmp(obj_req->sha1, obj_req->real_sha1, 20)) { + if (hashcmp(obj_req->sha1, obj_req->real_sha1)) { unlink(obj_req->tmpfile); return; } @@ -1070,7 +1070,7 @@ static int fetch_object(struct alt_base *repo, unsigned char *sha1) int ret = 0; struct object_request *obj_req = object_queue_head; - while (obj_req != NULL && memcmp(obj_req->sha1, sha1, 20)) + while (obj_req != NULL && hashcmp(obj_req->sha1, sha1)) obj_req = obj_req->next; if (obj_req == NULL) return error("Couldn't find request for %s in the queue", hex); @@ -1109,7 +1109,7 @@ static int fetch_object(struct alt_base *repo, unsigned char *sha1) } else if (obj_req->zret != Z_STREAM_END) { corrupt_object_found++; ret = error("File %s (%s) corrupt", hex, obj_req->url); - } else if (memcmp(obj_req->sha1, obj_req->real_sha1, 20)) { + } else if (hashcmp(obj_req->sha1, obj_req->real_sha1)) { ret = error("File %s has bad hash", hex); } else if (obj_req->rename < 0) { ret = error("unable to write sha1 filename %s", diff --git a/http-push.c b/http-push.c index 2bd9845765..48497797f1 100644 --- a/http-push.c +++ b/http-push.c @@ -745,7 +745,7 @@ static void finish_request(struct transfer_request *request) SHA1_Final(request->real_sha1, &request->c); if (request->zret != Z_STREAM_END) { unlink(request->tmpfile); - } else if (memcmp(request->obj->sha1, request->real_sha1, 20)) { + } else if (hashcmp(request->obj->sha1, request->real_sha1)) { unlink(request->tmpfile); } else { request->rename = @@ -2416,7 +2416,7 @@ int main(int argc, char **argv) if (!ref->peer_ref) continue; - if (!memcmp(ref->old_sha1, ref->peer_ref->new_sha1, 20)) { + if (!hashcmp(ref->old_sha1, ref->peer_ref->new_sha1)) { if (push_verbosely || 1) fprintf(stderr, "'%s': up-to-date\n", ref->name); continue; diff --git a/index-pack.c b/index-pack.c index b20659c259..96ea687463 100644 --- a/index-pack.c +++ b/index-pack.c @@ -82,7 +82,7 @@ static void parse_pack_header(void) SHA1_Init(&ctx); SHA1_Update(&ctx, pack_base, pack_size - 20); SHA1_Final(sha1, &ctx); - if (memcmp(sha1, pack_base + pack_size - 20, 20)) + if (hashcmp(sha1, pack_base + pack_size - 20)) die("packfile '%s' SHA1 mismatch", pack_name); } @@ -189,7 +189,7 @@ static int find_delta(const unsigned char *base_sha1) struct delta_entry *delta = &deltas[next]; int cmp; - cmp = memcmp(base_sha1, delta->base_sha1, 20); + cmp = hashcmp(base_sha1, delta->base_sha1); if (!cmp) return next; if (cmp < 0) { @@ -210,9 +210,9 @@ static int find_deltas_based_on_sha1(const unsigned char *base_sha1, if (first < 0) return -1; - while (first > 0 && !memcmp(deltas[first-1].base_sha1, base_sha1, 20)) + while (first > 0 && !hashcmp(deltas[first - 1].base_sha1, base_sha1)) --first; - while (last < end && !memcmp(deltas[last+1].base_sha1, base_sha1, 20)) + while (last < end && !hashcmp(deltas[last + 1].base_sha1, base_sha1)) ++last; *first_index = first; *last_index = last; @@ -278,7 +278,7 @@ static int compare_delta_entry(const void *a, const void *b) { const struct delta_entry *delta_a = a; const struct delta_entry *delta_b = b; - return memcmp(delta_a->base_sha1, delta_b->base_sha1, 20); + return hashcmp(delta_a->base_sha1, delta_b->base_sha1); } static void parse_pack_objects(void) @@ -350,7 +350,7 @@ static int sha1_compare(const void *_a, const void *_b) { struct object_entry *a = *(struct object_entry **)_a; struct object_entry *b = *(struct object_entry **)_b; - return memcmp(a->sha1, b->sha1, 20); + return hashcmp(a->sha1, b->sha1); } static void write_index_file(const char *index_name, unsigned char *sha1) diff --git a/merge-tree.c b/merge-tree.c index 7cf00be6d5..c2e9a867ed 100644 --- a/merge-tree.c +++ b/merge-tree.c @@ -152,7 +152,7 @@ static int same_entry(struct name_entry *a, struct name_entry *b) { return a->sha1 && b->sha1 && - !memcmp(a->sha1, b->sha1, 20) && + !hashcmp(a->sha1, b->sha1) && a->mode == b->mode; } diff --git a/object.c b/object.c index b5d8ed467d..fdcfff7c86 100644 --- a/object.c +++ b/object.c @@ -58,7 +58,7 @@ struct object *lookup_object(const unsigned char *sha1) i = hashtable_index(sha1); while ((obj = obj_hash[i]) != NULL) { - if (!memcmp(sha1, obj->sha1, 20)) + if (!hashcmp(sha1, obj->sha1)) break; i++; if (i == obj_hash_size) diff --git a/pack-check.c b/pack-check.c index 3a62e1b7e4..04c6c00821 100644 --- a/pack-check.c +++ b/pack-check.c @@ -29,10 +29,10 @@ static int verify_packfile(struct packed_git *p) pack_base = p->pack_base; SHA1_Update(&ctx, pack_base, pack_size - 20); SHA1_Final(sha1, &ctx); - if (memcmp(sha1, (char *) pack_base + pack_size - 20, 20)) + if (hashcmp(sha1, (unsigned char *)pack_base + pack_size - 20)) return error("Packfile %s SHA1 mismatch with itself", p->pack_name); - if (memcmp(sha1, (char *) index_base + index_size - 40, 20)) + if (hashcmp(sha1, (unsigned char *)index_base + index_size - 40)) return error("Packfile %s SHA1 mismatch with idx", p->pack_name); @@ -135,7 +135,7 @@ int verify_pack(struct packed_git *p, int verbose) SHA1_Init(&ctx); SHA1_Update(&ctx, index_base, index_size - 20); SHA1_Final(sha1, &ctx); - if (memcmp(sha1, (char *) index_base + index_size - 20, 20)) + if (hashcmp(sha1, (unsigned char *)index_base + index_size - 20)) ret = error("Packfile index for %s SHA1 mismatch", p->pack_name); diff --git a/pack-redundant.c b/pack-redundant.c index 92a09ed362..edb5524fc4 100644 --- a/pack-redundant.c +++ b/pack-redundant.c @@ -139,7 +139,7 @@ static inline struct llist_item *llist_insert_sorted_unique(struct llist *list, l = (hint == NULL) ? list->front : hint; while (l) { - int cmp = memcmp(l->sha1, sha1, 20); + int cmp = hashcmp(l->sha1, sha1); if (cmp > 0) { /* we insert before this entry */ return llist_insert(list, prev, sha1); } @@ -162,7 +162,7 @@ redo_from_start: l = (hint == NULL) ? list->front : hint; prev = NULL; while (l) { - int cmp = memcmp(l->sha1, sha1, 20); + int cmp = hashcmp(l->sha1, sha1); if (cmp > 0) /* not in list, since sorted */ return prev; if(!cmp) { /* found */ @@ -256,7 +256,7 @@ static void cmp_two_packs(struct pack_list *p1, struct pack_list *p2) while (p1_off <= p1->pack->index_size - 3 * 20 && p2_off <= p2->pack->index_size - 3 * 20) { - int cmp = memcmp(p1_base + p1_off, p2_base + p2_off, 20); + int cmp = hashcmp(p1_base + p1_off, p2_base + p2_off); /* cmp ~ p1 - p2 */ if (cmp == 0) { p1_hint = llist_sorted_remove(p1->unique_objects, @@ -351,16 +351,16 @@ static size_t sizeof_union(struct packed_git *p1, struct packed_git *p2) { size_t ret = 0; int p1_off, p2_off; - char *p1_base, *p2_base; + unsigned char *p1_base, *p2_base; p1_off = p2_off = 256 * 4 + 4; - p1_base = (char *)p1->index_base; - p2_base = (char *)p2->index_base; + p1_base = (unsigned char *)p1->index_base; + p2_base = (unsigned char *)p2->index_base; while (p1_off <= p1->index_size - 3 * 20 && p2_off <= p2->index_size - 3 * 20) { - int cmp = memcmp(p1_base + p1_off, p2_base + p2_off, 20); + int cmp = hashcmp(p1_base + p1_off, p2_base + p2_off); /* cmp ~ p1 - p2 */ if (cmp == 0) { ret++; diff --git a/read-cache.c b/read-cache.c index 6bec833eec..b6982eac41 100644 --- a/read-cache.c +++ b/read-cache.c @@ -60,7 +60,7 @@ static int ce_compare_data(struct cache_entry *ce, struct stat *st) if (fd >= 0) { unsigned char sha1[20]; if (!index_fd(sha1, fd, st, 0, NULL)) - match = memcmp(sha1, ce->sha1, 20); + match = hashcmp(sha1, ce->sha1); /* index_fd() closed the file descriptor already */ } return match; @@ -744,7 +744,7 @@ static int verify_hdr(struct cache_header *hdr, unsigned long size) SHA1_Init(&c); SHA1_Update(&c, hdr, size - 20); SHA1_Final(sha1, &c); - if (memcmp(sha1, (char *) hdr + size - 20, 20)) + if (hashcmp(sha1, (unsigned char *)hdr + size - 20)) return error("bad index file sha1 signature"); return 0; } diff --git a/refs.c b/refs.c index 86ef916614..17cd0cef3c 100644 --- a/refs.c +++ b/refs.c @@ -281,7 +281,7 @@ static struct ref_lock *verify_lock(struct ref_lock *lock, unlock_ref(lock); return NULL; } - if (memcmp(lock->old_sha1, old_sha1, 20)) { + if (hashcmp(lock->old_sha1, old_sha1)) { error("Ref %s is at %s but expected %s", lock->ref_file, sha1_to_hex(lock->old_sha1), sha1_to_hex(old_sha1)); unlock_ref(lock); @@ -411,7 +411,7 @@ int write_ref_sha1(struct ref_lock *lock, if (!lock) return -1; - if (!lock->force_write && !memcmp(lock->old_sha1, sha1, 20)) { + if (!lock->force_write && !hashcmp(lock->old_sha1, sha1)) { unlock_ref(lock); return 0; } @@ -475,7 +475,7 @@ int read_ref_at(const char *ref, unsigned long at_time, unsigned char *sha1) die("Log %s is corrupt.", logfile); if (get_sha1_hex(rec + 41, sha1)) die("Log %s is corrupt.", logfile); - if (memcmp(logged_sha1, sha1, 20)) { + if (hashcmp(logged_sha1, sha1)) { tz = strtoul(tz_c, NULL, 10); fprintf(stderr, "warning: Log %s has gap after %s.\n", @@ -489,7 +489,7 @@ int read_ref_at(const char *ref, unsigned long at_time, unsigned char *sha1) else { if (get_sha1_hex(rec + 41, logged_sha1)) die("Log %s is corrupt.", logfile); - if (memcmp(logged_sha1, sha1, 20)) { + if (hashcmp(logged_sha1, sha1)) { tz = strtoul(tz_c, NULL, 10); fprintf(stderr, "warning: Log %s unexpectedly ended on %s.\n", diff --git a/send-pack.c b/send-pack.c index 43e10b0a62..f7c0cfc6f6 100644 --- a/send-pack.c +++ b/send-pack.c @@ -265,7 +265,7 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec) char old_hex[60], *new_hex; if (!ref->peer_ref) continue; - if (!memcmp(ref->old_sha1, ref->peer_ref->new_sha1, 20)) { + if (!hashcmp(ref->old_sha1, ref->peer_ref->new_sha1)) { if (verbose) fprintf(stderr, "'%s': up-to-date\n", ref->name); continue; diff --git a/sha1_file.c b/sha1_file.c index 18dece46b1..04f7f94d21 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -485,10 +485,10 @@ int use_packed_git(struct packed_git *p) /* Check if the pack file matches with the index file. * this is cheap. */ - if (memcmp((char*)(p->index_base) + p->index_size - 40, - (char *) p->pack_base + p->pack_size - 20, - 20)) { - + if (hashcmp((unsigned char *)(p->index_base) + + p->index_size - 40, + (unsigned char *)p->pack_base + + p->pack_size - 20)) { die("packfile %s does not match index.", p->pack_name); } } @@ -643,7 +643,7 @@ int check_sha1_signature(const unsigned char *sha1, void *map, unsigned long siz SHA1_Update(&c, header, 1+sprintf(header, "%s %lu", type, size)); SHA1_Update(&c, map, size); SHA1_Final(real_sha1, &c); - return memcmp(sha1, real_sha1, 20) ? -1 : 0; + return hashcmp(sha1, real_sha1) ? -1 : 0; } void *map_sha1_file(const unsigned char *sha1, unsigned long *size) @@ -941,7 +941,7 @@ int check_reuse_pack_delta(struct packed_git *p, unsigned long offset, ptr = unpack_object_header(p, ptr, kindp, sizep); if (*kindp != OBJ_DELTA) goto done; - memcpy(base, (char *) p->pack_base + ptr, 20); + memcpy(base, (unsigned char *) p->pack_base + ptr, 20); status = 0; done: unuse_packed_git(p); @@ -1206,7 +1206,7 @@ int find_pack_entry_one(const unsigned char *sha1, do { int mi = (lo + hi) / 2; - int cmp = memcmp((char *) index + (24 * mi) + 4, sha1, 20); + int cmp = hashcmp((unsigned char *)index + (24 * mi) + 4, sha1); if (!cmp) { e->offset = ntohl(*((unsigned int *) ((char *) index + (24 * mi)))); memcpy(e->sha1, sha1, 20); @@ -1715,7 +1715,7 @@ int write_sha1_from_fd(const unsigned char *sha1, int fd, char *buffer, unlink(tmpfile); return error("File %s corrupted", sha1_to_hex(sha1)); } - if (memcmp(sha1, real_sha1, 20)) { + if (hashcmp(sha1, real_sha1)) { unlink(tmpfile); return error("File %s has bad hash", sha1_to_hex(sha1)); } diff --git a/sha1_name.c b/sha1_name.c index f567454d22..e9eb6ce882 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -84,7 +84,7 @@ static int find_short_packed_object(int len, const unsigned char *match, unsigne int cmp; nth_packed_object_sha1(p, mid, now); - cmp = memcmp(match, now, 20); + cmp = hashcmp(match, now); if (!cmp) { first = mid; break; @@ -106,7 +106,7 @@ static int find_short_packed_object(int len, const unsigned char *match, unsigne memcpy(found_sha1, now, 20); found++; } - else if (memcmp(found_sha1, now, 20)) { + else if (hashcmp(found_sha1, now)) { found = 2; break; } @@ -144,7 +144,7 @@ static int find_unique_short_object(int len, char *canonical, return 0; } /* Both have unique ones -- do they match? */ - if (memcmp(packed_sha1, unpacked_sha1, 20)) + if (hashcmp(packed_sha1, unpacked_sha1)) return SHORT_NAME_AMBIGUOUS; memcpy(sha1, packed_sha1, 20); return 0; diff --git a/ssh-fetch.c b/ssh-fetch.c index 0b89df6dda..b006c5c980 100644 --- a/ssh-fetch.c +++ b/ssh-fetch.c @@ -67,7 +67,7 @@ int fetch(unsigned char *sha1) signed char remote; struct object_list *temp; - if (memcmp(sha1, in_transit->item->sha1, 20)) { + if (hashcmp(sha1, in_transit->item->sha1)) { /* we must have already fetched it to clean the queue */ return has_sha1_file(sha1) ? 0 : -1; } diff --git a/tree-diff.c b/tree-diff.c index 916f489c5b..7e2f4f088a 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -39,8 +39,7 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const show_entry(opt, "+", t2, base); return 1; } - if (!opt->find_copies_harder && - !memcmp(sha1, sha2, 20) && mode1 == mode2) + if (!opt->find_copies_harder && !hashcmp(sha1, sha2) && mode1 == mode2) return 0; /* diff --git a/unpack-trees.c b/unpack-trees.c index 43ed12484f..467d9940f5 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -417,7 +417,7 @@ static int same(struct cache_entry *a, struct cache_entry *b) if (!a && !b) return 1; return a->ce_mode == b->ce_mode && - !memcmp(a->sha1, b->sha1, 20); + !hashcmp(a->sha1, b->sha1); } From 55c3eb434ab6d489c632263239be15a1054df7f2 Mon Sep 17 00:00:00 2001 From: Tilman Sauerbeck Date: Thu, 17 Aug 2006 20:44:16 +0200 Subject: [PATCH 148/160] Indentation fix. Signed-off-by: Tilman Sauerbeck Signed-off-by: Junio C Hamano --- commit.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/commit.c b/commit.c index d17451fbff..00bc3de22e 100644 --- a/commit.c +++ b/commit.c @@ -7,15 +7,15 @@ int save_commit_buffer = 1; struct sort_node { /* - * the number of children of the associated commit - * that also occur in the list being sorted. - */ + * the number of children of the associated commit + * that also occur in the list being sorted. + */ unsigned int indegree; /* - * reference to original list item that we will re-use - * on output. - */ + * reference to original list item that we will re-use + * on output. + */ struct commit_list * list_item; }; From 43134fcb350fb70d26634be163db1f71c14db19f Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sat, 19 Aug 2006 16:52:21 +0200 Subject: [PATCH 149/160] builtin-mv: readability patch The old version was not liked at all. This is hopefully better. Oh, and it gets rid of the goto. Note that it does not change any functionality. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- builtin-mv.c | 102 ++++++++++++++++++++++----------------------------- 1 file changed, 43 insertions(+), 59 deletions(-) diff --git a/builtin-mv.c b/builtin-mv.c index c0c8764f7f..1fdb0c77f6 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -126,48 +126,43 @@ int cmd_mv(int argc, const char **argv, const char *prefix) /* Checking */ for (i = 0; i < count; i++) { - int length; + const char *src = source[i], *dst = destination[i]; + int length, src_is_dir; const char *bad = NULL; if (show_only) - printf("Checking rename of '%s' to '%s'\n", - source[i], destination[i]); + printf("Checking rename of '%s' to '%s'\n", src, dst); - if (lstat(source[i], &st) < 0) + length = strlen(src); + if (lstat(src, &st) < 0) bad = "bad source"; - - if (!bad && - (length = strlen(source[i])) >= 0 && - !strncmp(destination[i], source[i], length) && - (destination[i][length] == 0 || destination[i][length] == '/')) + else if (!strncmp(src, dst, length) && + (dst[length] == 0 || dst[length] == '/')) { bad = "can not move directory into itself"; - - if (S_ISDIR(st.st_mode)) { - const char *dir = source[i], *dest_dir = destination[i]; - int first, last, len = strlen(dir); - - if (lstat(dest_dir, &st) == 0) { - bad = "cannot move directory over file"; - goto next; - } + } else if ((src_is_dir = S_ISDIR(st.st_mode)) + && lstat(dst, &st) == 0) + bad = "cannot move directory over file"; + else if (src_is_dir) { + int first, last; modes[i] = WORKING_DIRECTORY; - first = cache_name_pos(source[i], len); + first = cache_name_pos(src, length); if (first >= 0) - die ("Huh? %s/ is in index?", dir); + die ("Huh? %s/ is in index?", src); first = -1 - first; for (last = first; last < active_nr; last++) { const char *path = active_cache[last]->name; - if (strncmp(path, dir, len) || path[len] != '/') + if (strncmp(path, src, length) + || path[length] != '/') break; } if (last - first < 1) bad = "source directory is empty"; - else if (!bad) { - int j, dst_len = strlen(dest_dir); + else { + int j, dst_len; if (last - first > 0) { source = realloc(source, @@ -181,24 +176,21 @@ int cmd_mv(int argc, const char **argv, const char *prefix) * sizeof(enum update_mode)); } - dest_dir = add_slash(dest_dir); + dst = add_slash(dst); + dst_len = strlen(dst) - 1; for (j = 0; j < last - first; j++) { const char *path = active_cache[first + j]->name; source[count + j] = path; destination[count + j] = - prefix_path(dest_dir, dst_len, - path + len); + prefix_path(dst, dst_len, + path + length); modes[count + j] = INDEX; } count += last - first; } - - goto next; - } - - if (!bad && lstat(destination[i], &st) == 0) { + } else if (lstat(dst, &st) == 0) { bad = "destination exists"; if (force) { /* @@ -210,24 +202,17 @@ int cmd_mv(int argc, const char **argv, const char *prefix) " will overwrite!\n", bad); bad = NULL; - path_list_insert(destination[i], - &overwritten); + path_list_insert(dst, &overwritten); } else bad = "Cannot overwrite"; } - } - - if (!bad && cache_name_pos(source[i], strlen(source[i])) < 0) + } else if (cache_name_pos(src, length) < 0) bad = "not under version control"; + else if (path_list_has_path(&src_for_dst, dst)) + bad = "multiple sources for the same target"; + else + path_list_insert(dst, &src_for_dst); - if (!bad) { - if (path_list_has_path(&src_for_dst, destination[i])) - bad = "multiple sources for the same target"; - else - path_list_insert(destination[i], &src_for_dst); - } - -next: if (bad) { if (ignore_errors) { if (--count > 0) { @@ -239,33 +224,32 @@ next: } } else die ("%s, source=%s, destination=%s", - bad, source[i], destination[i]); + bad, src, dst); } } for (i = 0; i < count; i++) { + const char *src = source[i], *dst = destination[i]; + enum update_mode mode = modes[i]; if (show_only || verbose) - printf("Renaming %s to %s\n", - source[i], destination[i]); - if (!show_only && modes[i] != INDEX && - rename(source[i], destination[i]) < 0 && - !ignore_errors) - die ("renaming %s failed: %s", - source[i], strerror(errno)); + printf("Renaming %s to %s\n", src, dst); + if (!show_only && mode != INDEX && + rename(src, dst) < 0 && !ignore_errors) + die ("renaming %s failed: %s", src, strerror(errno)); - if (modes[i] == WORKING_DIRECTORY) + if (mode == WORKING_DIRECTORY) continue; - if (cache_name_pos(source[i], strlen(source[i])) >= 0) { - path_list_insert(source[i], &deleted); + if (cache_name_pos(src, strlen(src)) >= 0) { + path_list_insert(src, &deleted); /* destination can be a directory with 1 file inside */ - if (path_list_has_path(&overwritten, destination[i])) - path_list_insert(destination[i], &changed); + if (path_list_has_path(&overwritten, dst)) + path_list_insert(dst, &changed); else - path_list_insert(destination[i], &added); + path_list_insert(dst, &added); } else - path_list_insert(destination[i], &added); + path_list_insert(dst, &added); } if (show_only) { From c5203bdf66531c848a2b6cd74f3c02cb18286c55 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 18 Aug 2006 12:42:39 +0200 Subject: [PATCH 150/160] git-mv: special case destination "." Since the normalized basename of "." is "", the check for directory failed erroneously. Noticed by Fredrik Kuivinen. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- builtin-mv.c | 5 ++++- t/t7001-mv.sh | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/builtin-mv.c b/builtin-mv.c index c0c8764f7f..b2ecc26f23 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -114,7 +114,10 @@ int cmd_mv(int argc, const char **argv, const char *prefix) modes = xcalloc(count, sizeof(enum update_mode)); dest_path = copy_pathspec(prefix, argv + argc - 1, 1, 0); - if (!lstat(dest_path[0], &st) && + if (dest_path[0][0] == '\0') + /* special case: "." was normalized to "" */ + destination = copy_pathspec(dest_path[0], argv + i, count, 1); + else if (!lstat(dest_path[0], &st) && S_ISDIR(st.st_mode)) { dest_path[0] = add_slash(dest_path[0]); destination = copy_pathspec(dest_path[0], argv + i, count, 1); diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh index e5e0bb9d51..b7fcdb390c 100755 --- a/t/t7001-mv.sh +++ b/t/t7001-mv.sh @@ -82,4 +82,8 @@ test_expect_failure \ 'do not move directory over existing directory' \ 'mkdir path0 && mkdir path0/path2 && git-mv path2 path0' +test_expect_success \ + 'move into "."' \ + 'git-mv path1/path2/ .' + test_done From 6e17886d376ee8480cc9a8b9bc5046f2d721565f Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 21 Aug 2006 22:22:25 +0200 Subject: [PATCH 151/160] git-mv: fix off-by-one error Embarassing. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- builtin-mv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin-mv.c b/builtin-mv.c index b2ecc26f23..e3bc7a86bb 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -26,7 +26,7 @@ static const char **copy_pathspec(const char *prefix, const char **pathspec, if (length > 0 && result[i][length - 1] == '/') { char *without_slash = xmalloc(length); memcpy(without_slash, result[i], length - 1); - without_slash[length] = '\0'; + without_slash[length - 1] = '\0'; result[i] = without_slash; } if (base_name) { From 60a6bf5f53635005f4f68d8b8a33172309193623 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sat, 19 Aug 2006 16:52:21 +0200 Subject: [PATCH 152/160] builtin-mv: readability patch The old version was not liked at all. This is hopefully better. Oh, and it gets rid of the goto. Note that it does not change any functionality. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- builtin-mv.c | 102 ++++++++++++++++++++++----------------------------- 1 file changed, 43 insertions(+), 59 deletions(-) diff --git a/builtin-mv.c b/builtin-mv.c index e3bc7a86bb..ff882bec47 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -129,48 +129,43 @@ int cmd_mv(int argc, const char **argv, const char *prefix) /* Checking */ for (i = 0; i < count; i++) { - int length; + const char *src = source[i], *dst = destination[i]; + int length, src_is_dir; const char *bad = NULL; if (show_only) - printf("Checking rename of '%s' to '%s'\n", - source[i], destination[i]); + printf("Checking rename of '%s' to '%s'\n", src, dst); - if (lstat(source[i], &st) < 0) + length = strlen(src); + if (lstat(src, &st) < 0) bad = "bad source"; - - if (!bad && - (length = strlen(source[i])) >= 0 && - !strncmp(destination[i], source[i], length) && - (destination[i][length] == 0 || destination[i][length] == '/')) + else if (!strncmp(src, dst, length) && + (dst[length] == 0 || dst[length] == '/')) { bad = "can not move directory into itself"; - - if (S_ISDIR(st.st_mode)) { - const char *dir = source[i], *dest_dir = destination[i]; - int first, last, len = strlen(dir); - - if (lstat(dest_dir, &st) == 0) { - bad = "cannot move directory over file"; - goto next; - } + } else if ((src_is_dir = S_ISDIR(st.st_mode)) + && lstat(dst, &st) == 0) + bad = "cannot move directory over file"; + else if (src_is_dir) { + int first, last; modes[i] = WORKING_DIRECTORY; - first = cache_name_pos(source[i], len); + first = cache_name_pos(src, length); if (first >= 0) - die ("Huh? %s/ is in index?", dir); + die ("Huh? %s/ is in index?", src); first = -1 - first; for (last = first; last < active_nr; last++) { const char *path = active_cache[last]->name; - if (strncmp(path, dir, len) || path[len] != '/') + if (strncmp(path, src, length) + || path[length] != '/') break; } if (last - first < 1) bad = "source directory is empty"; - else if (!bad) { - int j, dst_len = strlen(dest_dir); + else { + int j, dst_len; if (last - first > 0) { source = realloc(source, @@ -184,24 +179,21 @@ int cmd_mv(int argc, const char **argv, const char *prefix) * sizeof(enum update_mode)); } - dest_dir = add_slash(dest_dir); + dst = add_slash(dst); + dst_len = strlen(dst) - 1; for (j = 0; j < last - first; j++) { const char *path = active_cache[first + j]->name; source[count + j] = path; destination[count + j] = - prefix_path(dest_dir, dst_len, - path + len); + prefix_path(dst, dst_len, + path + length); modes[count + j] = INDEX; } count += last - first; } - - goto next; - } - - if (!bad && lstat(destination[i], &st) == 0) { + } else if (lstat(dst, &st) == 0) { bad = "destination exists"; if (force) { /* @@ -213,24 +205,17 @@ int cmd_mv(int argc, const char **argv, const char *prefix) " will overwrite!\n", bad); bad = NULL; - path_list_insert(destination[i], - &overwritten); + path_list_insert(dst, &overwritten); } else bad = "Cannot overwrite"; } - } - - if (!bad && cache_name_pos(source[i], strlen(source[i])) < 0) + } else if (cache_name_pos(src, length) < 0) bad = "not under version control"; + else if (path_list_has_path(&src_for_dst, dst)) + bad = "multiple sources for the same target"; + else + path_list_insert(dst, &src_for_dst); - if (!bad) { - if (path_list_has_path(&src_for_dst, destination[i])) - bad = "multiple sources for the same target"; - else - path_list_insert(destination[i], &src_for_dst); - } - -next: if (bad) { if (ignore_errors) { if (--count > 0) { @@ -242,33 +227,32 @@ next: } } else die ("%s, source=%s, destination=%s", - bad, source[i], destination[i]); + bad, src, dst); } } for (i = 0; i < count; i++) { + const char *src = source[i], *dst = destination[i]; + enum update_mode mode = modes[i]; if (show_only || verbose) - printf("Renaming %s to %s\n", - source[i], destination[i]); - if (!show_only && modes[i] != INDEX && - rename(source[i], destination[i]) < 0 && - !ignore_errors) - die ("renaming %s failed: %s", - source[i], strerror(errno)); + printf("Renaming %s to %s\n", src, dst); + if (!show_only && mode != INDEX && + rename(src, dst) < 0 && !ignore_errors) + die ("renaming %s failed: %s", src, strerror(errno)); - if (modes[i] == WORKING_DIRECTORY) + if (mode == WORKING_DIRECTORY) continue; - if (cache_name_pos(source[i], strlen(source[i])) >= 0) { - path_list_insert(source[i], &deleted); + if (cache_name_pos(src, strlen(src)) >= 0) { + path_list_insert(src, &deleted); /* destination can be a directory with 1 file inside */ - if (path_list_has_path(&overwritten, destination[i])) - path_list_insert(destination[i], &changed); + if (path_list_has_path(&overwritten, dst)) + path_list_insert(dst, &changed); else - path_list_insert(destination[i], &added); + path_list_insert(dst, &added); } else - path_list_insert(destination[i], &added); + path_list_insert(dst, &added); } if (show_only) { From 3f0073a2fabce18303aeef154dd6ec5aa8faa5e7 Mon Sep 17 00:00:00 2001 From: Rene Scharfe Date: Mon, 21 Aug 2006 20:11:48 +0200 Subject: [PATCH 153/160] Axe the last ent In the name of Standardization, this cleanses the last usage string of mystical creatures. But they still dwell deep within the source and in some debug messages, it is said. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- builtin-tar-tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin-tar-tree.c b/builtin-tar-tree.c index 215892b696..aeb5a8c2ad 100644 --- a/builtin-tar-tree.c +++ b/builtin-tar-tree.c @@ -14,7 +14,7 @@ #define BLOCKSIZE (RECORDSIZE * 20) static const char tar_tree_usage[] = -"git-tar-tree [--remote=] [basedir]"; +"git-tar-tree [--remote=] [basedir]"; static char block[BLOCKSIZE]; static unsigned long offset; From 7230e6d042ae385377f09c4d226d9b1aa7a2c13b Mon Sep 17 00:00:00 2001 From: Rene Scharfe Date: Mon, 21 Aug 2006 20:43:43 +0200 Subject: [PATCH 154/160] Add write_or_die(), a helper function The little helper write_or_die() won't come back with bad news about full disks or broken pipes. It either succeeds or terminates the program, making additional error handling unnecessary. This patch adds the new function and uses it to replace two similar ones (the one in tar-tree originally has been copied from cat-file btw.). I chose to add the fd parameter which both lacked to make write_or_die() just as flexible as write() and thus suitable for lib-ification. There is a regression: error messages emitted by this function don't show the program name, while the replaced two functions did. That's acceptable, I think; a lot of other functions do the same. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- Makefile | 1 + builtin-cat-file.c | 29 ++++++----------------------- builtin-tar-tree.c | 27 ++++----------------------- cache.h | 1 + write_or_die.c | 20 ++++++++++++++++++++ 5 files changed, 32 insertions(+), 46 deletions(-) create mode 100644 write_or_die.c diff --git a/Makefile b/Makefile index 23cd8a017b..b15b420ea2 100644 --- a/Makefile +++ b/Makefile @@ -248,6 +248,7 @@ LIB_OBJS = \ server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \ tag.o tree.o usage.o config.o environment.o ctype.o copy.o \ fetch-clone.o revision.o pager.o tree-walk.o xdiff-interface.o \ + write_or_die.o \ alloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS) BUILTIN_OBJS = \ diff --git a/builtin-cat-file.c b/builtin-cat-file.c index df009ade7a..7a6fa56e93 100644 --- a/builtin-cat-file.c +++ b/builtin-cat-file.c @@ -9,23 +9,6 @@ #include "tree.h" #include "builtin.h" -static void flush_buffer(const char *buf, unsigned long size) -{ - while (size > 0) { - long ret = xwrite(1, buf, size); - if (ret < 0) { - /* Ignore epipe */ - if (errno == EPIPE) - break; - die("git-cat-file: %s", strerror(errno)); - } else if (!ret) { - die("git-cat-file: disk full?"); - } - size -= ret; - buf += ret; - } -} - static void pprint_tag(const unsigned char *sha1, const char *buf, unsigned long size) { /* the parser in tag.c is useless here. */ @@ -42,7 +25,7 @@ static void pprint_tag(const unsigned char *sha1, const char *buf, unsigned long /* Found the tagger line. Copy out the contents * of the buffer so far. */ - flush_buffer(buf, cp - buf); + write_or_die(1, buf, cp - buf); /* * Do something intelligent, like pretty-printing @@ -61,18 +44,18 @@ static void pprint_tag(const unsigned char *sha1, const char *buf, unsigned long sp++; if (sp == cp) { /* give up */ - flush_buffer(tagger, + write_or_die(1, tagger, cp - tagger); break; } while (sp < cp && !('0' <= *sp && *sp <= '9')) sp++; - flush_buffer(tagger, sp - tagger); + write_or_die(1, tagger, sp - tagger); date = strtoul(sp, &ep, 10); tz = strtol(ep, NULL, 10); sp = show_date(date, tz); - flush_buffer(sp, strlen(sp)); + write_or_die(1, sp, strlen(sp)); xwrite(1, "\n", 1); break; } @@ -90,7 +73,7 @@ static void pprint_tag(const unsigned char *sha1, const char *buf, unsigned long * remainder as is. */ if (cp < endp) - flush_buffer(cp, endp - cp); + write_or_die(1, cp, endp - cp); } int cmd_cat_file(int argc, const char **argv, const char *prefix) @@ -162,6 +145,6 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix) if (!buf) die("git-cat-file %s: bad file", argv[2]); - flush_buffer(buf, size); + write_or_die(1, buf, size); return 0; } diff --git a/builtin-tar-tree.c b/builtin-tar-tree.c index aeb5a8c2ad..e0bcb0a1e1 100644 --- a/builtin-tar-tree.c +++ b/builtin-tar-tree.c @@ -22,30 +22,11 @@ static unsigned long offset; static time_t archive_time; static int tar_umask; -/* tries hard to write, either succeeds or dies in the attempt */ -static void reliable_write(const void *data, unsigned long size) -{ - const char *buf = data; - - while (size > 0) { - long ret = xwrite(1, buf, size); - if (ret < 0) { - if (errno == EPIPE) - exit(0); - die("git-tar-tree: %s", strerror(errno)); - } else if (!ret) { - die("git-tar-tree: disk full?"); - } - size -= ret; - buf += ret; - } -} - /* writes out the whole block, but only if it is full */ static void write_if_needed(void) { if (offset == BLOCKSIZE) { - reliable_write(block, BLOCKSIZE); + write_or_die(1, block, BLOCKSIZE); offset = 0; } } @@ -70,7 +51,7 @@ static void write_blocked(const void *data, unsigned long size) write_if_needed(); } while (size >= BLOCKSIZE) { - reliable_write(buf, BLOCKSIZE); + write_or_die(1, buf, BLOCKSIZE); size -= BLOCKSIZE; buf += BLOCKSIZE; } @@ -94,10 +75,10 @@ static void write_trailer(void) { int tail = BLOCKSIZE - offset; memset(block + offset, 0, tail); - reliable_write(block, BLOCKSIZE); + write_or_die(1, block, BLOCKSIZE); if (tail < 2 * RECORDSIZE) { memset(block, 0, offset); - reliable_write(block, BLOCKSIZE); + write_or_die(1, block, BLOCKSIZE); } } diff --git a/cache.h b/cache.h index f99254bf99..08d6a91279 100644 --- a/cache.h +++ b/cache.h @@ -388,6 +388,7 @@ extern char git_default_name[MAX_GITNAME]; extern char git_commit_encoding[MAX_ENCODING_LENGTH]; extern int copy_fd(int ifd, int ofd); +extern void write_or_die(int fd, const void *buf, size_t count); /* Finish off pack transfer receiving end */ extern int receive_unpack_pack(int fd[2], const char *me, int quiet, int); diff --git a/write_or_die.c b/write_or_die.c new file mode 100644 index 0000000000..ab4cb8a69c --- /dev/null +++ b/write_or_die.c @@ -0,0 +1,20 @@ +#include "cache.h" + +void write_or_die(int fd, const void *buf, size_t count) +{ + const char *p = buf; + ssize_t written; + + while (count > 0) { + written = xwrite(fd, p, count); + if (written == 0) + die("disk full?"); + else if (written < 0) { + if (errno == EPIPE) + exit(0); + die("write error (%s)", strerror(errno)); + } + count -= written; + p += written; + } +} From da7560110f91088ee2a664e98f75ff54e0d9e1e1 Mon Sep 17 00:00:00 2001 From: Shawn Pearce Date: Mon, 21 Aug 2006 03:10:02 -0400 Subject: [PATCH 155/160] Verify we know how to read a pack before trying to using it. If the pack format were to ever change or be extended in the future there is no assurance that just because the pack file lives in objects/pack and doesn't end in .idx that we can read and decompress its contents properly. If we encounter what we think is a pack file and it isn't or we don't recognize its version then die and suggest to the user that they upgrade to a newer version of GIT which can handle that pack file. Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- sha1_file.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sha1_file.c b/sha1_file.c index 04f7f94d21..5f34c69d3a 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -463,6 +463,7 @@ int use_packed_git(struct packed_git *p) int fd; struct stat st; void *map; + struct pack_header *hdr; pack_mapped += p->pack_size; while (PACK_MAX_SZ < pack_mapped && unuse_one_packed_git()) @@ -482,6 +483,17 @@ int use_packed_git(struct packed_git *p) die("packfile %s cannot be mapped.", p->pack_name); p->pack_base = map; + /* Check if we understand this pack file. If we don't we're + * likely too old to handle it. + */ + hdr = map; + if (hdr->hdr_signature != htonl(PACK_SIGNATURE)) + die("packfile %s isn't actually a pack.", p->pack_name); + if (!pack_version_ok(hdr->hdr_version)) + die("packfile %s is version %i and not supported" + " (try upgrading GIT to a newer version)", + p->pack_name, ntohl(hdr->hdr_version)); + /* Check if the pack file matches with the index file. * this is cheap. */ From 44c10841ea3edeef47cc6be0fdba5058344e2e95 Mon Sep 17 00:00:00 2001 From: Shawn Pearce Date: Mon, 21 Aug 2006 03:10:36 -0400 Subject: [PATCH 156/160] Remove unnecessary forward declaration of unpack_entry. This declaration probably used to be necessary but the code has been refactored since to use unpack_entry_gently instead. Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- sha1_file.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index 5f34c69d3a..066cff1fa6 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -1057,9 +1057,6 @@ static int packed_object_info(struct pack_entry *entry, return 0; } -/* forward declaration for a mutually recursive function */ -static void *unpack_entry(struct pack_entry *, char *, unsigned long *); - static void *unpack_delta_entry(unsigned char *base_sha1, unsigned long delta_size, unsigned long left, From 68d42c41ef33cde500307660bb64a1c74f62711e Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Wed, 23 Aug 2006 03:02:59 -0700 Subject: [PATCH 157/160] git-send-email: Don't set author_not_sender from Cc: lines When an mbox-style patch contains a Cc: line in the header, git-send-email will check the address against the sender specified on the command line. If they don't match, sender_not_author will be set to the address obtained from the Cc line. When this happens, git-send-email inserts a From: line at the beginning of the message body with the address obtained from the Cc line in the header, and the sender might be accused of forging patch authors. This patch fixes this by only updating sender_not_author when processing From: lines, not when processing Cc: lines. Signed-off-by: Haavard Skinnemoen Signed-off-by: Junio C Hamano --- git-send-email.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-send-email.perl b/git-send-email.perl index a83c7e9094..746c525079 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -510,7 +510,7 @@ foreach my $t (@files) { if ($2 eq $from) { next if ($suppress_from); } - else { + elsif ($1 eq 'From') { $author_not_sender = $2; } printf("(mbox) Adding cc: %s from line '%s'\n", From b05faa2da9ec24d737bbba47c71e815255f3eaa7 Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Wed, 23 Aug 2006 11:17:55 +0200 Subject: [PATCH 158/160] Fix a comparison bug in diff-delta.c (1 << i) < hspace is compared in the `int` space rather that in the unsigned one. the result will be wrong if hspace is between 0x40000000 and 0x80000000. Signed-off-by: Pierre Habouzit Signed-off-by: Junio C Hamano --- diff-delta.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/diff-delta.c b/diff-delta.c index 7da9205a5d..51e2e56177 100644 --- a/diff-delta.c +++ b/diff-delta.c @@ -152,7 +152,7 @@ struct delta_index * create_delta_index(const void *buf, unsigned long bufsize) initialization in create_delta(). */ entries = (bufsize - 1) / RABIN_WINDOW; hsize = entries / 4; - for (i = 4; (1 << i) < hsize && i < 31; i++); + for (i = 4; (1u << i) < hsize && i < 31; i++); hsize = 1 << i; hmask = hsize - 1; From e702496e434a160f798447b95b9cea3cd138c140 Mon Sep 17 00:00:00 2001 From: Shawn Pearce Date: Wed, 23 Aug 2006 02:49:00 -0400 Subject: [PATCH 159/160] Convert memcpy(a,b,20) to hashcpy(a,b). This abstracts away the size of the hash values when copying them from memory location to memory location, much as the introduction of hashcmp abstracted away hash value comparsion. A few call sites were using char* rather than unsigned char* so I added the cast rather than open hashcpy to be void*. This is a reasonable tradeoff as most call sites already use unsigned char* and the existing hashcmp is also declared to be unsigned char*. [jc: Splitted the patch to "master" part, to be followed by a patch for merge-recursive.c which is not in "master" yet. Fixed the cast in the latter hunk to combine-diff.c which was wrong in the original. Also converted ones left-over in combine-diff.c, diff-lib.c and upload-pack.c ] Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- blame.c | 4 ++-- builtin-diff.c | 4 ++-- builtin-pack-objects.c | 6 +++--- builtin-read-tree.c | 2 +- builtin-unpack-objects.c | 4 ++-- builtin-update-index.c | 4 ++-- builtin-write-tree.c | 4 ++-- cache-tree.c | 6 +++--- cache.h | 4 ++++ combine-diff.c | 10 +++++----- connect.c | 6 +++--- convert-objects.c | 6 +++--- csum-file.c | 2 +- diff-lib.c | 3 +-- diff.c | 6 +++--- fetch-pack.c | 2 +- fetch.c | 2 +- fsck-objects.c | 2 +- http-fetch.c | 2 +- http-push.c | 6 +++--- index-pack.c | 4 ++-- mktree.c | 4 ++-- object.c | 2 +- patch-id.c | 2 +- receive-pack.c | 4 ++-- refs.c | 2 +- revision.c | 2 +- send-pack.c | 4 ++-- sha1_file.c | 18 +++++++++--------- sha1_name.c | 22 +++++++++++----------- tree-walk.c | 4 ++-- tree.c | 2 +- unpack-trees.c | 2 +- upload-pack.c | 2 +- 34 files changed, 81 insertions(+), 78 deletions(-) diff --git a/blame.c b/blame.c index c253b9ca45..5a8af72623 100644 --- a/blame.c +++ b/blame.c @@ -176,7 +176,7 @@ static int get_blob_sha1(struct tree *t, const char *pathname, if (i == 20) return -1; - memcpy(sha1, blob_sha1, 20); + hashcpy(sha1, blob_sha1); return 0; } @@ -191,7 +191,7 @@ static int get_blob_sha1_internal(const unsigned char *sha1, const char *base, strcmp(blame_file + baselen, pathname)) return -1; - memcpy(blob_sha1, sha1, 20); + hashcpy(blob_sha1, sha1); return -1; } diff --git a/builtin-diff.c b/builtin-diff.c index 874f773421..a6590205e8 100644 --- a/builtin-diff.c +++ b/builtin-diff.c @@ -192,7 +192,7 @@ static int builtin_diff_combined(struct rev_info *revs, parent = xmalloc(ents * sizeof(*parent)); /* Again, the revs are all reverse */ for (i = 0; i < ents; i++) - memcpy(parent + i, ent[ents - 1 - i].item->sha1, 20); + hashcpy((unsigned char*)parent + i, ent[ents - 1 - i].item->sha1); diff_tree_combined(parent[0], parent + 1, ents - 1, revs->dense_combined_merges, revs); return 0; @@ -290,7 +290,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix) if (obj->type == OBJ_BLOB) { if (2 <= blobs) die("more than two blobs given: '%s'", name); - memcpy(blob[blobs].sha1, obj->sha1, 20); + hashcpy(blob[blobs].sha1, obj->sha1); blob[blobs].name = name; blobs++; continue; diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c index f19f0d6046..46f524dfc3 100644 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@ -534,7 +534,7 @@ static int add_object_entry(const unsigned char *sha1, unsigned hash, int exclud entry = objects + idx; nr_objects = idx + 1; memset(entry, 0, sizeof(*entry)); - memcpy(entry->sha1, sha1, 20); + hashcpy(entry->sha1, sha1); entry->hash = hash; if (object_ix_hashsz * 3 <= nr_objects * 4) @@ -649,7 +649,7 @@ static struct pbase_tree_cache *pbase_tree_get(const unsigned char *sha1) free(ent->tree_data); nent = ent; } - memcpy(nent->sha1, sha1, 20); + hashcpy(nent->sha1, sha1); nent->tree_data = data; nent->tree_size = size; nent->ref = 1; @@ -799,7 +799,7 @@ static void add_preferred_base(unsigned char *sha1) it->next = pbase_tree; pbase_tree = it; - memcpy(it->pcache.sha1, tree_sha1, 20); + hashcpy(it->pcache.sha1, tree_sha1); it->pcache.tree_data = data; it->pcache.tree_size = size; } diff --git a/builtin-read-tree.c b/builtin-read-tree.c index 53087faf7a..c1867d2a00 100644 --- a/builtin-read-tree.c +++ b/builtin-read-tree.c @@ -53,7 +53,7 @@ static void prime_cache_tree_rec(struct cache_tree *it, struct tree *tree) struct name_entry entry; int cnt; - memcpy(it->sha1, tree->object.sha1, 20); + hashcpy(it->sha1, tree->object.sha1); desc.buf = tree->buffer; desc.size = tree->size; cnt = 0; diff --git a/builtin-unpack-objects.c b/builtin-unpack-objects.c index f0ae5c987a..ca0ebc2585 100644 --- a/builtin-unpack-objects.c +++ b/builtin-unpack-objects.c @@ -95,7 +95,7 @@ static void add_delta_to_list(unsigned char *base_sha1, void *delta, unsigned lo { struct delta_info *info = xmalloc(sizeof(*info)); - memcpy(info->base_sha1, base_sha1, 20); + hashcpy(info->base_sha1, base_sha1); info->size = size; info->delta = delta; info->next = delta_list; @@ -173,7 +173,7 @@ static int unpack_delta_entry(unsigned long delta_size) unsigned char base_sha1[20]; int result; - memcpy(base_sha1, fill(20), 20); + hashcpy(base_sha1, fill(20)); use(20); delta_data = get_data(delta_size); diff --git a/builtin-update-index.c b/builtin-update-index.c index 5dd91af180..8675126471 100644 --- a/builtin-update-index.c +++ b/builtin-update-index.c @@ -142,7 +142,7 @@ static int add_cacheinfo(unsigned int mode, const unsigned char *sha1, size = cache_entry_size(len); ce = xcalloc(1, size); - memcpy(ce->sha1, sha1, 20); + hashcpy(ce->sha1, sha1); memcpy(ce->name, path, len); ce->ce_flags = create_ce_flags(len, stage); ce->ce_mode = create_ce_mode(mode); @@ -333,7 +333,7 @@ static struct cache_entry *read_one_ent(const char *which, size = cache_entry_size(namelen); ce = xcalloc(1, size); - memcpy(ce->sha1, sha1, 20); + hashcpy(ce->sha1, sha1); memcpy(ce->name, path, namelen); ce->ce_flags = create_ce_flags(namelen, stage); ce->ce_mode = create_ce_mode(mode); diff --git a/builtin-write-tree.c b/builtin-write-tree.c index ca06149f18..50670dc7bf 100644 --- a/builtin-write-tree.c +++ b/builtin-write-tree.c @@ -50,10 +50,10 @@ int write_tree(unsigned char *sha1, int missing_ok, const char *prefix) if (prefix) { struct cache_tree *subtree = cache_tree_find(active_cache_tree, prefix); - memcpy(sha1, subtree->sha1, 20); + hashcpy(sha1, subtree->sha1); } else - memcpy(sha1, active_cache_tree->sha1, 20); + hashcpy(sha1, active_cache_tree->sha1); rollback_lock_file(lock_file); diff --git a/cache-tree.c b/cache-tree.c index d9f7e1e3dd..323c68a670 100644 --- a/cache-tree.c +++ b/cache-tree.c @@ -335,7 +335,7 @@ static int update_one(struct cache_tree *it, offset += sprintf(buffer + offset, "%o %.*s", mode, entlen, path + baselen); buffer[offset++] = 0; - memcpy(buffer + offset, sha1, 20); + hashcpy((unsigned char*)buffer + offset, sha1); offset += 20; #if DEBUG @@ -412,7 +412,7 @@ static void *write_one(struct cache_tree *it, #endif if (0 <= it->entry_count) { - memcpy(buffer + *offset, it->sha1, 20); + hashcpy((unsigned char*)buffer + *offset, it->sha1); *offset += 20; } for (i = 0; i < it->subtree_nr; i++) { @@ -478,7 +478,7 @@ static struct cache_tree *read_one(const char **buffer, unsigned long *size_p) if (0 <= it->entry_count) { if (size < 20) goto free_return; - memcpy(it->sha1, buf, 20); + hashcpy(it->sha1, (unsigned char*)buf); buf += 20; size -= 20; } diff --git a/cache.h b/cache.h index 08d6a91279..cc3f00c2b8 100644 --- a/cache.h +++ b/cache.h @@ -218,6 +218,10 @@ static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2) { return memcmp(sha1, sha2, 20); } +static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src) +{ + memcpy(sha_dst, sha_src, 20); +} int git_mkstemp(char *path, size_t n, const char *template); diff --git a/combine-diff.c b/combine-diff.c index 0682acd50d..46d9121baf 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -31,9 +31,9 @@ static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr, memset(p->parent, 0, sizeof(p->parent[0]) * num_parent); - memcpy(p->sha1, q->queue[i]->two->sha1, 20); + hashcpy(p->sha1, q->queue[i]->two->sha1); p->mode = q->queue[i]->two->mode; - memcpy(p->parent[n].sha1, q->queue[i]->one->sha1, 20); + hashcpy(p->parent[n].sha1, q->queue[i]->one->sha1); p->parent[n].mode = q->queue[i]->one->mode; p->parent[n].status = q->queue[i]->status; *tail = p; @@ -56,8 +56,7 @@ static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr, len = strlen(path); if (len == p->len && !memcmp(path, p->path, len)) { found = 1; - memcpy(p->parent[n].sha1, - q->queue[i]->one->sha1, 20); + hashcpy(p->parent[n].sha1, q->queue[i]->one->sha1); p->parent[n].mode = q->queue[i]->one->mode; p->parent[n].status = q->queue[i]->status; break; @@ -927,6 +926,7 @@ void diff_tree_combined_merge(const unsigned char *sha1, for (parents = commit->parents, num_parent = 0; parents; parents = parents->next, num_parent++) - memcpy(parent + num_parent, parents->item->object.sha1, 20); + hashcpy((unsigned char*)(parent + num_parent), + parents->item->object.sha1); diff_tree_combined(sha1, parent, num_parent, dense, rev); } diff --git a/connect.c b/connect.c index 7a6a73f2a3..e501ccce25 100644 --- a/connect.c +++ b/connect.c @@ -77,7 +77,7 @@ struct ref **get_remote_heads(int in, struct ref **list, if (nr_match && !path_match(name, nr_match, match)) continue; ref = xcalloc(1, sizeof(*ref) + len - 40); - memcpy(ref->old_sha1, old_sha1, 20); + hashcpy(ref->old_sha1, old_sha1); memcpy(ref->name, buffer + 41, len - 40); *list = ref; list = &ref->next; @@ -208,7 +208,7 @@ static struct ref *try_explicit_object_name(const char *name) len = strlen(name) + 1; ref = xcalloc(1, sizeof(*ref) + len); memcpy(ref->name, name, len); - memcpy(ref->new_sha1, sha1, 20); + hashcpy(ref->new_sha1, sha1); return ref; } @@ -318,7 +318,7 @@ int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail, int len = strlen(src->name) + 1; dst_peer = xcalloc(1, sizeof(*dst_peer) + len); memcpy(dst_peer->name, src->name, len); - memcpy(dst_peer->new_sha1, src->new_sha1, 20); + hashcpy(dst_peer->new_sha1, src->new_sha1); link_dst_tail(dst_peer, dst_tail); } dst_peer->peer_ref = src; diff --git a/convert-objects.c b/convert-objects.c index 4e7ff7517f..631678b08a 100644 --- a/convert-objects.c +++ b/convert-objects.c @@ -23,7 +23,7 @@ static struct entry * convert_entry(unsigned char *sha1); static struct entry *insert_new(unsigned char *sha1, int pos) { struct entry *new = xcalloc(1, sizeof(struct entry)); - memcpy(new->old_sha1, sha1, 20); + hashcpy(new->old_sha1, sha1); memmove(convert + pos + 1, convert + pos, (nr_convert - pos) * sizeof(struct entry *)); convert[pos] = new; nr_convert++; @@ -54,7 +54,7 @@ static struct entry *lookup_entry(unsigned char *sha1) static void convert_binary_sha1(void *buffer) { struct entry *entry = convert_entry(buffer); - memcpy(buffer, entry->new_sha1, 20); + hashcpy(buffer, entry->new_sha1); } static void convert_ascii_sha1(void *buffer) @@ -104,7 +104,7 @@ static int write_subdirectory(void *buffer, unsigned long size, const char *base if (!slash) { newlen += sprintf(new + newlen, "%o %s", mode, path); new[newlen++] = '\0'; - memcpy(new + newlen, (char *) buffer + len - 20, 20); + hashcpy((unsigned char*)new + newlen, (unsigned char *) buffer + len - 20); newlen += 20; used += len; diff --git a/csum-file.c b/csum-file.c index e2278897d0..b7174c6c05 100644 --- a/csum-file.c +++ b/csum-file.c @@ -38,7 +38,7 @@ int sha1close(struct sha1file *f, unsigned char *result, int update) } SHA1_Final(f->buffer, &f->ctx); if (result) - memcpy(result, f->buffer, 20); + hashcpy(result, f->buffer); if (update) sha1flush(f, 20); if (close(f->fd)) diff --git a/diff-lib.c b/diff-lib.c index 3e4b3b96b7..2fc41263ae 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -66,8 +66,7 @@ int run_diff_files(struct rev_info *revs, int silent_on_removed) if (2 <= stage) { int mode = ntohl(nce->ce_mode); num_compare_stages++; - memcpy(dpath->parent[stage-2].sha1, - nce->sha1, 20); + hashcpy(dpath->parent[stage-2].sha1, nce->sha1); dpath->parent[stage-2].mode = canon_mode(mode); dpath->parent[stage-2].status = diff --git a/diff.c b/diff.c index da7cca1952..ca171e8e69 100644 --- a/diff.c +++ b/diff.c @@ -1101,7 +1101,7 @@ void fill_filespec(struct diff_filespec *spec, const unsigned char *sha1, { if (mode) { spec->mode = canon_mode(mode); - memcpy(spec->sha1, sha1, 20); + hashcpy(spec->sha1, sha1); spec->sha1_valid = !is_null_sha1(sha1); } } @@ -1194,7 +1194,7 @@ static struct sha1_size_cache *locate_size_cache(unsigned char *sha1, sizeof(*sha1_size_cache)); e = xmalloc(sizeof(struct sha1_size_cache)); sha1_size_cache[first] = e; - memcpy(e->sha1, sha1, 20); + hashcpy(e->sha1, sha1); e->size = size; return e; } @@ -1516,7 +1516,7 @@ static void diff_fill_sha1_info(struct diff_filespec *one) } } else - memset(one->sha1, 0, 20); + hashclr(one->sha1); } static void run_diff(struct diff_filepair *p, struct diff_options *o) diff --git a/fetch-pack.c b/fetch-pack.c index e18c1489a1..377feded1c 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -404,7 +404,7 @@ static int everything_local(struct ref **refs, int nr_match, char **match) continue; } - memcpy(ref->new_sha1, local, 20); + hashcpy(ref->new_sha1, local); if (!verbose) continue; fprintf(stderr, diff --git a/fetch.c b/fetch.c index aeb6bf2639..ef60b045ea 100644 --- a/fetch.c +++ b/fetch.c @@ -84,7 +84,7 @@ static int process_commit(struct commit *commit) if (commit->object.flags & COMPLETE) return 0; - memcpy(current_commit_sha1, commit->object.sha1, 20); + hashcpy(current_commit_sha1, commit->object.sha1); pull_say("walk %s\n", sha1_to_hex(commit->object.sha1)); diff --git a/fsck-objects.c b/fsck-objects.c index 31e00d84b3..ae0ec8d039 100644 --- a/fsck-objects.c +++ b/fsck-objects.c @@ -356,7 +356,7 @@ static void add_sha1_list(unsigned char *sha1, unsigned long ino) int nr; entry->ino = ino; - memcpy(entry->sha1, sha1, 20); + hashcpy(entry->sha1, sha1); nr = sha1_list.nr; if (nr == MAX_SHA1_ENTRIES) { fsck_sha1_list(); diff --git a/http-fetch.c b/http-fetch.c index d1f74b443b..7619b338fe 100644 --- a/http-fetch.c +++ b/http-fetch.c @@ -393,7 +393,7 @@ void prefetch(unsigned char *sha1) char *filename = sha1_file_name(sha1); newreq = xmalloc(sizeof(*newreq)); - memcpy(newreq->sha1, sha1, 20); + hashcpy(newreq->sha1, sha1); newreq->repo = alt; newreq->url = NULL; newreq->local = -1; diff --git a/http-push.c b/http-push.c index 48497797f1..ebfcc73a9e 100644 --- a/http-push.c +++ b/http-push.c @@ -1874,7 +1874,7 @@ static int one_local_ref(const char *refname, const unsigned char *sha1) struct ref *ref; int len = strlen(refname) + 1; ref = xcalloc(1, sizeof(*ref) + len); - memcpy(ref->new_sha1, sha1, 20); + hashcpy(ref->new_sha1, sha1); memcpy(ref->name, refname, len); *local_tail = ref; local_tail = &ref->next; @@ -1909,7 +1909,7 @@ static void one_remote_ref(char *refname) } ref = xcalloc(1, sizeof(*ref) + len); - memcpy(ref->old_sha1, remote_sha1, 20); + hashcpy(ref->old_sha1, remote_sha1); memcpy(ref->name, refname, len); *remote_tail = ref; remote_tail = &ref->next; @@ -2445,7 +2445,7 @@ int main(int argc, char **argv) continue; } } - memcpy(ref->new_sha1, ref->peer_ref->new_sha1, 20); + hashcpy(ref->new_sha1, ref->peer_ref->new_sha1); if (is_zero_sha1(ref->new_sha1)) { error("cannot happen anymore"); rc = -3; diff --git a/index-pack.c b/index-pack.c index 96ea687463..80bc6cb45b 100644 --- a/index-pack.c +++ b/index-pack.c @@ -161,7 +161,7 @@ static void *unpack_raw_entry(unsigned long offset, case OBJ_DELTA: if (pos + 20 >= pack_limit) bad_object(offset, "object extends past end of pack"); - memcpy(delta_base, pack_base + pos, 20); + hashcpy(delta_base, pack_base + pos); pos += 20; /* fallthru */ case OBJ_COMMIT: @@ -304,7 +304,7 @@ static void parse_pack_objects(void) if (obj->type == OBJ_DELTA) { struct delta_entry *delta = &deltas[nr_deltas++]; delta->obj = obj; - memcpy(delta->base_sha1, base_sha1, 20); + hashcpy(delta->base_sha1, base_sha1); } else sha1_object(data, data_size, obj->type, obj->sha1); free(data); diff --git a/mktree.c b/mktree.c index 93241385e4..56205d1e00 100644 --- a/mktree.c +++ b/mktree.c @@ -30,7 +30,7 @@ static void append_to_tree(unsigned mode, unsigned char *sha1, char *path) ent = entries[used++] = xmalloc(sizeof(**entries) + len + 1); ent->mode = mode; ent->len = len; - memcpy(ent->sha1, sha1, 20); + hashcpy(ent->sha1, sha1); memcpy(ent->name, path, len+1); } @@ -64,7 +64,7 @@ static void write_tree(unsigned char *sha1) offset += sprintf(buffer + offset, "%o ", ent->mode); offset += sprintf(buffer + offset, "%s", ent->name); buffer[offset++] = 0; - memcpy(buffer + offset, ent->sha1, 20); + hashcpy((unsigned char*)buffer + offset, ent->sha1); offset += 20; } write_sha1_file(buffer, offset, tree_type, sha1); diff --git a/object.c b/object.c index fdcfff7c86..60bf16b902 100644 --- a/object.c +++ b/object.c @@ -91,7 +91,7 @@ void created_object(const unsigned char *sha1, struct object *obj) obj->used = 0; obj->type = OBJ_NONE; obj->flags = 0; - memcpy(obj->sha1, sha1, 20); + hashcpy(obj->sha1, sha1); if (obj_hash_size - 1 <= nr_objs * 2) grow_object_hash(); diff --git a/patch-id.c b/patch-id.c index 3b4c80f764..086d2d9c68 100644 --- a/patch-id.c +++ b/patch-id.c @@ -47,7 +47,7 @@ static void generate_id_list(void) if (!get_sha1_hex(p, n)) { flush_current_id(patchlen, sha1, &ctx); - memcpy(sha1, n, 20); + hashcpy(sha1, n); patchlen = 0; continue; } diff --git a/receive-pack.c b/receive-pack.c index 81e91909b8..201531626c 100644 --- a/receive-pack.c +++ b/receive-pack.c @@ -247,8 +247,8 @@ static void read_head_info(void) report_status = 1; } cmd = xmalloc(sizeof(struct command) + len - 80); - memcpy(cmd->old_sha1, old_sha1, 20); - memcpy(cmd->new_sha1, new_sha1, 20); + hashcpy(cmd->old_sha1, old_sha1); + hashcpy(cmd->new_sha1, new_sha1); memcpy(cmd->ref_name, line + 82, len - 81); cmd->error_string = "n/a (unpacker error)"; cmd->next = NULL; diff --git a/refs.c b/refs.c index 17cd0cef3c..e70ef0ae0f 100644 --- a/refs.c +++ b/refs.c @@ -29,7 +29,7 @@ const char *resolve_ref(const char *path, unsigned char *sha1, int reading) if (lstat(path, &st) < 0) { if (reading || errno != ENOENT) return NULL; - memset(sha1, 0, 20); + hashclr(sha1); return path; } diff --git a/revision.c b/revision.c index 5a91d06b98..1d89d72738 100644 --- a/revision.c +++ b/revision.c @@ -496,7 +496,7 @@ static int add_parents_only(struct rev_info *revs, const char *arg, int flags) it = get_reference(revs, arg, sha1, 0); if (it->type != OBJ_TAG) break; - memcpy(sha1, ((struct tag*)it)->tagged->sha1, 20); + hashcpy(sha1, ((struct tag*)it)->tagged->sha1); } if (it->type != OBJ_COMMIT) return 0; diff --git a/send-pack.c b/send-pack.c index f7c0cfc6f6..fd79a61923 100644 --- a/send-pack.c +++ b/send-pack.c @@ -185,7 +185,7 @@ static int one_local_ref(const char *refname, const unsigned char *sha1) struct ref *ref; int len = strlen(refname) + 1; ref = xcalloc(1, sizeof(*ref) + len); - memcpy(ref->new_sha1, sha1, 20); + hashcpy(ref->new_sha1, sha1); memcpy(ref->name, refname, len); *local_tail = ref; local_tail = &ref->next; @@ -310,7 +310,7 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec) continue; } } - memcpy(ref->new_sha1, ref->peer_ref->new_sha1, 20); + hashcpy(ref->new_sha1, ref->peer_ref->new_sha1); if (is_zero_sha1(ref->new_sha1)) { error("cannot happen anymore"); ret = -3; diff --git a/sha1_file.c b/sha1_file.c index 066cff1fa6..769a80984d 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -540,7 +540,7 @@ struct packed_git *add_packed_git(char *path, int path_len, int local) p->pack_use_cnt = 0; p->pack_local = local; if ((path_len > 44) && !get_sha1_hex(path + path_len - 44, sha1)) - memcpy(p->sha1, sha1, 20); + hashcpy(p->sha1, sha1); return p; } @@ -571,7 +571,7 @@ struct packed_git *parse_pack_index_file(const unsigned char *sha1, char *idx_pa p->pack_base = NULL; p->pack_last_used = 0; p->pack_use_cnt = 0; - memcpy(p->sha1, sha1, 20); + hashcpy(p->sha1, sha1); return p; } @@ -953,7 +953,7 @@ int check_reuse_pack_delta(struct packed_git *p, unsigned long offset, ptr = unpack_object_header(p, ptr, kindp, sizep); if (*kindp != OBJ_DELTA) goto done; - memcpy(base, (unsigned char *) p->pack_base + ptr, 20); + hashcpy(base, (unsigned char *) p->pack_base + ptr); status = 0; done: unuse_packed_git(p); @@ -981,7 +981,7 @@ void packed_object_info_detail(struct pack_entry *e, if (p->pack_size <= offset + 20) die("pack file %s records an incomplete delta base", p->pack_name); - memcpy(base_sha1, pack, 20); + hashcpy(base_sha1, pack); do { struct pack_entry base_ent; unsigned long junk; @@ -1201,7 +1201,7 @@ int nth_packed_object_sha1(const struct packed_git *p, int n, void *index = p->index_base + 256; if (n < 0 || num_packed_objects(p) <= n) return -1; - memcpy(sha1, (char *) index + (24 * n) + 4, 20); + hashcpy(sha1, (unsigned char *) index + (24 * n) + 4); return 0; } @@ -1218,7 +1218,7 @@ int find_pack_entry_one(const unsigned char *sha1, int cmp = hashcmp((unsigned char *)index + (24 * mi) + 4, sha1); if (!cmp) { e->offset = ntohl(*((unsigned int *) ((char *) index + (24 * mi)))); - memcpy(e->sha1, sha1, 20); + hashcpy(e->sha1, sha1); e->p = p; return 1; } @@ -1331,7 +1331,7 @@ void *read_object_with_reference(const unsigned char *sha1, unsigned long isize; unsigned char actual_sha1[20]; - memcpy(actual_sha1, sha1, 20); + hashcpy(actual_sha1, sha1); while (1) { int ref_length = -1; const char *ref_type = NULL; @@ -1342,7 +1342,7 @@ void *read_object_with_reference(const unsigned char *sha1, if (!strcmp(type, required_type)) { *size = isize; if (actual_sha1_return) - memcpy(actual_sha1_return, actual_sha1, 20); + hashcpy(actual_sha1_return, actual_sha1); return buffer; } /* Handle references */ @@ -1537,7 +1537,7 @@ int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned cha */ filename = write_sha1_file_prepare(buf, len, type, sha1, hdr, &hdrlen); if (returnsha1) - memcpy(returnsha1, sha1, 20); + hashcpy(returnsha1, sha1); if (has_sha1_file(sha1)) return 0; fd = open(filename, O_RDONLY); diff --git a/sha1_name.c b/sha1_name.c index e9eb6ce882..89b9e3b77a 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -103,7 +103,7 @@ static int find_short_packed_object(int len, const unsigned char *match, unsigne !match_sha(len, match, next)) { /* unique within this pack */ if (!found) { - memcpy(found_sha1, now, 20); + hashcpy(found_sha1, now); found++; } else if (hashcmp(found_sha1, now)) { @@ -120,7 +120,7 @@ static int find_short_packed_object(int len, const unsigned char *match, unsigne } } if (found == 1) - memcpy(sha1, found_sha1, 20); + hashcpy(sha1, found_sha1); return found; } @@ -140,13 +140,13 @@ static int find_unique_short_object(int len, char *canonical, if (1 < has_unpacked || 1 < has_packed) return SHORT_NAME_AMBIGUOUS; if (has_unpacked != has_packed) { - memcpy(sha1, (has_packed ? packed_sha1 : unpacked_sha1), 20); + hashcpy(sha1, (has_packed ? packed_sha1 : unpacked_sha1)); return 0; } /* Both have unique ones -- do they match? */ if (hashcmp(packed_sha1, unpacked_sha1)) return SHORT_NAME_AMBIGUOUS; - memcpy(sha1, packed_sha1, 20); + hashcpy(sha1, packed_sha1); return 0; } @@ -320,13 +320,13 @@ static int get_parent(const char *name, int len, if (parse_commit(commit)) return -1; if (!idx) { - memcpy(result, commit->object.sha1, 20); + hashcpy(result, commit->object.sha1); return 0; } p = commit->parents; while (p) { if (!--idx) { - memcpy(result, p->item->object.sha1, 20); + hashcpy(result, p->item->object.sha1); return 0; } p = p->next; @@ -347,9 +347,9 @@ static int get_nth_ancestor(const char *name, int len, if (!commit || parse_commit(commit) || !commit->parents) return -1; - memcpy(sha1, commit->parents->item->object.sha1, 20); + hashcpy(sha1, commit->parents->item->object.sha1); } - memcpy(result, sha1, 20); + hashcpy(result, sha1); return 0; } @@ -401,7 +401,7 @@ static int peel_onion(const char *name, int len, unsigned char *sha1) o = deref_tag(o, name, sp - name - 2); if (!o || (!o->parsed && !parse_object(o->sha1))) return -1; - memcpy(sha1, o->sha1, 20); + hashcpy(sha1, o->sha1); } else { /* At this point, the syntax look correct, so @@ -413,7 +413,7 @@ static int peel_onion(const char *name, int len, unsigned char *sha1) if (!o || (!o->parsed && !parse_object(o->sha1))) return -1; if (o->type == expected_type) { - memcpy(sha1, o->sha1, 20); + hashcpy(sha1, o->sha1); return 0; } if (o->type == OBJ_TAG) @@ -520,7 +520,7 @@ int get_sha1(const char *name, unsigned char *sha1) memcmp(ce->name, cp, namelen)) break; if (ce_stage(ce) == stage) { - memcpy(sha1, ce->sha1, 20); + hashcpy(sha1, ce->sha1); return 0; } pos++; diff --git a/tree-walk.c b/tree-walk.c index 3f83e98f3a..14cc5aea6c 100644 --- a/tree-walk.c +++ b/tree-walk.c @@ -179,7 +179,7 @@ static int find_tree_entry(struct tree_desc *t, const char *name, unsigned char if (cmp < 0) break; if (entrylen == namelen) { - memcpy(result, sha1, 20); + hashcpy(result, sha1); return 0; } if (name[entrylen] != '/') @@ -187,7 +187,7 @@ static int find_tree_entry(struct tree_desc *t, const char *name, unsigned char if (!S_ISDIR(*mode)) break; if (++entrylen == namelen) { - memcpy(result, sha1, 20); + hashcpy(result, sha1); return 0; } return get_tree_entry(sha1, name + entrylen, result, mode); diff --git a/tree.c b/tree.c index ef456be9dd..ea386e5066 100644 --- a/tree.c +++ b/tree.c @@ -25,7 +25,7 @@ static int read_one_entry(const unsigned char *sha1, const char *base, int basel ce->ce_flags = create_ce_flags(baselen + len, stage); memcpy(ce->name, base, baselen); memcpy(ce->name + baselen, pathname, len+1); - memcpy(ce->sha1, sha1, 20); + hashcpy(ce->sha1, sha1); return add_cache_entry(ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_SKIP_DFCHECK); } diff --git a/unpack-trees.c b/unpack-trees.c index 467d9940f5..3ac0289b3a 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -200,7 +200,7 @@ static int unpack_trees_rec(struct tree_entry_list **posns, int len, any_files = 1; - memcpy(ce->sha1, posns[i]->sha1, 20); + hashcpy(ce->sha1, posns[i]->sha1); src[i + o->merge] = ce; subposns[i] = df_conflict_list; posns[i] = posns[i]->next; diff --git a/upload-pack.c b/upload-pack.c index fcf279843a..51ce936b06 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -374,7 +374,7 @@ static int get_common_commits(void) sha1_to_hex(sha1), multi_ack ? " continue" : ""); if (multi_ack) - memcpy(last_sha1, sha1, 20); + hashcpy(last_sha1, sha1); } continue; } From a8e0d16d85fb2ea53775f64549cac2396cd621a6 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 23 Aug 2006 13:57:23 -0700 Subject: [PATCH 160/160] Convert memset(hash,0,20) to hashclr(hash). In the same spirit as hashcmp() and hashcpy(). Signed-off-by: Junio C Hamano --- blame.c | 2 +- builtin-update-ref.c | 2 +- cache.h | 4 ++++ diff-lib.c | 2 +- http-push.c | 2 +- sha1_name.c | 2 +- 6 files changed, 9 insertions(+), 5 deletions(-) diff --git a/blame.c b/blame.c index 5a8af72623..8968046b00 100644 --- a/blame.c +++ b/blame.c @@ -165,7 +165,7 @@ static int get_blob_sha1(struct tree *t, const char *pathname, blame_file = pathname; pathspec[0] = pathname; pathspec[1] = NULL; - memset(blob_sha1, 0, sizeof(blob_sha1)); + hashclr(blob_sha1); read_tree_recursive(t, "", 0, 0, pathspec, get_blob_sha1_internal); for (i = 0; i < 20; i++) { diff --git a/builtin-update-ref.c b/builtin-update-ref.c index 5bd71825fd..90a3da53ad 100644 --- a/builtin-update-ref.c +++ b/builtin-update-ref.c @@ -44,7 +44,7 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix) if (get_sha1(value, sha1)) die("%s: not a valid SHA1", value); - memset(oldsha1, 0, 20); + hashclr(oldsha1); if (oldval && get_sha1(oldval, oldsha1)) die("%s: not a valid old SHA1", oldval); diff --git a/cache.h b/cache.h index cc3f00c2b8..e00505a343 100644 --- a/cache.h +++ b/cache.h @@ -222,6 +222,10 @@ static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src) { memcpy(sha_dst, sha_src, 20); } +static inline void hashclr(unsigned char *hash) +{ + memset(hash, 0, 20); +} int git_mkstemp(char *path, size_t n, const char *template); diff --git a/diff-lib.c b/diff-lib.c index 2fc41263ae..9edfa92626 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -48,7 +48,7 @@ int run_diff_files(struct rev_info *revs, int silent_on_removed) memcpy(dpath->path, ce->name, path_len); dpath->path[path_len] = '\0'; dpath->mode = 0; - memset(dpath->sha1, 0, 20); + hashclr(dpath->sha1); memset(&(dpath->parent[0]), 0, sizeof(struct combine_diff_parent)*5); diff --git a/http-push.c b/http-push.c index ebfcc73a9e..8df7a0d576 100644 --- a/http-push.c +++ b/http-push.c @@ -2164,7 +2164,7 @@ static void fetch_symref(const char *path, char **symref, unsigned char *sha1) if (*symref != NULL) free(*symref); *symref = NULL; - memset(sha1, 0, 20); + hashclr(sha1); if (buffer.posn == 0) return; diff --git a/sha1_name.c b/sha1_name.c index 89b9e3b77a..3f6b77ccfa 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -159,7 +159,7 @@ static int get_short_sha1(const char *name, int len, unsigned char *sha1, if (len < MINIMUM_ABBREV) return -1; - memset(res, 0, 20); + hashclr(res); memset(canonical, 'x', 40); for (i = 0; i < len ;i++) { unsigned char c = name[i];