From c774b2dcf6c16a408757e9da1bf7c006528fc6a6 Mon Sep 17 00:00:00 2001 From: Art Haas Date: Tue, 19 Sep 2006 07:20:19 -0500 Subject: [PATCH 01/10] Patch for http-fetch.c and older curl releases Older curl releases do not define CURLE_HTTP_RETURNED_ERROR, they use CURLE_HTTP_NOT_FOUND instead. Newer curl releases keep the CURLE_HTTP_NOT_FOUND definition but using a -DCURL_NO_OLDIES preprocessor flag the old name will not be present in the 'curl.h' header. This patch makes our code written for newer releases of the curl library but allow compiling against an older curl (older than 0x070a03) by defining the missing CURLE_HTTP_RETURNED_ERROR as a synonym for CURLE_HTTP_NOT_FOUND. Signed-off-by: Art Haas Signed-off-by: Junio C Hamano --- http.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/http.h b/http.h index 9ca16acec2..6e12e41688 100644 --- a/http.h +++ b/http.h @@ -22,6 +22,10 @@ #define NO_CURL_EASY_DUPHANDLE #endif +#if LIBCURL_VERSION_NUM < 0x070a03 +#define CURLE_HTTP_RETURNED_ERROR CURLE_HTTP_NOT_FOUND +#endif + struct slot_results { CURLcode curl_result; From 8059319acc3638c8398d1bd34f647a2b28f48d5c Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Tue, 19 Sep 2006 13:57:03 +0200 Subject: [PATCH 02/10] gitweb: Fix mimetype_guess_file for files with multiple extensions Fix getting correct mimetype for "blob_plain" view for files which have multiple extensions, e.g. foo.1.html; now only the last extension is used to find mimetype. Noticed by Martin Waitz. 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 c77270c7cd..969c2de951 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -1197,7 +1197,7 @@ sub mimetype_guess_file { } close(MIME); - $filename =~ /\.(.*?)$/; + $filename =~ /\.([^.]*)$/; return $mimemap{$1}; } From 45ad9b5096b5b823f8cec562500dc8830d5961b5 Mon Sep 17 00:00:00 2001 From: Jonas Fonseca Date: Wed, 20 Sep 2006 12:15:39 +0200 Subject: [PATCH 03/10] Fix trivial typos and inconsistencies in hooks documentation Pointed out by Alan Chandler. Signed-off-by: Jonas Fonseca Signed-off-by: Junio C Hamano --- Documentation/hooks.txt | 56 ++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/Documentation/hooks.txt b/Documentation/hooks.txt index 898b4aaf80..517f49b5cc 100644 --- a/Documentation/hooks.txt +++ b/Documentation/hooks.txt @@ -5,8 +5,7 @@ Hooks are little scripts you can place in `$GIT_DIR/hooks` directory to trigger action at certain points. When `git-init-db` is run, a handful example hooks are copied in the `hooks` directory of the new repository, but by default they are -all disabled. To enable a hook, make it executable with `chmod -+x`. +all disabled. To enable a hook, make it executable with `chmod +x`. This document describes the currently defined hooks. @@ -16,16 +15,16 @@ applypatch-msg This hook is invoked by `git-applypatch` script, which is typically invoked by `git-applymbox`. It takes a single parameter, the name of the file that holds the proposed commit -log message. Exiting with non-zero status causes the -'git-applypatch' to abort before applying the patch. +log message. Exiting with non-zero status causes +`git-applypatch` to abort before applying the patch. The hook is allowed to edit the message file in place, and can be used to normalize the message into some project standard format (if the project has one). It can also be used to refuse the commit after inspecting the message file. -The default applypatch-msg hook, when enabled, runs the -commit-msg hook, if the latter is enabled. +The default 'applypatch-msg' hook, when enabled, runs the +'commit-msg' hook, if the latter is enabled. pre-applypatch -------------- @@ -39,8 +38,8 @@ after application of the patch not committed. It can be used to inspect the current working tree and refuse to make a commit if it does not pass certain test. -The default pre-applypatch hook, when enabled, runs the -pre-commit hook, if the latter is enabled. +The default 'pre-applypatch' hook, when enabled, runs the +'pre-commit' hook, if the latter is enabled. post-applypatch --------------- @@ -61,9 +60,9 @@ invoked before obtaining the proposed commit log message and making a commit. Exiting with non-zero status from this script causes the `git-commit` to abort. -The default pre-commit hook, when enabled, catches introduction +The default 'pre-commit' hook, when enabled, catches introduction of lines with trailing whitespaces and aborts the commit when -a such line is found. +such a line is found. commit-msg ---------- @@ -79,8 +78,8 @@ be used to normalize the message into some project standard format (if the project has one). It can also be used to refuse the commit after inspecting the message file. -The default commit-msg hook, when enabled, detects duplicate -Signed-off-by: lines, and aborts the commit when one is found. +The default 'commit-msg' hook, when enabled, detects duplicate +"Signed-off-by" lines, and aborts the commit if one is found. post-commit ----------- @@ -91,23 +90,24 @@ parameter, and is invoked after a commit is made. This hook is meant primarily for notification, and cannot affect the outcome of `git-commit`. -The default post-commit hook, when enabled, demonstrates how to +The default 'post-commit' hook, when enabled, demonstrates how to send out a commit notification e-mail. update ------ This hook is invoked by `git-receive-pack` on the remote repository, -which is happens when a `git push` is done on a local repository. +which happens when a `git push` is done on a local repository. Just before updating the ref on the remote repository, the update hook is invoked. Its exit status determines the success or failure of the ref update. The hook executes once for each ref to be updated, and takes three parameters: - - the name of the ref being updated, - - the old object name stored in the ref, - - and the new objectname to be stored in the ref. + + - the name of the ref being updated, + - the old object name stored in the ref, + - and the new objectname to be stored in the ref. A zero exit from the update hook allows the ref to be updated. Exiting with a non-zero status prevents `git-receive-pack` @@ -126,16 +126,16 @@ Another use suggested on the mailing list is to use this hook to implement access control which is finer grained than the one based on filesystem group. -The standard output of this hook is sent to /dev/null; if you -want to report something to the git-send-pack on the other end, -you can redirect your output to your stderr. +The standard output of this hook is sent to `/dev/null`; if you +want to report something to the `git-send-pack` on the other end, +you can redirect your output to your `stderr`. post-update ----------- This hook is invoked by `git-receive-pack` on the remote repository, -which is happens when a `git push` is done on a local repository. +which happens when a `git push` is done on a local repository. It executes on the remote repository once after all the refs have been updated. @@ -145,16 +145,16 @@ name of ref that was actually updated. This hook is meant primarily for notification, and cannot affect the outcome of `git-receive-pack`. -The post-update hook can tell what are the heads that were pushed, +The 'post-update' hook can tell what are the heads that were pushed, but it does not know what their original and updated values are, so it is a poor place to do log old..new. -The default post-update hook, when enabled, runs +When enabled, the default 'post-update' hook runs `git-update-server-info` to keep the information used by dumb -transports (e.g., http) up-to-date. If you are publishing -a git repository that is accessible via http, you should +transports (e.g., HTTP) up-to-date. If you are publishing +a git repository that is accessible via HTTP, you should probably enable this hook. -The standard output of this hook is sent to /dev/null; if you -want to report something to the git-send-pack on the other end, -you can redirect your output to your stderr. +The standard output of this hook is sent to `/dev/null`; if you +want to report something to the `git-send-pack` on the other end, +you can redirect your output to your `stderr`. From 44d2775a98c14daa77baa66b039080acad5efa0c Mon Sep 17 00:00:00 2001 From: Jonas Fonseca Date: Wed, 20 Sep 2006 12:23:41 +0200 Subject: [PATCH 04/10] gitk(1): mention --all Signed-off-by: Jonas Fonseca Signed-off-by: Junio C Hamano --- Documentation/gitk.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Documentation/gitk.txt b/Documentation/gitk.txt index 23be0050b0..f1aeb07f64 100644 --- a/Documentation/gitk.txt +++ b/Documentation/gitk.txt @@ -37,6 +37,10 @@ frequently used options. Show commits older than a specific date. +--all:: + + Show all branches. + :: Limit the revisions to show. This can be either a single revision @@ -63,6 +67,11 @@ gitk --since="2 weeks ago" \-- gitk:: The "--" is necessary to avoid confusion with the *branch* named 'gitk' +gitk --max-count=100 --all -- Makefile:: + + Show at most 100 changes made to the file 'Makefile'. Instead of only + looking for changes in the current branch look in all branches. + See Also -------- 'qgit(1)':: From cd90e75ff4a9b01a9cf59505d8d10d79fd1071ca Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Wed, 20 Sep 2006 00:49:51 +0200 Subject: [PATCH 05/10] gitweb: Even more support for PATH_INFO based URLs Now the following types of path based URLs are supported: * project overview (summary) page of project * project/branch shortlog of branch * project/branch:file file in branch, blob_plain view * project/branch:dir/ directory listing of dir in branch, tree view The following shortcuts works (see explanation below): * project/branch: directory listing of branch, main tree view * project/:file file in HEAD (raw) * project/:dir/ directory listing of dir in HEAD * project/: directory listing of project's HEAD We use ':' as separator between branch (ref) name and file name (pathname) because valid branch (ref) name cannot have ':' inside. This limit applies to branch name only. This allow for hierarchical branches e.g. topic branch 'topic/subtopic', separate remotes tracking branches e.g. 'refs/remotes/origin/HEAD', and discriminate between head (branch) and tag with the same name. Empty branch should be interpreted as HEAD. If pathname (the part after ':') ends with '/', we assume that pathname is name of directory, and we want to show contents of said directory using "tree" view. If pathname is empty, it is equivalent to '/' (top directory). If pathname (the part after ':') does not end with '/', we assume that pathname is name of file, and we show contents of said file using "blob_plain" view. Pathname is stripped of leading '/', so we can use ':/' to separate branch from pathname. The rationale behind support for PATH_INFO based URLs was to support project web pages for small projects: just create an html branch and then use an URL like http://nowhere.com/gitweb.cgi/project.git/html:/index.html The ':/' syntax allow for working links between .html files served in such way, e.g. link inside "index.html" would get http://nowhere.com/gitweb.cgi/project.git/html:/main.html. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 969c2de951..5f597f71e0 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -274,13 +274,16 @@ sub evaluate_path_info { return if defined $project; my $path_info = $ENV{"PATH_INFO"}; return if !$path_info; - $path_info =~ s,(^/|/$),,gs; - $path_info = validate_input($path_info); + $path_info =~ s,^/+,,; return if !$path_info; + # find which part of PATH_INFO is project $project = $path_info; + $project =~ s,/+$,,; while ($project && !-e "$projectroot/$project/HEAD") { $project =~ s,/*[^/]*$,,; } + # validate project + $project = validate_input($project); if (!$project || ($export_ok && !-e "$projectroot/$project/$export_ok") || ($strict_export && !project_in_list($project))) { @@ -289,15 +292,23 @@ sub evaluate_path_info { } # do not change any parameters if an action is given using the query string return if $action; - if ($path_info =~ m,^$project/([^/]+)/(.+)$,) { - # we got "project.git/branch/filename" - $action ||= "blob_plain"; - $hash_base ||= validate_input($1); - $file_name ||= validate_input($2); - } elsif ($path_info =~ m,^$project/([^/]+)$,) { + $path_info =~ s,^$project/*,,; + my ($refname, $pathname) = split(/:/, $path_info, 2); + if (defined $pathname) { + # we got "project.git/branch:filename" or "project.git/branch:dir/" + # we could use git_get_type(branch:pathname), but it needs $git_dir + $pathname =~ s,^/+,,; + if (!$pathname || substr($pathname, -1) eq "/") { + $action ||= "tree"; + } else { + $action ||= "blob_plain"; + } + $hash_base ||= validate_input($refname); + $file_name ||= validate_input($pathname); + } elsif (defined $refname) { # we got "project.git/branch" $action ||= "shortlog"; - $hash ||= validate_input($1); + $hash ||= validate_input($refname); } } evaluate_path_info(); From d04d3d424b913332f5c400162f0d87faac1ad3ea Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Tue, 19 Sep 2006 21:53:22 +0200 Subject: [PATCH 06/10] gitweb: Require project for almost all actions Require that project (repository) is given for all actions except project_list, project_index and opml. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 5f597f71e0..7fd2e19446 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -352,6 +352,10 @@ if (defined $project) { if (!defined($actions{$action})) { die_error(undef, "Unknown action"); } +if ($action !~ m/^(opml|project_list|project_index)$/ && + !$project) { + die_error(undef, "Project needed"); +} $actions{$action}->(); exit; From 9704d75ddc3e38f4945e23f5afffb849fb51b09f Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Tue, 19 Sep 2006 14:31:49 +0200 Subject: [PATCH 07/10] gitweb: Always use git-peek-remote in git_get_references Instead of trying to read info/refs file, which might not be present (we did fallback to git-ls-remote), always use git-peek-remote in git_get_references. It is preparation for git_get_refs_info to also return references info. We should not use info/refs for git_get_refs_info as the repository is not served for http-fetch clients. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 7fd2e19446..532bd0064f 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -843,16 +843,10 @@ 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^{} - if (-f "$projectroot/$project/info/refs") { - open $fd, "$projectroot/$project/info/refs" - or return; - } else { - open $fd, "-|", git_cmd(), "ls-remote", "." - or return; - } + open my $fd, "-|", $GIT, "peek-remote", "$projectroot/$project/" + or return; while (my $line = <$fd>) { chomp $line; From 120ddde2a843e923944abd5d6e61f8625e820e92 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Tue, 19 Sep 2006 14:33:22 +0200 Subject: [PATCH 08/10] gitweb: Make git_get_refs_list do work of git_get_references Make git_get_refs_list do also work of git_get_references, to avoid calling git-peek-remote twice. Change meaning of git_get_refs_list meaning: it is now type, and not a full path, e.g. we now use git_get_refs_list("heads") instead of former git_get_refs_list("refs/heads"). Modify git_summary to use only one call to git_get_refs_list instead of one call to git_get_references and two to git_get_refs_list. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 66 +++++++++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 24 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 532bd0064f..0d13b3388f 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -1134,7 +1134,8 @@ sub parse_ls_tree_line ($;%) { ## parse to array of hashes functions sub git_get_refs_list { - my $ref_dir = shift; + my $type = shift || ""; + my %refs; my @reflist; my @refs; @@ -1142,14 +1143,21 @@ sub git_get_refs_list { or return; while (my $line = <$fd>) { chomp $line; - if ($line =~ m/^([0-9a-fA-F]{40})\t$ref_dir\/?([^\^]+)$/) { - push @refs, { hash => $1, name => $2 }; - } elsif ($line =~ m/^[0-9a-fA-F]{40}\t$ref_dir\/?(.*)\^\{\}$/ && - $1 eq $refs[-1]{'name'}) { - # most likely a tag is followed by its peeled - # (deref) one, and when that happens we know the - # previous one was of type 'tag'. - $refs[-1]{'type'} = "tag"; + if ($line =~ m/^([0-9a-fA-F]{40})\trefs\/($type\/?([^\^]+))(\^\{\})?$/) { + if (defined $refs{$1}) { + push @{$refs{$1}}, $2; + } else { + $refs{$1} = [ $2 ]; + } + + if (! $4) { # unpeeled, direct reference + push @refs, { hash => $1, name => $3 }; # without type + } elsif ($3 eq $refs[-1]{'name'}) { + # most likely a tag is followed by its peeled + # (deref) one, and when that happens we know the + # previous one was of type 'tag'. + $refs[-1]{'type'} = "tag"; + } } } close $fd; @@ -1165,7 +1173,7 @@ sub git_get_refs_list { } # sort refs by age @reflist = sort {$b->{'epoch'} <=> $a->{'epoch'}} @reflist; - return \@reflist; + return (\@reflist, \%refs); } ## ---------------------------------------------------------------------- @@ -2129,14 +2137,14 @@ sub git_tags_body { sub git_heads_body { # uses global variable $project - my ($taglist, $head, $from, $to, $extra) = @_; + my ($headlist, $head, $from, $to, $extra) = @_; $from = 0 unless defined $from; - $to = $#{$taglist} if (!defined $to || $#{$taglist} < $to); + $to = $#{$headlist} if (!defined $to || $#{$headlist} < $to); print "\n"; my $alternate = 0; for (my $i = $from; $i <= $to; $i++) { - my $entry = $taglist->[$i]; + my $entry = $headlist->[$i]; my %tag = %$entry; my $curr = $tag{'id'} eq $head; if ($alternate) { @@ -2306,7 +2314,19 @@ sub git_summary { my $owner = git_get_project_owner($project); - my $refs = git_get_references(); + my ($reflist, $refs) = git_get_refs_list(); + + my @taglist; + my @headlist; + foreach my $ref (@$reflist) { + if ($ref->{'name'} =~ s!^heads/!!) { + push @headlist, $ref; + } else { + $ref->{'name'} =~ s!^tags/!!; + push @taglist, $ref; + } + } + git_header_html(); git_print_page_nav('summary','', $head); @@ -2336,17 +2356,15 @@ sub git_summary { git_shortlog_body(\@revlist, 0, 15, $refs, $cgi->a({-href => href(action=>"shortlog")}, "...")); - my $taglist = git_get_refs_list("refs/tags"); - if (defined @$taglist) { + if (@taglist) { git_print_header_div('tags'); - git_tags_body($taglist, 0, 15, + git_tags_body(\@taglist, 0, 15, $cgi->a({-href => href(action=>"tags")}, "...")); } - my $headlist = git_get_refs_list("refs/heads"); - if (defined @$headlist) { + if (@headlist) { git_print_header_div('heads'); - git_heads_body($headlist, $head, 0, 15, + git_heads_body(\@headlist, $head, 0, 15, $cgi->a({-href => href(action=>"heads")}, "...")); } @@ -2557,7 +2575,7 @@ sub git_tags { git_print_page_nav('','', $head,undef,$head); git_print_header_div('summary', $project); - my $taglist = git_get_refs_list("refs/tags"); + my ($taglist) = git_get_refs_list("tags"); if (defined @$taglist) { git_tags_body($taglist); } @@ -2570,9 +2588,9 @@ sub git_heads { git_print_page_nav('','', $head,undef,$head); git_print_header_div('summary', $project); - my $taglist = git_get_refs_list("refs/heads"); - if (defined @$taglist) { - git_heads_body($taglist, $head); + my ($headlist) = git_get_refs_list("heads"); + if (defined @$headlist) { + git_heads_body($headlist, $head); } git_footer_html(); } From 62e27f273d66afa996cb7aee6cdb25fbedc053f6 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Tue, 19 Sep 2006 20:47:27 +0200 Subject: [PATCH 09/10] gitweb: Fix thinko in git_tags and git_heads git_get_refs_list always return reference to list (and reference to hash which we ignore), so $taglist (in git_tags) and $headlist (in git_heads) are always defined, but @$taglist / @$headlist might be empty. Replaced incorrect "if (defined @$taglist)" with "if (@$taglist)" in git_tags and respectively in git_heads. 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 0d13b3388f..baadbe7512 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -2576,7 +2576,7 @@ sub git_tags { git_print_header_div('summary', $project); my ($taglist) = git_get_refs_list("tags"); - if (defined @$taglist) { + if (@$taglist) { git_tags_body($taglist); } git_footer_html(); @@ -2589,7 +2589,7 @@ sub git_heads { git_print_header_div('summary', $project); my ($headlist) = git_get_refs_list("heads"); - if (defined @$headlist) { + if (@$headlist) { git_heads_body($headlist, $head); } git_footer_html(); From cd0d74d2f9c7578b36e705dda55f79731dbe9696 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 18 Sep 2006 02:29:01 -0700 Subject: [PATCH 10/10] repack: use only pack-objects, not rev-list. Signed-off-by: Junio C Hamano --- git-repack.sh | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/git-repack.sh b/git-repack.sh index b525fc5dfd..9ae5092208 100755 --- a/git-repack.sh +++ b/git-repack.sh @@ -32,12 +32,10 @@ trap 'rm -f "$PACKTMP"-*' 0 1 2 3 15 # There will be more repacking strategies to come... case ",$all_into_one," in ,,) - rev_list='--unpacked' - pack_objects='--incremental' + args='--unpacked --incremental' ;; ,t,) - rev_list= - pack_objects= + args= # Redundancy check in all-into-one case is trivial. existing=`test -d "$PACKDIR" && cd "$PACKDIR" && \ @@ -45,11 +43,8 @@ case ",$all_into_one," in ;; esac -pack_objects="$pack_objects $local $quiet $no_reuse_delta$extra" -name=$( { git-rev-list --objects --all $rev_list || - echo "git-rev-list died with exit code $?" - } | - git-pack-objects --non-empty $pack_objects "$PACKTMP") || +args="$args $local $quiet $no_reuse_delta$extra" +name=$(git-pack-objects --non-empty --all $args