From 560b25a86f30ad81d2bc3a383da19c3b7e631b8b Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 30 Jun 2006 22:55:30 -0400 Subject: [PATCH 1/9] don't load objects needlessly when repacking If no delta is attempted on some objects then it is useless to load them in memory, neither create any delta index for them. The best thing to do is therefore to load and index them only when really needed. Signed-off-by: Nicolas Pitre Signed-off-by: Junio C Hamano --- pack-objects.c | 45 ++++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/pack-objects.c b/pack-objects.c index 47da33baa3..b486ea528a 100644 --- a/pack-objects.c +++ b/pack-objects.c @@ -970,11 +970,12 @@ struct unpacked { * one. */ static int try_delta(struct unpacked *trg, struct unpacked *src, - struct delta_index *src_index, unsigned max_depth) + unsigned max_depth) { struct object_entry *trg_entry = trg->entry; struct object_entry *src_entry = src->entry; - unsigned long size, src_size, delta_size, sizediff, max_size; + unsigned long trg_size, src_size, delta_size, sizediff, max_size, sz; + char type[10]; void *delta_buf; /* Don't bother doing diffs between different types */ @@ -1009,19 +1010,38 @@ static int try_delta(struct unpacked *trg, struct unpacked *src, return 0; /* Now some size filtering heuristics. */ - size = trg_entry->size; - max_size = size/2 - 20; + trg_size = trg_entry->size; + max_size = trg_size/2 - 20; max_size = max_size * (max_depth - src_entry->depth) / max_depth; if (max_size == 0) return 0; if (trg_entry->delta && trg_entry->delta_size <= max_size) max_size = trg_entry->delta_size-1; src_size = src_entry->size; - sizediff = src_size < size ? size - src_size : 0; + sizediff = src_size < trg_size ? trg_size - src_size : 0; if (sizediff >= max_size) return 0; - delta_buf = create_delta(src_index, trg->data, size, &delta_size, max_size); + /* Load data if not already done */ + if (!trg->data) { + trg->data = read_sha1_file(trg_entry->sha1, type, &sz); + if (sz != trg_size) + die("object %s inconsistent object length (%lu vs %lu)", + sha1_to_hex(trg_entry->sha1), sz, trg_size); + } + if (!src->data) { + src->data = read_sha1_file(src_entry->sha1, type, &sz); + if (sz != src_size) + die("object %s inconsistent object length (%lu vs %lu)", + sha1_to_hex(src_entry->sha1), sz, src_size); + } + if (!src->index) { + src->index = create_delta_index(src->data, src_size); + if (!src->index) + die("out of memory"); + } + + delta_buf = create_delta(src->index, trg->data, trg_size, &delta_size, max_size); if (!delta_buf) return 0; @@ -1054,8 +1074,6 @@ static void find_deltas(struct object_entry **list, int window, int depth) while (--i >= 0) { struct object_entry *entry = list[i]; struct unpacked *n = array + idx; - unsigned long size; - char type[10]; int j; if (!entry->preferred_base) @@ -1082,11 +1100,8 @@ static void find_deltas(struct object_entry **list, int window, int depth) free_delta_index(n->index); n->index = NULL; free(n->data); + n->data = NULL; n->entry = entry; - n->data = read_sha1_file(entry->sha1, type, &size); - if (size != entry->size) - die("object %s inconsistent object length (%lu vs %lu)", - sha1_to_hex(entry->sha1), size, entry->size); j = window; while (--j > 0) { @@ -1097,7 +1112,7 @@ static void find_deltas(struct object_entry **list, int window, int depth) m = array + other_idx; if (!m->entry) break; - if (try_delta(n, m, m->index, depth) < 0) + if (try_delta(n, m, depth) < 0) break; } /* if we made n a delta, and if n is already at max @@ -1107,10 +1122,6 @@ static void find_deltas(struct object_entry **list, int window, int depth) if (entry->delta && depth <= entry->depth) continue; - n->index = create_delta_index(n->data, size); - if (!n->index) - die("out of memory"); - idx++; if (idx >= window) idx = 0; From 03e0ea871206e50bcd1c5167c6fc9a41c6642abb Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 30 Jun 2006 21:42:53 -0700 Subject: [PATCH 2/9] git-svn: allow a local target directory to be specified for init git-svn init url://to/the/repo local-repo will create the local-repo dirrectory if doesn't exist yet and populate it as expected. Original patch by Luca Barbato, cleaned up and made to work for the current version of git-svn by me (Eric Wong). Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- contrib/git-svn/git-svn.perl | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl index b3d3f479da..1e19aa19b2 100755 --- a/contrib/git-svn/git-svn.perl +++ b/contrib/git-svn/git-svn.perl @@ -264,9 +264,19 @@ when you have upgraded your tools and habits to use refs/remotes/$GIT_SVN } sub init { - $SVN_URL = shift or die "SVN repository location required " . + my $url = shift or die "SVN repository location required " . "as a command-line argument\n"; - $SVN_URL =~ s!/+$!!; # strip trailing slash + $url =~ s!/+$!!; # strip trailing slash + + if (my $repo_path = shift) { + unless (-d $repo_path) { + mkpath([$repo_path]); + } + $GIT_DIR = $ENV{GIT_DIR} = $repo_path . "/.git"; + init_vars(); + } + + $SVN_URL = $url; unless (-d $GIT_DIR) { my @init_db = ('git-init-db'); push @init_db, "--template=$_template" if defined $_template; From c64ea8521bc81b52da45d3deb3a419928d4b6b29 Mon Sep 17 00:00:00 2001 From: Robin Rosenberg Date: Sun, 2 Jul 2006 02:07:40 +0200 Subject: [PATCH 3/9] Minor documentation fixup. Signed-off-by: Robin Rosenberg Signed-off-by: Junio C Hamano --- Documentation/git-commit.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index 0fe66f2d0c..517a86b238 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -15,9 +15,9 @@ SYNOPSIS DESCRIPTION ----------- Updates the index file for given paths, or all modified files if -'-a' is specified, and makes a commit object. The command -VISUAL and EDITOR environment variables to edit the commit log -message. +'-a' is specified, and makes a commit object. The command specified +by either the VISUAL or EDITOR environment variables are used to edit +the commit log message. Several environment variable are used during commits. They are documented in gitlink:git-commit-tree[1]. From ac3bc6c1d1f549f6809d8a7d29bcaed302f3c193 Mon Sep 17 00:00:00 2001 From: Petr Baudis Date: Sat, 1 Jul 2006 23:56:26 +0200 Subject: [PATCH 4/9] Fix errno usage in connect.c errno was used after it could've been modified by a subsequent library call. Spotted by Morten Welinder. Signed-off-by: Petr Baudis Signed-off-by: Junio C Hamano --- connect.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/connect.c b/connect.c index cb4656d79d..9a87bd999a 100644 --- a/connect.c +++ b/connect.c @@ -328,7 +328,7 @@ static enum protocol get_protocol(const char *name) */ static int git_tcp_connect_sock(char *host) { - int sockfd = -1; + int sockfd = -1, saved_errno = 0; char *colon, *end; const char *port = STR(DEFAULT_GIT_PORT); struct addrinfo hints, *ai0, *ai; @@ -362,9 +362,12 @@ static int git_tcp_connect_sock(char *host) for (ai0 = ai; ai; ai = ai->ai_next) { sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - if (sockfd < 0) + if (sockfd < 0) { + saved_errno = errno; continue; + } if (connect(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) { + saved_errno = errno; close(sockfd); sockfd = -1; continue; @@ -375,7 +378,7 @@ static int git_tcp_connect_sock(char *host) freeaddrinfo(ai0); if (sockfd < 0) - die("unable to connect a socket (%s)", strerror(errno)); + die("unable to connect a socket (%s)", strerror(saved_errno)); return sockfd; } @@ -387,7 +390,7 @@ static int git_tcp_connect_sock(char *host) */ static int git_tcp_connect_sock(char *host) { - int sockfd = -1; + int sockfd = -1, saved_errno = 0; char *colon, *end; char *port = STR(DEFAULT_GIT_PORT), *ep; struct hostent *he; @@ -426,8 +429,10 @@ static int git_tcp_connect_sock(char *host) for (ap = he->h_addr_list; *ap; ap++) { sockfd = socket(he->h_addrtype, SOCK_STREAM, 0); - if (sockfd < 0) + if (sockfd < 0) { + saved_errno = errno; continue; + } memset(&sa, 0, sizeof sa); sa.sin_family = he->h_addrtype; @@ -435,6 +440,7 @@ static int git_tcp_connect_sock(char *host) memcpy(&sa.sin_addr, *ap, he->h_length); if (connect(sockfd, (struct sockaddr *)&sa, sizeof sa) < 0) { + saved_errno = errno; close(sockfd); sockfd = -1; continue; @@ -443,7 +449,7 @@ static int git_tcp_connect_sock(char *host) } if (sockfd < 0) - die("unable to connect a socket (%s)", strerror(errno)); + die("unable to connect a socket (%s)", strerror(saved_errno)); return sockfd; } From 6631c73685bea3c6300938f4900db0d0c6bee457 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 30 Jun 2006 20:21:59 -0700 Subject: [PATCH 5/9] revision.c: --full-history fix. With history simplification, we still show merges that are required to make the history _complete_, i.e. say that you had: a | b / \ c d | | and neither "a" nor "b" actually changed the file, but both "c" and "d" did: in this case we have to leave "b" around just because otherwise there would be no way to show the _relationship_, even if "b" itself doesn't actually change the tree in any way what-so-ever. It would make sense to make that further simplification if the "--parents" flag wasn't present. In that case the user is literally asking for a list of commits and is not interested in the relationship between them. This patch also fixes a real bug. Without this patch, the "--parents --full-history" combination (which you'd get if you do something like gitk --full-history Makefile or similar) will actually _drop_ merges where all children are identical. That's wrong in the --full-history case, because it means that the graph ends up missing lots of entries. In the process, this also should make git-rev-list --full-history Makefile give just the _true_ list of all commits that changed Makefile (and properly ignore merges that were identical in one parent), because now we're not asking for "--parent", so we don't need the unnecessary merge commits to keep the history together. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- revision.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/revision.c b/revision.c index b963f2adfd..1cf6276ad8 100644 --- a/revision.c +++ b/revision.c @@ -280,7 +280,7 @@ int rev_same_tree_as_empty(struct rev_info *revs, struct tree *t1) static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit) { struct commit_list **pp, *parent; - int tree_changed = 0; + int tree_changed = 0, tree_same = 0; if (!commit->tree) return; @@ -298,6 +298,7 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit) parse_commit(p); switch (rev_compare_tree(revs, p->tree, commit->tree)) { case REV_TREE_SAME: + tree_same = 1; if (!revs->simplify_history || (p->object.flags & UNINTERESTING)) { /* Even if a merge with an uninteresting * side branch brought the entire change @@ -334,7 +335,7 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit) } die("bad tree compare for commit %s", sha1_to_hex(commit->object.sha1)); } - if (tree_changed) + if (tree_changed && !tree_same) commit->object.flags |= TREECHANGE; } @@ -896,6 +897,8 @@ static int rewrite_one(struct rev_info *revs, struct commit **pp) struct commit *p = *pp; if (!revs->limited) add_parents_to_list(revs, p, &revs->commits); + if (p->parents && p->parents->next) + return 0; if (p->object.flags & (TREECHANGE | UNINTERESTING)) return 0; if (!p->parents) @@ -988,8 +991,15 @@ struct commit *get_revision(struct rev_info *revs) commit->parents && commit->parents->next) continue; if (revs->prune_fn && revs->dense) { - if (!(commit->object.flags & TREECHANGE)) - continue; + /* Commit without changes? */ + if (!(commit->object.flags & TREECHANGE)) { + /* drop merges unless we want parenthood */ + if (!revs->parents) + continue; + /* non-merge - always ignore it */ + if (commit->parents && !commit->parents->next) + continue; + } if (revs->parents) rewrite_parents(revs, commit); } From 0556a11a0df6b4119e01aa77dfb795561e62eb34 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 30 Jun 2006 11:20:33 -0700 Subject: [PATCH 6/9] git object hash cleanups This IMNSHO cleans up the object hashing. The hash expansion is separated out into a function of its own, the hash array (and size) names are made more obvious, and the code is generally made to look a bit more like the object-ref hashing. It also gets rid of "find_object()" returning an index (or negative position if no object is found), since that is made redundant by the simplified object rehashing. The basic operation is now "lookup_object()" which just returns the object itself. There's an almost unmeasurable speed increase, but more importantly, I think the end result is more readable. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- object.c | 115 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 62 insertions(+), 53 deletions(-) diff --git a/object.c b/object.c index 31c77ea03a..37277f9438 100644 --- a/object.c +++ b/object.c @@ -5,88 +5,97 @@ #include "commit.h" #include "tag.h" -static struct object **objs; -static int nr_objs, obj_allocs; +static struct object **obj_hash; +static int nr_objs, obj_hash_size; unsigned int get_max_object_index(void) { - return obj_allocs; + return obj_hash_size; } struct object *get_indexed_object(unsigned int idx) { - return objs[idx]; + return obj_hash[idx]; } const char *type_names[] = { "none", "blob", "tree", "commit", "bad" }; +static unsigned int hash_obj(struct object *obj, unsigned int n) +{ + unsigned int hash = *(unsigned int *)obj->sha1; + return hash % n; +} + +static void insert_obj_hash(struct object *obj, struct object **hash, unsigned int size) +{ + int j = hash_obj(obj, size); + + while (hash[j]) { + j++; + if (j >= size) + j = 0; + } + hash[j] = obj; +} + static int hashtable_index(const unsigned char *sha1) { unsigned int i; memcpy(&i, sha1, sizeof(unsigned int)); - return (int)(i % obj_allocs); -} - -static int find_object(const unsigned char *sha1) -{ - int i; - - if (!objs) - return -1; - - i = hashtable_index(sha1); - while (objs[i]) { - if (memcmp(sha1, objs[i]->sha1, 20) == 0) - return i; - i++; - if (i == obj_allocs) - i = 0; - } - return -1 - i; + return (int)(i % obj_hash_size); } struct object *lookup_object(const unsigned char *sha1) { - int pos = find_object(sha1); - if (pos >= 0) - return objs[pos]; - return NULL; + int i; + struct object *obj; + + if (!obj_hash) + return NULL; + + i = hashtable_index(sha1); + while ((obj = obj_hash[i]) != NULL) { + if (!memcmp(sha1, obj->sha1, 20)) + break; + i++; + if (i == obj_hash_size) + i = 0; + } + return obj; +} + +static void grow_object_hash(void) +{ + int i; + int new_hash_size = obj_hash_size < 32 ? 32 : 2 * obj_hash_size; + struct object **new_hash; + + new_hash = calloc(new_hash_size, sizeof(struct object *)); + for (i = 0; i < obj_hash_size; i++) { + struct object *obj = obj_hash[i]; + if (!obj) + continue; + insert_obj_hash(obj, new_hash, new_hash_size); + } + free(obj_hash); + obj_hash = new_hash; + obj_hash_size = new_hash_size; } void created_object(const unsigned char *sha1, struct object *obj) { - int pos; - obj->parsed = 0; - memcpy(obj->sha1, sha1, 20); - obj->type = TYPE_NONE; obj->used = 0; + obj->type = TYPE_NONE; + obj->flags = 0; + memcpy(obj->sha1, sha1, 20); - if (obj_allocs - 1 <= nr_objs * 2) { - int i, count = obj_allocs; - obj_allocs = (obj_allocs < 32 ? 32 : 2 * obj_allocs); - objs = xrealloc(objs, obj_allocs * sizeof(struct object *)); - memset(objs + count, 0, (obj_allocs - count) - * sizeof(struct object *)); - for (i = 0; i < obj_allocs; i++) - if (objs[i]) { - int j = find_object(objs[i]->sha1); - if (j != i) { - j = -1 - j; - objs[j] = objs[i]; - objs[i] = NULL; - } - } - } + if (obj_hash_size - 1 <= nr_objs * 2) + grow_object_hash(); - pos = find_object(sha1); - if (pos >= 0) - die("Inserting %s twice\n", sha1_to_hex(sha1)); - pos = -pos-1; - - objs[pos] = obj; + insert_obj_hash(obj, obj_hash, obj_hash_size); nr_objs++; } From cdd4037d7053647c97139ac77d4319124f17d47e Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 30 Jun 2006 18:54:32 -0700 Subject: [PATCH 7/9] gitweb: optimize per-file history generation The rev-list command that is recent enough can filter commits based on paths they touch, so use it instead of generating the full list and limiting it by passing it with diff-tree --stdin. [jc: The patch originally came from Luben Tuikov but the it was corrupt, but it was short enough to be applied by hand. I added the --full-history to make the output compatible with the original while doing so.] Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index 035e76d0a3..1007742153 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -2295,16 +2295,13 @@ sub git_history { "\n"; print "
/" . esc_html($file_name) . "
\n"; - open my $fd, "-|", "$gitbin/git-rev-list $hash | $gitbin/git-diff-tree -r --stdin -- \'$file_name\'"; - my $commit; + open my $fd, "-|", + "$gitbin/git-rev-list --full-history $hash -- \'$file_name\'"; print "\n"; my $alternate = 0; while (my $line = <$fd>) { if ($line =~ m/^([0-9a-fA-F]{40})/){ - $commit = $1; - next; - } - if ($line =~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)\t(.*)$/ && (defined $commit)) { + my $commit = $1; my %co = git_read_commit($commit); if (!%co) { next; @@ -2336,7 +2333,6 @@ sub git_history { } print "\n" . "\n"; - undef $commit; } } print "
\n"; From 85b7cfb1036b4218d13cbc215729ad083a61a0ea Mon Sep 17 00:00:00 2001 From: Luben Tuikov Date: Fri, 30 Jun 2006 19:11:18 -0700 Subject: [PATCH 8/9] gitweb: Enable tree (directory) history display This patch allows history display of whole trees/directories a la "git-rev-list HEAD -- ". I find this useful especially when a project lives in its own subdirectory, as opposed to being all of the GIT repository (i.e. when a sub-project is merged into a super-project). Signed-off-by: Luben Tuikov 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 1007742153..efffc8d078 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -1676,6 +1676,7 @@ sub git_tree { "\n" . "" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$t_hash$base_key;f=$base$t_name")}, "tree") . + " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;h=$hash_base;f=$base$t_name")}, "history") . "\n"; } print "\n"; From 4a87b43e374626a95c14362f21c9ca1023638a2c Mon Sep 17 00:00:00 2001 From: Dennis Stosberg Date: Wed, 21 Jun 2006 15:07:08 +0200 Subject: [PATCH 9/9] gitweb: Declare global variables with "our" Variables declared with "my" in the file scope cannot be accessed from subroutines with mod_perl. Signed-off-by: Junio C Hamano --- gitweb/gitweb.cgi | 55 +++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi index efffc8d078..3e2790c5d6 100755 --- a/gitweb/gitweb.cgi +++ b/gitweb/gitweb.cgi @@ -16,21 +16,21 @@ use Encode; use Fcntl ':mode'; binmode STDOUT, ':utf8'; -my $cgi = new CGI; -my $version = "267"; -my $my_url = $cgi->url(); -my $my_uri = $cgi->url(-absolute => 1); -my $rss_link = ""; +our $cgi = new CGI; +our $version = "267"; +our $my_url = $cgi->url(); +our $my_uri = $cgi->url(-absolute => 1); +our $rss_link = ""; # location of the git-core binaries -my $gitbin = "/usr/bin"; +our $gitbin = "/usr/bin"; # absolute fs-path which will be prepended to the project path -#my $projectroot = "/pub/scm"; -my $projectroot = "/home/kay/public_html/pub/scm"; +#our $projectroot = "/pub/scm"; +our $projectroot = "/home/kay/public_html/pub/scm"; # version of the git-core binaries -my $git_version = qx($gitbin/git --version); +our $git_version = qx($gitbin/git --version); if ($git_version =~ m/git version (.*)$/) { $git_version = $1; } else { @@ -38,32 +38,31 @@ if ($git_version =~ m/git version (.*)$/) { } # location for temporary files needed for diffs -my $git_temp = "/tmp/gitweb"; +our $git_temp = "/tmp/gitweb"; # target of the home link on top of all pages -my $home_link = $my_uri; +our $home_link = $my_uri; # html text to include at home page -my $home_text = "indextext.html"; +our $home_text = "indextext.html"; # URI of default stylesheet -my $stylesheet = "gitweb.css"; +our $stylesheet = "gitweb.css"; # source of projects list -#my $projects_list = $projectroot; -my $projects_list = "index/index.aux"; +#our $projects_list = $projectroot; +our $projects_list = "index/index.aux"; # default blob_plain mimetype and default charset for text/plain blob -my $default_blob_plain_mimetype = 'text/plain'; -my $default_text_plain_charset = undef; +our $default_blob_plain_mimetype = 'text/plain'; +our $default_text_plain_charset = undef; # file to use for guessing MIME types before trying /etc/mime.types # (relative to the current git repository) -my $mimetypes_file = undef; - +our $mimetypes_file = undef; # input validation and dispatch -my $action = $cgi->param('a'); +our $action = $cgi->param('a'); if (defined $action) { if ($action =~ m/[^0-9a-zA-Z\.\-_]/) { undef $action; @@ -78,7 +77,7 @@ if (defined $action) { } } -my $order = $cgi->param('o'); +our $order = $cgi->param('o'); if (defined $order) { if ($order =~ m/[^0-9a-zA-Z_]/) { undef $order; @@ -86,7 +85,7 @@ if (defined $order) { } } -my $project = ($cgi->param('p') || $ENV{'PATH_INFO'}); +our $project = ($cgi->param('p') || $ENV{'PATH_INFO'}); if (defined $project) { $project =~ s|^/||; $project =~ s|/$||; $project = validate_input($project); @@ -109,7 +108,7 @@ if (defined $project) { exit; } -my $file_name = $cgi->param('f'); +our $file_name = $cgi->param('f'); if (defined $file_name) { $file_name = validate_input($file_name); if (!defined($file_name)) { @@ -117,7 +116,7 @@ if (defined $file_name) { } } -my $hash = $cgi->param('h'); +our $hash = $cgi->param('h'); if (defined $hash) { $hash = validate_input($hash); if (!defined($hash)) { @@ -125,7 +124,7 @@ if (defined $hash) { } } -my $hash_parent = $cgi->param('hp'); +our $hash_parent = $cgi->param('hp'); if (defined $hash_parent) { $hash_parent = validate_input($hash_parent); if (!defined($hash_parent)) { @@ -133,7 +132,7 @@ if (defined $hash_parent) { } } -my $hash_base = $cgi->param('hb'); +our $hash_base = $cgi->param('hb'); if (defined $hash_base) { $hash_base = validate_input($hash_base); if (!defined($hash_base)) { @@ -141,7 +140,7 @@ if (defined $hash_base) { } } -my $page = $cgi->param('pg'); +our $page = $cgi->param('pg'); if (defined $page) { if ($page =~ m/[^0-9]$/) { undef $page; @@ -149,7 +148,7 @@ if (defined $page) { } } -my $searchtext = $cgi->param('s'); +our $searchtext = $cgi->param('s'); if (defined $searchtext) { if ($searchtext =~ m/[^a-zA-Z0-9_\.\/\-\+\:\@ ]/) { undef $searchtext;