* Re: recur status on linux-2.6
From: Fredrik Kuivinen @ 2006-08-19 10:46 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git
In-Reply-To: <Pine.LNX.4.63.0608131550290.10541@wbgn013.biozentrum.uni-wuerzburg.de>
On Sun, Aug 13, 2006 at 03:54:19PM +0200, Johannes Schindelin wrote:
> Hi,
>
> I tested git-merge-recur vs. git-merge-recursive on the linux-2.6
> repository last night. It contains 2298 two-head merges. _All_ of them
> come out identically with -recur as compared to -recursive (looking at
> the resulting index only).
After the latest updates to git-merge-recur it passes all the tests I
have too.
> That was the good news. The bad news is: it _seems_, that -recur is only
> about 6x faster than -recursive, not 10x, and this number becomes smaller,
> the longer the merge takes. So I see a startup effect here, probably.
That is a quite nice improvement anyway :)
- Fredrik
^ permalink raw reply
* Re: [PATCH] gitweb: Support for snapshot
From: Junio C Hamano @ 2006-08-19 10:51 UTC (permalink / raw)
To: Aneesh Kumar; +Cc: Luben Tuikov, git, jakub narebski
In-Reply-To: <cc723f590608190110t68e6de8etbf6b5b002fd83ca1@mail.gmail.com>
What I had in mind is more like this.
* The global hash %feature defines optional features that site
administrator can enable (or allow repo-owners to enable).
The hash is keyed with feature name.
* The value of the hash is an array whose first two elements
are a sub and a bool, and the rest of the elements are the
default values of feature specific parameters.
* The bool tells gitweb_check_feature if the feature is
overridable per repository, and the sub is called with the
rest of elements in the array only when it is overridable.
The sub should read from the repository config and if the
values are satisfactory return them; otherwise it should
throw back the default parameters.
* When you want to know if a feature with enabled (and with
what option), you call gitweb_check_feature with the feature
name. It will return either the default parameters for the
feature, or the parameters overridden by the repository.
In the example, I do not allow overriding the setting of
'blame', so calling gitweb_check_feature('blame') would always
return 0 (because the third element of the feature array is that
value).
If you want to allow repositories to override, you put true
value as the second member; then repositories that define their
own gitweb.blame can override the default.
The patch demonstrates the use of overridable configuration;
gitweb.snapshot can be left undefined (to get site-wide
default), or defined to be 'none' (to disable it for the
repository even when site-wide default allows it), or 'gzip', or
'bzip2'.
While I was at it, I got rid of git_get_project_config_bool()
which was poorly designed. It did not understand various ways
you can spell true and false, and did not distinguish between
defining a variable to false and not having any definition for
the variable.
I did this patch as a demonstration of the overall framework, so
minor details of feature_xxx implementation might be wrong.
Obviously patch is not tested.
But personally, this patch makes things a bit easier to read
(but I am biased -- I wrote it).
---
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index f8d1036..af8867e 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -67,6 +67,51 @@ # file to use for guessing MIME types be
# (relative to the current git repository)
our $mimetypes_file = undef;
+################################################################
+# Feature configuration.
+# These subs are only called when per repository
+# overrides are allowed. They take the default options,
+# inspect the repository and return the values from there if
+# the repository wants to override the system default.
+
+sub feature_blame {
+ my ($val) = git_get_project_config('blame', '--bool');
+ if ($val eq 'true') { return 1; }
+ elsif ($val eq 'false') { return 0; }
+
+ return $_[0];
+}
+
+sub feature_snapshot {
+ my ($ctype, $suffix, $command) = @_;
+ my ($val) = git_get_project_config('snapshot');
+ if ($val eq 'gzip') { return ('gzip', 'gz'); }
+ elsif ($val eq 'bzip2') { return ('bzip2', 'bz2'); }
+ elsif ($val eq 'none') { return (); }
+
+ return ($ctype, $suffix, $command);
+}
+
+# You define site-wide feature defaults here; override them with
+# $GITWEB_CONFIG as necessary.
+our %feature =
+(
+ # feature => [feature-sub, allow-override, default options...]
+
+ 'blame' => [\&feature_blame, 0, 0],
+ 'snapshot' => [\&feature_snapshot, 0, 'x-gzip', 'gz', 'gzip'],
+);
+
+sub gitweb_check_feature {
+ my ($name) = @_;
+ return undef unless exists $feature{$name};
+ my ($sub, $override, @defaults) = @{$feature{$name}};
+ if (!$override) { return @defaults; }
+ return $sub->(@defaults);
+}
+
+################################################################
+
our $GITWEB_CONFIG = $ENV{'GITWEB_CONFIG'} || "++GITWEB_CONFIG++";
require $GITWEB_CONFIG if -e $GITWEB_CONFIG;
@@ -485,24 +530,19 @@ sub git_get_type {
}
sub git_get_project_config {
- my $key = shift;
+ my ($key, $type) = @_;
return unless ($key);
$key =~ s/^gitweb\.//;
return if ($key =~ m/\W/);
- my $val = qx($GIT repo-config --get gitweb.$key);
+ my @x = ($GIT, 'repo-config', '--get');
+ if (defined $type) { push @x, $type; }
+ push @x, "gitweb.$key";
+ my $val = qx(@x);
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;
@@ -1397,7 +1437,10 @@ sub git_difftree_body {
sub git_shortlog_body {
# uses global variable $project
my ($revlist, $from, $to, $refs, $extra) = @_;
- my $have_snapshot = git_get_project_config_bool('snapshot');
+
+ my ($ctype, $suffix, $command) = gitweb_check_feature('snapshot');
+ my $have_snapshot = (defined $ctype && defined $suffix);
+
$from = 0 unless defined $from;
$to = $#{$revlist} if (!defined $to || $#{$revlist} < $to);
@@ -1858,7 +1901,10 @@ sub git_tag {
sub git_blame2 {
my $fd;
my $ftype;
- die_error(undef, "Permission denied") if (!git_get_project_config_bool ('blame'));
+
+ if (!gitweb_check_feature('blame')) {
+ die_error(undef, "Permission denied");
+ }
die_error('404 Not Found', "File name not defined") if (!$file_name);
$hash_base ||= git_get_head_hash($project);
die_error(undef, "Couldn't find base commit") unless ($hash_base);
@@ -1916,7 +1962,10 @@ sub git_blame2 {
sub git_blame {
my $fd;
- die_error('403 Permission denied', "Permission denied") if (!git_get_project_config_bool ('blame'));
+
+ if (!gitweb_check_feature('blame')) {
+ die_error(undef, "Permission denied");
+ }
die_error('404 Not Found', "File name not defined") if (!$file_name);
$hash_base ||= git_get_head_hash($project);
die_error(undef, "Couldn't find base commit") unless ($hash_base);
@@ -2195,25 +2244,31 @@ sub git_tree {
sub git_snapshot {
+ my ($ctype, $suffix, $command) = gitweb_check_feature('snapshot');
+ my $have_snapshot = (defined $ctype && defined $suffix);
+ if (!$have_snapshot) {
+ die_error(undef, "Permission denied");
+ }
+
if (!defined $hash) {
$hash = git_get_head_hash($project);
}
- my $filename = basename($project) . "-$hash.tar.gz";
+ my $filename = basename($project) . "-$hash.tar.$suffix";
print $cgi->header(-type => 'application/x-tar',
- -content-encoding => 'x-gzip',
- '-content-disposition' => "inline; filename=\"$filename\"",
- -status => '200 OK');
+ -content-encoding => $ctype,
+ '-content-disposition' =>
+ "inline; filename=\"$filename\"",
+ -status => '200 OK');
- open my $fd, "-|", "$GIT tar-tree $hash \'$project\' | gzip" or
- die_error(undef, "Execute git-tar-tree failed.");
+ open my $fd, "-|", "$GIT tar-tree $hash \'$project\' | $command" or
+ die_error(undef, "Execute git-tar-tree failed.");
binmode STDOUT, ':raw';
print <$fd>;
binmode STDOUT, ':utf8'; # as set at the beginning of gitweb.cgi
close $fd;
-
}
sub git_log {
^ permalink raw reply related
* Re: [PATCH] gitweb: use common parameter parsing and generation for "o", too.
From: Jakub Narebski @ 2006-08-19 10:55 UTC (permalink / raw)
To: git
In-Reply-To: <20060818202013.GB30022@admingilde.org>
Martin Waitz wrote:
> Perhaps introduce a new function which is used to access the parameters?
> This new function could check the URL or CGI->param or whatever and then
> return the requested value.
CGI->param. There is no reason to duplicate CGI module.
> Then the action functions could get all parameters they need, validate
> them themselves and then act on them.
> This would suit my "break out parameter parsing from actions" and your
> "validate parameters in the action function".
> (And I really interpret your sentence in such a way that you only want
> to move the _validation_, not the actual parsing (which is done inside
> CGI->param at the moment.)
Validation and accessing. Parsing via CGI->param.
There is another reason I want to move accessing and validation of
parameters to the "action" function (perhaps, as you suggested, via
"wrapper" function), namely removing some global variables. Perhaps it is
unnecessary, but I wonder how well that works with mod_perl. Other global
variables are configuration and do not change form execution to execution
of script...
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply
* Re: git clone dies (large git repository)
From: Jakub Narebski @ 2006-08-19 10:58 UTC (permalink / raw)
To: git
In-Reply-To: <op.teh30gmyies9li@rygel.lnxi.com>
Troy Telford wrote:
> I originally had everything as loose objects. I then ran 'git-repack -d'
> on occasion, so I had a combination of a large pack file, smaller pack
> files, and loose objects. Finally, I tried 'git repack -a -d' and
> consolidated it all into a single 4GB pack file. It didn't seem to make
> much difference in the output.
>
> Am I bumping some sort of limitation within git, or have I uncovered
> a bug?
You _might_ have bumped into filesystem limit on file size, or system limit
on mmap size.
IIRC it was to be addressed (splitting packs into manageable hunks).
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply
* Re: [PATCH] gitweb: Support for snapshot
From: Jakub Narebski @ 2006-08-19 11:09 UTC (permalink / raw)
To: git
In-Reply-To: <7virkp3snv.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano wrote:
> +sub feature_snapshot {
> + my ($ctype, $suffix, $command) = @_;
> + my ($val) = git_get_project_config('snapshot');
> + if ($val eq 'gzip') { return ('gzip', 'gz'); }
> + elsif ($val eq 'bzip2') { return ('bzip2', 'bz2'); }
> + elsif ($val eq 'none') { return (); }
> +
> + return ($ctype, $suffix, $command);
> +}
Should it be ('x-gzip', 'gzip', 'gz') and ('x-bzip2', 'bzip2', 'bz2'),
i.e. with $ctype first?
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply
* Re: [PATCH] gitweb: Support for snapshot
From: Jakub Narebski @ 2006-08-19 11:13 UTC (permalink / raw)
To: git
In-Reply-To: <7virkp3snv.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano wrote:
> * The value of the hash is an array whose first two elements
> are a sub and a bool, and the rest of the elements are the
> default values of feature specific parameters.
Which means that it is not that easy to change defaults from
$GITWEB_CONFIG ($feature{'blame'}->[1] = 1; ?).
And there is no way to enable for example 'blame' support for all
repositories...
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply
* Re: [PATCH] gitweb: Support for snapshot
From: Aneesh Kumar K.V @ 2006-08-19 11:58 UTC (permalink / raw)
To: git
In-Reply-To: <ec6rol$dbe$1@sea.gmane.org>
Jakub Narebski wrote:
> Junio C Hamano wrote:
>
>> * The value of the hash is an array whose first two elements
>> are a sub and a bool, and the rest of the elements are the
>> default values of feature specific parameters.
>
> Which means that it is not that easy to change defaults from
> $GITWEB_CONFIG ($feature{'blame'}->[1] = 1; ?).
>
how about
'blame' => [\&feature_blame, $feature_blame_override, 0],
and picking only $feature_blame_override from $GITWEB_CONFIG
-aneesh
^ permalink raw reply
* [PATCH] Added support for dropping privileges to git-daemon.
From: Tilman Sauerbeck @ 2006-08-19 12:27 UTC (permalink / raw)
To: git
Signed-off-by: Tilman Sauerbeck <tilman@code-monkey.de>
---
I'm not sure how useful this is. I'd like to start git-daemon as root,
so it can store it's PID in /var/run, but I don't want it to keep root
privileges. My git repos are world readable, so for serving them, root
privileges aren't needed at all.
What do you think?
Documentation/git-daemon.txt | 8 +++++++-
daemon.c | 39 ++++++++++++++++++++++++++++++++++++++-
2 files changed, 45 insertions(+), 2 deletions(-)
diff --git a/Documentation/git-daemon.txt b/Documentation/git-daemon.txt
index 0f7d274..a8d75d9 100644
--- a/Documentation/git-daemon.txt
+++ b/Documentation/git-daemon.txt
@@ -11,7 +11,8 @@ SYNOPSIS
'git-daemon' [--verbose] [--syslog] [--inetd | --port=n] [--export-all]
[--timeout=n] [--init-timeout=n] [--strict-paths]
[--base-path=path] [--user-path | --user-path=path]
- [--reuseaddr] [--detach] [--pid-file=file] [directory...]
+ [--reuseaddr] [--detach] [--pid-file=file]
+ [--user=u] [--group=g] [directory...]
DESCRIPTION
-----------
@@ -93,6 +94,11 @@ OPTIONS
--pid-file=file::
Save the process id in 'file'.
+--user=u::
+--group=g::
+ If both options are given, `git-daemon` will change it's uid and gid to
+ the ones of 'u' and 'g' before entering the server loop.
+
<directory>::
A directory to add to the whitelist of allowed directories. Unless
--strict-paths is specified this will also include subdirectories
diff --git a/daemon.c b/daemon.c
index 012936f..78658c1 100644
--- a/daemon.c
+++ b/daemon.c
@@ -7,6 +7,8 @@ #include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <syslog.h>
+#include <pwd.h>
+#include <grp.h>
#include "pkt-line.h"
#include "cache.h"
#include "exec_cmd.h"
@@ -14,12 +16,15 @@ #include "exec_cmd.h"
static int log_syslog;
static int verbose;
static int reuseaddr;
+static const char *user;
+static const char *group;
static const char daemon_usage[] =
"git-daemon [--verbose] [--syslog] [--inetd | --port=n] [--export-all]\n"
" [--timeout=n] [--init-timeout=n] [--strict-paths]\n"
" [--base-path=path] [--user-path | --user-path=path]\n"
-" [--reuseaddr] [--detach] [--pid-file=file] [directory...]";
+" [--reuseaddr] [--detach] [--pid-file=file]\n"
+" [--user=u] [--group=g] [directory...]";
/* List of acceptable pathname prefixes */
static char **ok_paths;
@@ -701,6 +706,24 @@ static void store_pid(const char *path)
fclose(f);
}
+static void drop_privileges()
+{
+ struct passwd *p;
+ struct group *g;
+
+ p = getpwnam (user);
+ if (!p)
+ die("user not found - %s", user);
+
+ g = getgrnam (group);
+ if (!g)
+ die("group not found - %s", group);
+
+ if (initgroups (p->pw_name, g->gr_gid) || setgid (g->gr_gid) ||
+ setuid (p->pw_uid))
+ die("cannot drop privileges");
+}
+
static int serve(int port)
{
int socknum, *socklist;
@@ -709,6 +732,9 @@ static int serve(int port)
if (socknum == 0)
die("unable to allocate any listen sockets on port %u", port);
+ if (user && group)
+ drop_privileges();
+
return service_loop(socknum, socklist);
}
@@ -791,6 +817,14 @@ int main(int argc, char **argv)
log_syslog = 1;
continue;
}
+ if (!strncmp(arg, "--user=", 7)) {
+ user = arg + 7;
+ continue;
+ }
+ if (!strncmp(arg, "--group=", 8)) {
+ group = arg + 8;
+ continue;
+ }
if (!strcmp(arg, "--")) {
ok_paths = &argv[i+1];
break;
@@ -802,6 +836,9 @@ int main(int argc, char **argv)
usage(daemon_usage);
}
+ if (!user ^ !group)
+ die("either set both user and group or none of them");
+
if (log_syslog) {
openlog("git-daemon", 0, LOG_DAEMON);
set_die_routine(daemon_die);
--
1.4.2
^ permalink raw reply related
* Re: [PATCH] Added support for dropping privileges to git-daemon.
From: Marco Costalba @ 2006-08-19 13:23 UTC (permalink / raw)
To: Tilman Sauerbeck; +Cc: git
In-Reply-To: <1155990772.6591@hammerfest>
>
> + if (!user ^ !group)
> + die("either set both user and group or none of them");
> +
>
Just a question. Why simply not
if (user ^ group)
^ permalink raw reply
* Re: [PATCH] Added support for dropping privileges to git-daemon.
From: Tilman Sauerbeck @ 2006-08-19 13:29 UTC (permalink / raw)
To: git
In-Reply-To: <e5bfff550608190623j58de8c1cn6a9304249ee1ecb8@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 519 bytes --]
Marco Costalba [2006-08-19 15:23]:
> >
> >+ if (!user ^ !group)
> >+ die("either set both user and group or none of them");
> >+
> >
>
> Just a question. Why simply not
>
> if (user ^ group)
Because gcc doesn't like that:
error: invalid operands to binary ^
Regards,
Tilman
--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: [PATCH] Added support for dropping privileges to git-daemon.
From: Johannes Schindelin @ 2006-08-19 13:32 UTC (permalink / raw)
To: Tilman Sauerbeck; +Cc: git
In-Reply-To: <1155990772.6591@hammerfest>
Hi,
On Sat, 19 Aug 2006, Tilman Sauerbeck wrote:
> What do you think?
I think it is a good addition. Note that most people will probably use
inetd instead, though.
> + [--user=u] [--group=g] [directory...]
Since you enforce both --user and --group, this should read
[--user=u --group=g]
Ciao,
Dscho
^ permalink raw reply
* Re: [PATCH] gitweb: Support for snapshot
From: Aneesh Kumar K.V @ 2006-08-19 13:56 UTC (permalink / raw)
To: git; +Cc: Luben Tuikov, git, jakub narebski
In-Reply-To: <7virkp3snv.fsf@assigned-by-dhcp.cox.net>
[-- Attachment #1: Type: text/plain, Size: 584 bytes --]
Junio C Hamano wrote:
>
> I did this patch as a demonstration of the overall framework, so
> minor details of feature_xxx implementation might be wrong.
> Obviously patch is not tested.
>
> But personally, this patch makes things a bit easier to read
> (but I am biased -- I wrote it).
>
I tested this and added some comments. I also fixed some code. I am attaching the full diff.
BTW git-repo-config have the below bug.
$ git repo-config --bool --get gitweb.blame
true
$ git repo-config --get --bool gitweb.blame
$
So i dropped --get from the git_get_project_config
-aneesh
[-- Attachment #2: gitweb.diff --]
[-- Type: text/x-patch, Size: 6453 bytes --]
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index f8d1036..1037ab9 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -67,6 +67,58 @@ # file to use for guessing MIME types be
# (relative to the current git repository)
our $mimetypes_file = undef;
+# Feature configuration.
+# These subs are only called when per repository
+# overrides are allowed. They take the default options,
+# inspect the repository and return the values from there if
+# the repository wants to override the system default.
+
+# To enable system wide have in $GITWEB_CONFIG
+# $feature{'blame'} = [\&feature_blame, 0, 1];
+# To disbale project wide
+# you should have allow-override enabled in $GITWEB_CONFIG
+# and in project config gitweb.blame = 0;
+sub feature_blame {
+ my ($val) = git_get_project_config('blame', '--bool');
+ if ($val eq 'true') { return 1; }
+ elsif ($val eq 'false') { return 0; }
+
+ return $_[0];
+}
+
+# To disable system wide have in $GITWEB_CONFIG
+# $feature{'snapshot'} = [\&feature_snapshot, 0, undef, undef, undef];
+# To change the encoding type
+# you should have allow-override enabled in $GITWEB_CONFIG
+# and in project config gitweb.snapshot = bzip2
+sub feature_snapshot {
+ my ($ctype, $suffix, $command) = @_;
+ my ($val) = git_get_project_config('snapshot');
+ if ($val eq 'gzip') { return ('x-gzip', 'gz', 'gzip'); }
+ elsif ($val eq 'bzip2') { return ('x-bzip2', 'bz2', 'bzip2'); }
+ elsif ($val eq 'none') { return (); }
+
+ return ($ctype, $suffix, $command);
+}
+
+# You define site-wide feature defaults here; override them with
+# $GITWEB_CONFIG as necessary.
+our %feature =
+(
+ # feature => [feature-sub, allow-override, default options...]
+
+ 'blame' => [\&feature_blame, 0, 0],
+ 'snapshot' => [\&feature_snapshot, 0, 'x-gzip', 'gz', 'gzip'],
+);
+
+sub gitweb_check_feature {
+ my ($name) = @_;
+ return undef unless exists $feature{$name};
+ my ($sub, $override, @defaults) = @{$feature{$name}};
+ if (!$override) { return @defaults; }
+ return $sub->(@defaults);
+}
+
our $GITWEB_CONFIG = $ENV{'GITWEB_CONFIG'} || "++GITWEB_CONFIG++";
require $GITWEB_CONFIG if -e $GITWEB_CONFIG;
@@ -485,24 +537,20 @@ sub git_get_type {
}
sub git_get_project_config {
- my $key = shift;
+ my ($key, $type) = @_;
return unless ($key);
$key =~ s/^gitweb\.//;
return if ($key =~ m/\W/);
- my $val = qx($GIT repo-config --get gitweb.$key);
+ my @x = ($GIT, 'repo-config');
+ if (defined $type) { push @x, $type; }
+ push @x, "gitweb.$key";
+ my $val = qx(@x);
+ chomp $val;
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;
@@ -1397,7 +1445,10 @@ sub git_difftree_body {
sub git_shortlog_body {
# uses global variable $project
my ($revlist, $from, $to, $refs, $extra) = @_;
- my $have_snapshot = git_get_project_config_bool('snapshot');
+
+ my ($ctype, $suffix, $command) = gitweb_check_feature('snapshot');
+ my $have_snapshot = (defined $ctype && defined $suffix);
+
$from = 0 unless defined $from;
$to = $#{$revlist} if (!defined $to || $#{$revlist} < $to);
@@ -1858,7 +1909,10 @@ sub git_tag {
sub git_blame2 {
my $fd;
my $ftype;
- die_error(undef, "Permission denied") if (!git_get_project_config_bool ('blame'));
+
+ if (!gitweb_check_feature('blame')) {
+ die_error(undef, "Permission denied");
+ }
die_error('404 Not Found', "File name not defined") if (!$file_name);
$hash_base ||= git_get_head_hash($project);
die_error(undef, "Couldn't find base commit") unless ($hash_base);
@@ -1916,7 +1970,10 @@ sub git_blame2 {
sub git_blame {
my $fd;
- die_error('403 Permission denied', "Permission denied") if (!git_get_project_config_bool ('blame'));
+
+ if (!gitweb_check_feature('blame')) {
+ die_error(undef, "Permission denied");
+ }
die_error('404 Not Found', "File name not defined") if (!$file_name);
$hash_base ||= git_get_head_hash($project);
die_error(undef, "Couldn't find base commit") unless ($hash_base);
@@ -2069,7 +2126,7 @@ sub git_blob {
die_error(undef, "No file name defined");
}
}
- my $have_blame = git_get_project_config_bool ('blame');
+ my $have_blame = gitweb_check_feature('blame');
open my $fd, "-|", $GIT, "cat-file", "blob", $hash
or die_error(undef, "Couldn't cat $file_name, $hash");
my $mimetype = blob_mimetype($fd, $file_name);
@@ -2134,7 +2191,7 @@ sub git_tree {
git_header_html();
my %base_key = ();
my $base = "";
- my $have_blame = git_get_project_config_bool ('blame');
+ my $have_blame = gitweb_check_feature('blame');
if (defined $hash_base && (my %co = parse_commit($hash_base))) {
$base_key{hash_base} = $hash_base;
git_print_page_nav('tree','', $hash_base);
@@ -2195,25 +2252,31 @@ sub git_tree {
sub git_snapshot {
+ my ($ctype, $suffix, $command) = gitweb_check_feature('snapshot');
+ my $have_snapshot = (defined $ctype && defined $suffix);
+ if (!$have_snapshot) {
+ die_error(undef, "Permission denied");
+ }
+
if (!defined $hash) {
$hash = git_get_head_hash($project);
}
- my $filename = basename($project) . "-$hash.tar.gz";
+ my $filename = basename($project) . "-$hash.tar.$suffix";
print $cgi->header(-type => 'application/x-tar',
- -content-encoding => 'x-gzip',
- '-content-disposition' => "inline; filename=\"$filename\"",
- -status => '200 OK');
+ -content-encoding => $ctype,
+ '-content-disposition' =>
+ "inline; filename=\"$filename\"",
+ -status => '200 OK');
- open my $fd, "-|", "$GIT tar-tree $hash \'$project\' | gzip" or
- die_error(undef, "Execute git-tar-tree failed.");
+ open my $fd, "-|", "$GIT tar-tree $hash \'$project\' | $command" or
+ die_error(undef, "Execute git-tar-tree failed.");
binmode STDOUT, ':raw';
print <$fd>;
binmode STDOUT, ':utf8'; # as set at the beginning of gitweb.cgi
close $fd;
-
}
sub git_log {
@@ -2293,7 +2356,10 @@ sub git_commit {
}
my $refs = git_get_references();
my $ref = format_ref_marker($refs, $co{'id'});
- my $have_snapshot = git_get_project_config_bool('snapshot');
+
+ my ($ctype, $suffix, $command) = gitweb_check_feature('snapshot');
+ my $have_snapshot = (defined $ctype && defined $suffix);
+
my $formats_nav = '';
if (defined $file_name && defined $co{'parent'}) {
my $parent = $co{'parent'};
^ permalink raw reply related
* Re: [PATCH] gitweb: Support for snapshot
From: Jakub Narebski @ 2006-08-19 14:22 UTC (permalink / raw)
To: git
In-Reply-To: <44E71888.30104@gmail.com>
Aneesh Kumar K.V wrote:
> I tested this and added some comments. I also fixed some code.
> I am attaching the full diff.
Below comments to the patch.
> BTW git-repo-config have the below bug.
>
> $ git repo-config --bool --get gitweb.blame
> true
> $ git repo-config --get --bool gitweb.blame
> $
>
> So i dropped --get from the git_get_project_config
Wouldn't it be better to correct the error in git-repo-config?
Or (easier) add '--get' last (see comments)?
> +# Feature configuration.
Wouldn't it make it easier to understand code to put %feature hash
and gitweb_check_feature subroutine _before_ subroutines for specific
features?
> +# These subs are only called when per repository
> +# overrides are allowed. They take the default options,
> +# inspect the repository and return the values from there if
> +# the repository wants to override the system default.
> +
> +# To enable system wide have in $GITWEB_CONFIG
> +# $feature{'blame'} = [\&feature_blame, 0, 1];
This enables system wide, but also disables per-project override.
To enable system wide, while allowing for per project disabling
it should read
# $feature{'blame'} = [\&feature_blame, 1, 1]; # overridable, enabled by default
> +# To disbale project wide
Typo. disbale -> disable.
> +# you should have allow-override enabled in $GITWEB_CONFIG
Example:
# $feature{'blame'} = [\&feature_blame, 1, 1]; # overridable, enabled by default
or just
$feature{'blame'}->[1] = 1;
(See below for comments on that form)
> +# and in project config gitweb.blame = 0;
Example:
# $ git repo-config --bool gitweb.blame false
> +# To disable system wide have in $GITWEB_CONFIG
> +# $feature{'snapshot'} = [\&feature_snapshot, 0, undef, undef, undef];
It would be enough to put:
$feature{'snapshot'} = [\&feature_snapshot, 0, undef];
> +# You define site-wide feature defaults here; override them with
> +# $GITWEB_CONFIG as necessary.
> +our %feature =
> +(
> + # feature => [feature-sub, allow-override, default options...]
> +
> + 'blame' => [\&feature_blame, 0, 0],
> + 'snapshot' => [\&feature_snapshot, 0, 'x-gzip', 'gz', 'gzip'],
> +);
By the way, wouldn't it be better to use _hash_ for mixed meaning
than _array_? I.e.
our %feature =
(
# feature => {'sub' => feature-sub, 'override' => allow-override, 'default' => default options...]
'blame' => {'sub' => \&feature_blame, 'override' => 0, 'default' => 0},
#or 'blame' => {'sub' => \&feature_blame, 'override' => 0, 'default' => [ 0 ]},
'snapshot' => {'sub' => \&feature_snapshot, 'override' => 0, 'default => [ 'x-gzip', 'gz', 'gzip' ]},
);
Then you could enable override, or change default simplier in
$GITWEB_CONFIG, e.g. $feature{'blame'}{'override'} = 1; instead
of $feature{'blame'}[1] = 1;
By the way, it has more sense to have feature by default
(i.e. in gitweb.perl) with override enabled if it is set to on.
> sub git_get_project_config {
[...]
> - my $val = qx($GIT repo-config --get gitweb.$key);
> + my @x = ($GIT, 'repo-config');
> + if (defined $type) { push @x, $type; }
Just add '--get' as the last argument, _after_ type:
+ push @x, '--get';
> + push @x, "gitweb.$key";
> + my $val = qx(@x);
> + chomp $val;
> return ($val);
> }
> - die_error('403 Permission denied', "Permission denied") if (!git_get_project_config_bool ('blame'));
> +
> + if (!gitweb_check_feature('blame')) {
> + die_error(undef, "Permission denied");
> + }
Why did you drop '403 Permission denied' HTTP return code from call
to die_error? (And not set in other similar cases)?
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply
* [PATCH] builtin-mv: readability patch
From: Johannes Schindelin @ 2006-08-19 14:52 UTC (permalink / raw)
To: git, junkio
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 <Johannes.Schindelin@gmx.de>
---
builtin-mv.c | 104 +++++++++++++++++++++++++---------------------------------
1 files changed, 44 insertions(+), 60 deletions(-)
diff --git a/builtin-mv.c b/builtin-mv.c
index c0c8764..1fdb0c7 100644
--- a/builtin-mv.c
+++ b/builtin-mv.c
@@ -126,48 +126,43 @@ int cmd_mv(int argc, const char **argv,
/* 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,
* 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,
" 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));
-
- if (modes[i] == WORKING_DIRECTORY)
+ 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 (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) {
--
1.4.2.gd3f3-dirty
^ permalink raw reply related
* Re: [PATCH] Added support for dropping privileges to git-daemon.
From: Marco Costalba @ 2006-08-19 15:19 UTC (permalink / raw)
To: git
In-Reply-To: <20060819132922.GA6644@code-monkey.de>
On 8/19/06, Tilman Sauerbeck <tilman@code-monkey.de> wrote:
> Marco Costalba [2006-08-19 15:23]:
> > >
> > >+ if (!user ^ !group)
> > >+ die("either set both user and group or none of them");
> > >+
> > >
> >
> > Just a question. Why simply not
> >
> > if (user ^ group)
>
> Because gcc doesn't like that:
> error: invalid operands to binary ^
>
Interesting!
Indeed gcc it's right, operator ^ it's a bitwise operator, not a
logical one. So operands must be booleans (or numerical types in case
of C).
The trick is that operator '!' performs an implicit conversion to
integral on the 'user' and 'group' pointers.
BTW the following (very ugly) works.
if ((int)user ^ (int)group)
^ permalink raw reply
* Re: [PATCH] Added support for dropping privileges to git-daemon.
From: Marco Costalba @ 2006-08-19 15:22 UTC (permalink / raw)
To: git
In-Reply-To: <e5bfff550608190819i3cade548g28b2c95fab172a49@mail.gmail.com>
> logical one. So operands must be booleans (or numerical types in case
> of C).
Operands must be numerical types of course, not booleans!!
^ permalink raw reply
* Re: [PATCH] gitweb: Support for snapshot
From: Aneesh Kumar K.V @ 2006-08-19 16:17 UTC (permalink / raw)
To: git
In-Reply-To: <ec76rd$8qf$1@sea.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 274 bytes --]
Jakub Narebski wrote:
> Aneesh Kumar K.V wrote:
>
>> I tested this and added some comments. I also fixed some code.
>> I am attaching the full diff.
>
> Below comments to the patch.
>
updated patch attached. I guess i have taken care of all your comments.
-aneesh
[-- Attachment #2: gitweb.diff --]
[-- Type: text/x-patch, Size: 6518 bytes --]
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index f8d1036..e8a4a6f 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -67,6 +67,68 @@ # file to use for guessing MIME types be
# (relative to the current git repository)
our $mimetypes_file = undef;
+# You define site-wide feature defaults here; override them with
+# $GITWEB_CONFIG as necessary.
+our %feature =
+(
+
+# feature => {'sub' => feature-sub, 'override' => allow-override, 'default' => [ default options...]
+
+'blame' => {'sub' => \&feature_blame, 'override' => 0, 'default' => [0]},
+'snapshot' => {'sub' => \&feature_snapshot, 'override' => 0, 'default' => ['x-gzip', 'gz', 'gzip']},
+
+);
+
+sub gitweb_check_feature {
+ my ($name) = @_;
+ return undef unless exists $feature{$name};
+ my ($sub, $override, @defaults) = ($feature{$name}{'sub'},
+ $feature{$name}{'override'},
+ @{$feature{$name}{'default'}});
+ if (!$override) { return @defaults; }
+ return $sub->(@defaults);
+}
+
+# To enable system wide have in $GITWEB_CONFIG
+# $feature{'blame'}{'default'} = [0];
+# To have project specific config enable override in $GITWEB_CONFIG
+# $feature{'blame'}{'override'} = 1;
+# and in project config gitweb.blame = 0|1;
+
+sub feature_blame {
+ my ($val) = git_get_project_config('blame', '--bool');
+
+ if ($val eq 'true') {
+ return 1;
+ } elsif ($val eq 'false') {
+ return 0;
+ }
+
+ return $_[0];
+}
+
+# To disable system wide have in $GITWEB_CONFIG
+# $feature{'snapshot'}{'default'} = [undef];
+# To have project specific config enable override in $GITWEB_CONFIG
+# $feature{'blame'}{'override'} = 1;
+# and in project config gitweb.snapshot = no|gzip|bzip2
+
+sub feature_snapshot {
+ my ($ctype, $suffix, $command) = @_;
+
+ my ($val) = git_get_project_config('snapshot');
+
+ if ($val eq 'gzip') {
+ return ('x-gzip', 'gz', 'gzip');
+ } elsif ($val eq 'bzip2') {
+ return ('x-bzip2', 'bz2', 'bzip2');
+ } elsif ($val eq 'none') {
+ return ();
+ }
+
+ return ($ctype, $suffix, $command);
+}
+
our $GITWEB_CONFIG = $ENV{'GITWEB_CONFIG'} || "++GITWEB_CONFIG++";
require $GITWEB_CONFIG if -e $GITWEB_CONFIG;
@@ -485,24 +547,21 @@ sub git_get_type {
}
sub git_get_project_config {
- my $key = shift;
+ my ($key, $type) = @_;
return unless ($key);
$key =~ s/^gitweb\.//;
return if ($key =~ m/\W/);
- my $val = qx($GIT repo-config --get gitweb.$key);
+ my @x = ($GIT, 'repo-config');
+ if (defined $type) { push @x, $type; }
+ push @x, "--get";
+ push @x, "gitweb.$key";
+ my $val = qx(@x);
+ chomp $val;
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;
@@ -1397,7 +1456,10 @@ sub git_difftree_body {
sub git_shortlog_body {
# uses global variable $project
my ($revlist, $from, $to, $refs, $extra) = @_;
- my $have_snapshot = git_get_project_config_bool('snapshot');
+
+ my ($ctype, $suffix, $command) = gitweb_check_feature('snapshot');
+ my $have_snapshot = (defined $ctype && defined $suffix);
+
$from = 0 unless defined $from;
$to = $#{$revlist} if (!defined $to || $#{$revlist} < $to);
@@ -1858,7 +1920,10 @@ sub git_tag {
sub git_blame2 {
my $fd;
my $ftype;
- die_error(undef, "Permission denied") if (!git_get_project_config_bool ('blame'));
+
+ if (!gitweb_check_feature('blame')) {
+ die_error('403 Permission denied', "Permission denied");
+ }
die_error('404 Not Found', "File name not defined") if (!$file_name);
$hash_base ||= git_get_head_hash($project);
die_error(undef, "Couldn't find base commit") unless ($hash_base);
@@ -1916,7 +1981,10 @@ sub git_blame2 {
sub git_blame {
my $fd;
- die_error('403 Permission denied', "Permission denied") if (!git_get_project_config_bool ('blame'));
+
+ if (!gitweb_check_feature('blame')) {
+ die_error('403 Permission denied', "Permission denied");
+ }
die_error('404 Not Found', "File name not defined") if (!$file_name);
$hash_base ||= git_get_head_hash($project);
die_error(undef, "Couldn't find base commit") unless ($hash_base);
@@ -2069,7 +2137,7 @@ sub git_blob {
die_error(undef, "No file name defined");
}
}
- my $have_blame = git_get_project_config_bool ('blame');
+ my $have_blame = gitweb_check_feature('blame');
open my $fd, "-|", $GIT, "cat-file", "blob", $hash
or die_error(undef, "Couldn't cat $file_name, $hash");
my $mimetype = blob_mimetype($fd, $file_name);
@@ -2134,7 +2202,7 @@ sub git_tree {
git_header_html();
my %base_key = ();
my $base = "";
- my $have_blame = git_get_project_config_bool ('blame');
+ my $have_blame = gitweb_check_feature('blame');
if (defined $hash_base && (my %co = parse_commit($hash_base))) {
$base_key{hash_base} = $hash_base;
git_print_page_nav('tree','', $hash_base);
@@ -2195,25 +2263,31 @@ sub git_tree {
sub git_snapshot {
+ my ($ctype, $suffix, $command) = gitweb_check_feature('snapshot');
+ my $have_snapshot = (defined $ctype && defined $suffix);
+ if (!$have_snapshot) {
+ die_error('403 Permission denied', "Permission denied");
+ }
+
if (!defined $hash) {
$hash = git_get_head_hash($project);
}
- my $filename = basename($project) . "-$hash.tar.gz";
+ my $filename = basename($project) . "-$hash.tar.$suffix";
print $cgi->header(-type => 'application/x-tar',
- -content-encoding => 'x-gzip',
- '-content-disposition' => "inline; filename=\"$filename\"",
- -status => '200 OK');
+ -content-encoding => $ctype,
+ '-content-disposition' =>
+ "inline; filename=\"$filename\"",
+ -status => '200 OK');
- open my $fd, "-|", "$GIT tar-tree $hash \'$project\' | gzip" or
- die_error(undef, "Execute git-tar-tree failed.");
+ open my $fd, "-|", "$GIT tar-tree $hash \'$project\' | $command" or
+ die_error(undef, "Execute git-tar-tree failed.");
binmode STDOUT, ':raw';
print <$fd>;
binmode STDOUT, ':utf8'; # as set at the beginning of gitweb.cgi
close $fd;
-
}
sub git_log {
@@ -2293,7 +2367,10 @@ sub git_commit {
}
my $refs = git_get_references();
my $ref = format_ref_marker($refs, $co{'id'});
- my $have_snapshot = git_get_project_config_bool('snapshot');
+
+ my ($ctype, $suffix, $command) = gitweb_check_feature('snapshot');
+ my $have_snapshot = (defined $ctype && defined $suffix);
+
my $formats_nav = '';
if (defined $file_name && defined $co{'parent'}) {
my $parent = $co{'parent'};
^ permalink raw reply related
* Re: [PATCH] gitweb: Support for snapshot
From: Aneesh Kumar K.V @ 2006-08-19 16:26 UTC (permalink / raw)
To: git
In-Reply-To: <ec7dil$vcf$1@sea.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 414 bytes --]
Aneesh Kumar K.V wrote:
> Jakub Narebski wrote:
>> Aneesh Kumar K.V wrote:
>>
>>> I tested this and added some comments. I also fixed some code. I am
>>> attaching the full diff.
>>
>> Below comments to the patch.
>>
>
> updated patch attached. I guess i have taken care of all your comments.
After fixing some comments and adding signed-off
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@gmail.com>
-aneesh
[-- Attachment #2: gitweb.diff --]
[-- Type: text/x-patch, Size: 6520 bytes --]
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index f8d1036..063735d 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -67,6 +67,68 @@ # file to use for guessing MIME types be
# (relative to the current git repository)
our $mimetypes_file = undef;
+# You define site-wide feature defaults here; override them with
+# $GITWEB_CONFIG as necessary.
+our %feature =
+(
+
+# feature => {'sub' => feature-sub, 'override' => allow-override, 'default' => [ default options...]
+
+'blame' => {'sub' => \&feature_blame, 'override' => 0, 'default' => [0]},
+'snapshot' => {'sub' => \&feature_snapshot, 'override' => 0, 'default' => ['x-gzip', 'gz', 'gzip']},
+
+);
+
+sub gitweb_check_feature {
+ my ($name) = @_;
+ return undef unless exists $feature{$name};
+ my ($sub, $override, @defaults) = ($feature{$name}{'sub'},
+ $feature{$name}{'override'},
+ @{$feature{$name}{'default'}});
+ if (!$override) { return @defaults; }
+ return $sub->(@defaults);
+}
+
+# To enable system wide have in $GITWEB_CONFIG
+# $feature{'blame'}{'default'} = [1];
+# To have project specific config enable override in $GITWEB_CONFIG
+# $feature{'blame'}{'override'} = 1;
+# and in project config gitweb.blame = 0|1;
+
+sub feature_blame {
+ my ($val) = git_get_project_config('blame', '--bool');
+
+ if ($val eq 'true') {
+ return 1;
+ } elsif ($val eq 'false') {
+ return 0;
+ }
+
+ return $_[0];
+}
+
+# To disable system wide have in $GITWEB_CONFIG
+# $feature{'snapshot'}{'default'} = [undef];
+# To have project specific config enable override in $GITWEB_CONFIG
+# $feature{'blame'}{'override'} = 1;
+# and in project config gitweb.snapshot = none|gzip|bzip2
+
+sub feature_snapshot {
+ my ($ctype, $suffix, $command) = @_;
+
+ my ($val) = git_get_project_config('snapshot');
+
+ if ($val eq 'gzip') {
+ return ('x-gzip', 'gz', 'gzip');
+ } elsif ($val eq 'bzip2') {
+ return ('x-bzip2', 'bz2', 'bzip2');
+ } elsif ($val eq 'none') {
+ return ();
+ }
+
+ return ($ctype, $suffix, $command);
+}
+
our $GITWEB_CONFIG = $ENV{'GITWEB_CONFIG'} || "++GITWEB_CONFIG++";
require $GITWEB_CONFIG if -e $GITWEB_CONFIG;
@@ -485,24 +547,21 @@ sub git_get_type {
}
sub git_get_project_config {
- my $key = shift;
+ my ($key, $type) = @_;
return unless ($key);
$key =~ s/^gitweb\.//;
return if ($key =~ m/\W/);
- my $val = qx($GIT repo-config --get gitweb.$key);
+ my @x = ($GIT, 'repo-config');
+ if (defined $type) { push @x, $type; }
+ push @x, "--get";
+ push @x, "gitweb.$key";
+ my $val = qx(@x);
+ chomp $val;
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;
@@ -1397,7 +1456,10 @@ sub git_difftree_body {
sub git_shortlog_body {
# uses global variable $project
my ($revlist, $from, $to, $refs, $extra) = @_;
- my $have_snapshot = git_get_project_config_bool('snapshot');
+
+ my ($ctype, $suffix, $command) = gitweb_check_feature('snapshot');
+ my $have_snapshot = (defined $ctype && defined $suffix);
+
$from = 0 unless defined $from;
$to = $#{$revlist} if (!defined $to || $#{$revlist} < $to);
@@ -1858,7 +1920,10 @@ sub git_tag {
sub git_blame2 {
my $fd;
my $ftype;
- die_error(undef, "Permission denied") if (!git_get_project_config_bool ('blame'));
+
+ if (!gitweb_check_feature('blame')) {
+ die_error('403 Permission denied', "Permission denied");
+ }
die_error('404 Not Found', "File name not defined") if (!$file_name);
$hash_base ||= git_get_head_hash($project);
die_error(undef, "Couldn't find base commit") unless ($hash_base);
@@ -1916,7 +1981,10 @@ sub git_blame2 {
sub git_blame {
my $fd;
- die_error('403 Permission denied', "Permission denied") if (!git_get_project_config_bool ('blame'));
+
+ if (!gitweb_check_feature('blame')) {
+ die_error('403 Permission denied', "Permission denied");
+ }
die_error('404 Not Found', "File name not defined") if (!$file_name);
$hash_base ||= git_get_head_hash($project);
die_error(undef, "Couldn't find base commit") unless ($hash_base);
@@ -2069,7 +2137,7 @@ sub git_blob {
die_error(undef, "No file name defined");
}
}
- my $have_blame = git_get_project_config_bool ('blame');
+ my $have_blame = gitweb_check_feature('blame');
open my $fd, "-|", $GIT, "cat-file", "blob", $hash
or die_error(undef, "Couldn't cat $file_name, $hash");
my $mimetype = blob_mimetype($fd, $file_name);
@@ -2134,7 +2202,7 @@ sub git_tree {
git_header_html();
my %base_key = ();
my $base = "";
- my $have_blame = git_get_project_config_bool ('blame');
+ my $have_blame = gitweb_check_feature('blame');
if (defined $hash_base && (my %co = parse_commit($hash_base))) {
$base_key{hash_base} = $hash_base;
git_print_page_nav('tree','', $hash_base);
@@ -2195,25 +2263,31 @@ sub git_tree {
sub git_snapshot {
+ my ($ctype, $suffix, $command) = gitweb_check_feature('snapshot');
+ my $have_snapshot = (defined $ctype && defined $suffix);
+ if (!$have_snapshot) {
+ die_error('403 Permission denied', "Permission denied");
+ }
+
if (!defined $hash) {
$hash = git_get_head_hash($project);
}
- my $filename = basename($project) . "-$hash.tar.gz";
+ my $filename = basename($project) . "-$hash.tar.$suffix";
print $cgi->header(-type => 'application/x-tar',
- -content-encoding => 'x-gzip',
- '-content-disposition' => "inline; filename=\"$filename\"",
- -status => '200 OK');
+ -content-encoding => $ctype,
+ '-content-disposition' =>
+ "inline; filename=\"$filename\"",
+ -status => '200 OK');
- open my $fd, "-|", "$GIT tar-tree $hash \'$project\' | gzip" or
- die_error(undef, "Execute git-tar-tree failed.");
+ open my $fd, "-|", "$GIT tar-tree $hash \'$project\' | $command" or
+ die_error(undef, "Execute git-tar-tree failed.");
binmode STDOUT, ':raw';
print <$fd>;
binmode STDOUT, ':utf8'; # as set at the beginning of gitweb.cgi
close $fd;
-
}
sub git_log {
@@ -2293,7 +2367,10 @@ sub git_commit {
}
my $refs = git_get_references();
my $ref = format_ref_marker($refs, $co{'id'});
- my $have_snapshot = git_get_project_config_bool('snapshot');
+
+ my ($ctype, $suffix, $command) = gitweb_check_feature('snapshot');
+ my $have_snapshot = (defined $ctype && defined $suffix);
+
my $formats_nav = '';
if (defined $file_name && defined $co{'parent'}) {
my $parent = $co{'parent'};
^ permalink raw reply related
* Re: [PATCH] Added support for dropping privileges to git-daemon.
From: Mitchell Blank Jr @ 2006-08-19 17:15 UTC (permalink / raw)
To: Marco Costalba; +Cc: git
In-Reply-To: <e5bfff550608190819i3cade548g28b2c95fab172a49@mail.gmail.com>
Marco Costalba wrote:
> >> >+ if (!user ^ !group)
> >> >+ die("either set both user and group or none of them");
>
> BTW the following (very ugly) works.
>
> if ((int)user ^ (int)group)
No it doesn't. Besides being a dangerous cast (no guarantee that a pointer
will fit in an "int") your code is basically just a fancy way of saying
if (user != group)
Which is definitely NOT what is intended. "user" and "group" are pointers --
unless they're both NULL we expect them to have different values. The
original code is equivalent to:
if ((user == NULL) != (group == NULL))
which is what is actually intended.
-Mitch
^ permalink raw reply
* Re: [PATCH] Added support for dropping privileges to git-daemon.
From: Mitchell Blank Jr @ 2006-08-19 17:25 UTC (permalink / raw)
To: Tilman Sauerbeck; +Cc: git
In-Reply-To: <1155990772.6591@hammerfest>
Tilman Sauerbeck wrote:
> + if (user && group)
> + drop_privileges();
It seems "if (user)" would be sufficient here.
> + if (!user ^ !group)
> + die("either set both user and group or none of them");
For simplicities sake I'd actually suggest allowing group==NULL. So
change this test to be
if (group && !user)
die("--group supplied without --user");
Then in drop_privileges() do something like:
struct passwd *p;
gid_t gid;
p = getpwnam(user);
if (!p)
die("user not found - %s", user);
if (group == NULL)
gid = p->pw_gid;
else {
struct group *g = getgrnam(group);
if (!g)
die("group not found - %s", group);
gid = g->gr_gid;
}
Since usually you want to use the same gid that is normally associated
with that pid, this just makes things a little easier on the user
-Mitch
^ permalink raw reply
* Re: [PATCH] gitweb: use common parameter parsing and generation for "o", too.
From: Martin Waitz @ 2006-08-19 18:33 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
In-Reply-To: <ec6qnp$aal$1@sea.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 567 bytes --]
hoi :)
On Sat, Aug 19, 2006 at 12:55:57PM +0200, Jakub Narebski wrote:
> > Perhaps introduce a new function which is used to access the parameters?
> > This new function could check the URL or CGI->param or whatever and then
> > return the requested value.
>
> CGI->param. There is no reason to duplicate CGI module.
yes there is.
using CGI->param it is not possible to use nice URLs ala
http://git.site.org/projectpath.git
I would really appreciate to be able to use nice URLs in gitweb that
correspond to the repository URL.
--
Martin Waitz
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: Huge win, compressing a window of delta runs as a unit
From: Linus Torvalds @ 2006-08-19 19:25 UTC (permalink / raw)
To: Jon Smirl; +Cc: Johannes Schindelin, Nicolas Pitre, Shawn Pearce, git
In-Reply-To: <9e4733910608180650j4542ab09q7daf4250825d3333@mail.gmail.com>
On Fri, 18 Aug 2006, Jon Smirl wrote:
> On 8/18/06, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> > Hi,
> >
> > On Fri, 18 Aug 2006, Jon Smirl wrote:
> >
> > > I suspect the size reduction is directly proportional to the age of
> > > the repository. The kernel repository only has three years worth of
> > > data in it. Linus has the full history in another repository that is
> > > not in general distribution. We can get it from him when he gets back
> > > from vacation.
> >
> > Maybe you mean
> >
> > http://www.kernel.org/git/gitweb.cgi?p=linux/kernel/git/tglx/history.git
>
> That one only goes to 2002, the full one goes back to around 1990.
I don't actually have such a "full" history. It would be wonderful if
somebody took the time to try to piece such a thing together (and git
actually makes that a _lot_ easier than some other SCM's, because you can
just import random versions in any order, and then re-stich just the
commit history when you add a new thing in the middle, without generating
any new trees or deltas or anything strange at all).
But it's a lot of work. I tried to do a "Linux-Historic" archive about a
year ago (and imported some of the old kernels I had), but I gave up, just
because it was such a pain to try to do a good job and try to find old
release notes etc to import into the changelogs etc.
Oh, well.
So the only "old" history I have is indeed that BK conversion by Thomas
Gleixner. Any pre-BK stuff only exists as patches and tar-balls on various
ftp sites (and I don't have any magic repository of my own, so everybody
else can do exactly as well as I could, with possibly the exception that I
might remember some random details about some old release history - but
considering my memory, that's pretty unlikely too. Google is your friend)
Linus
^ permalink raw reply
* git refuses to switch to older branches
From: Martin Waitz @ 2006-08-19 20:25 UTC (permalink / raw)
To: git
[-- Attachment #1: Type: text/plain, Size: 505 bytes --]
hoi :)
now that gitweb.cgi is autogenerated, git refuses to switch to old
branches unless force is applied:
fatal: Untracked working tree file 'gitweb/gitweb.cgi' would
be overwritten by merge.
This safety measure is quite useful normally, but for files that are
explicitly marked as to-be-ignored it should not be neccessary.
But all the code that handles .gitignore is only used by ls-files now.
Does it make sense to add exclude handling to unpack-trees.c, too?
--
Martin Waitz
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: git clone dies (large git repository)
From: Junio C Hamano @ 2006-08-19 20:46 UTC (permalink / raw)
To: Troy Telford; +Cc: git
In-Reply-To: <op.teh30gmyies9li@rygel.lnxi.com>
"Troy Telford" <ttelford@linuxnetworx.com> writes:
> I originally had everything as loose objects. I then ran 'git-repack
> -d' on occasion, so I had a combination of a large pack file, smaller
> pack files, and loose objects. Finally, I tried 'git repack -a -d'
> and consolidated it all into a single 4GB pack file. It didn't seem
> to make much difference in the output.
>
> Am I bumping some sort of limitation within git, or have I uncovered a bug?
The former. Unfortunately this comes from an old design
decision.
Fortunately this design decision is not something irreversible
(see Chapter 1 of Documentation/ManagementStyle in the kernel
repository ;-).
The packfile is a dual-use format. When used for network
transfer, we only send the .pack file and have the recipient
reconstruct the corresponding .idx file. When used locally, we
need both .pack and .idx file; .pack contains the meat of the
data, and .idx allows us random access to the objects stored in
the corresponding .pack file.
What is interesting is that .pack format does not have (as far
as I know) inherent size limitation. However, .idx file has
hardcoded 32-bit offsets into .pack -- hence, in practice, you
cannot use a .pack that is over 4GB locally.
One crude workaround that would work _today_ for your situation
without changing file formats would be to use git-fetch into an
empty repository (and do ref cloning by hand) instead of using
git-clone. git-fetch gets .pack data over the wire and explode
the objects contained in the stream into individual objects (as
opposed to git-clone gets .pack data, stores it as a .pack and
tries to create corresponding .idx which in your case would bust
the 32-bit limit and fail).
This is from a private note I sent to Linus on Jun 26 2005 when
pack & idx pairs were initially introduced.
- Design decision. As before, you have assumption that nothing
is longer than 2^32 bytes. I am not unhappy with that
restriction with individual objects (even their uncompressed
size limited below 4GB or even 2GB is fine --- after all we
are talking about a source control system). I am however
wondering if we would regret it later to have a packed file
also limited to 4GB by having object_entry.offset "unsigned
long" (and fwrite htonl'ed 4 bytes). I personally do not
have problem with this, but I can easily see HPA frowning on
us. He didn't like it when I said "in GIT world, file sizes
and offsets are of type 'unsigned long'" some time ago.
I do not have a copy of a response from Linus to this point, but
if I recall things correctly, since then, the plan always has
been (1) to limit the size of individual packfiles to fit within
the idx limit and/or (2) extend the idx format to be able to
express offset over 2^32. The latter is possible because idx
file is a local matter, used only for local accesses and does
not get set over the wire.
However, even if we revise the .idx file format, we have another
practical problem to solve. Currently we assume that we can mmap
one packfile as a whole and do a random access into it. This
needs to be changed so that we (perhaps optionally, only when
dealing with a huge packfile) mmap part of a .pack at a time.
I recall more recently (as opposed to the heated discussion
immediately after packfile was introduced June last year) we had
another discussion about people not being able to mmap huge
packfiles, and partial mmapping was one of the things that were
discussed there.
^ permalink raw reply
* Re: [RFC] adding support for md5
From: Linus Torvalds @ 2006-08-19 20:50 UTC (permalink / raw)
To: David Rientjes; +Cc: git
In-Reply-To: <Pine.LNX.4.63.0608172259280.25827@chino.corp.google.com>
On Thu, 17 Aug 2006, David Rientjes wrote:
>
> I'd like to solicit some comments about implementing support for md5 as a
> hash function that could be determined at runtime by the user during a
> project init-db.
I would _strongly_ suggest against this. At least not md5.
I can see the point of configurable hashes, but it would be for a stronger
hash than sha1, not for a (much) weaker one.
md5 is not only shorter, it's known to be broken, and there are attacks
out there that generate documents with the same md5 checksum quickly and
undetectably (ie depending on what the "document format" is, you might
actually not _see_ the corruption).
There's a real-life example of this (just google for "same md5") with a
postscript file, which when printed out still looks "valid".
In contrast, sha1 is still considered "hard", in that while you can
obviously always brute-force _any_ hash, the sha1 brute-forcing attack is
considered to be impractical and nobody has at least shown any realistic
version of the above postscript kind of hack.
In my fairly limited performance analysis, I've actually been surprised by
the fact that the hashing has never really shown up as a major issue in
any of my profiles. All the _real_ performance issues have been related to
memory usage, and things like the hash lookup (ie "memcmp()" was pretty
high on the list - just from comparing object names during lookup).
We've also had compression issues (initial check-in) and obviously the
delta selection used to be a _huge_ time-waster until the pack info reuse
code went in. But I don't think we've ever had a load that was really
hashing-limited.
So considering that md5 isn't _that_ much faster to compute (let's say
that it's ~30% slower), the biggest advantage of md5 would likely be just
the fact that 16 bytes is smaller than 20 bytes, and thus commit objects
and tree objects in particular could be smaller. But you'd be better off
just using the first 16 bytes of the sha1 than the md5 hash, if that was
the main goal.
So yes, maybe we'll want to make the hash choice a setup-time option, but
if we ever do, I don't think we should make md5 even a choice. It's just
not a very good hash, and no new program should start using it.
Linus
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox