Anonymous avatar Anonymous committed 9be3614

gitweb: Fix project-specific feature override behavior

This commit fixes a bug in processing project-specific override in
a situation when there is no project, e.g. for the projects list page.

When 'snapshot' feature had project specific config override enabled
by putting
$feature{'snapshot'}{'override'} = 1;

(or equivalent) in $GITWEB_CONFIG, and when viewing toplevel gitweb
page, which means the projects list page (to be more exact this
happens for any project-less action), gitweb would put the following
Perl warnings in error log:

gitweb.cgi: Use of uninitialized value $git_dir in concatenation (.) or string at gitweb.cgi line 2065.
fatal: error processing config file(s)
gitweb.cgi: Use of uninitialized value $git_dir in concatenation (.) or string at gitweb.cgi line 2221.
gitweb.cgi: Use of uninitialized value $git_dir in concatenation (.) or string at gitweb.cgi line 2218.

The problem is in the following fragment of code:

# path to the current git repository
our $git_dir;
$git_dir = "$projectroot/$project" if $project;

# list of supported snapshot formats
our @snapshot_fmts = gitweb_get_feature('snapshot');
@snapshot_fmts = filter_snapshot_fmts(@snapshot_fmts);

For the toplevel gitweb page, which is the list of projects, $project is not
defined, therefore neither is $git_dir. gitweb_get_feature() subroutine
calls git_get_project_config() if project specific override is turned
on... but we don't have project here.

Those errors mentioned above occur in the following fragment of code in

# get config
if (!defined $config_file ||
$config_file ne "$git_dir/config") {
%config = git_parse_project_config('gitweb');
$config_file = "$git_dir/config";

git_parse_project_config() calls git_cmd() which has '--git-dir='.$git_dir

There are (at least) three possible solutions:
1. Harden gitweb_get_feature() so that it doesn't call
git_get_project_config() if $project (and therefore $git_dir) is not
defined; there is no project for project specific config.
2. Harden git_get_project_config() like you did in your fix, returning early
if $git_dir is not defined.
3. Harden git_cmd() so that it doesn't add "--git-dir=$git_dir" if $git_dir
is not defined, and change git_get_project_config() so that it doesn't
even try to access $git_dir if it is not defined.

This commit implements both 1.) and 2.), i.e. gitweb_get_feature() doesn't
call project-specific override if $git_dir is not defined (if there is no
project), and git_get_project_config() returns early if $git_dir is not

Add a test for this bug to t/ test.

Reported-by: Eli Barzilay <>;
Signed-off-by: Jakub Narebski <>;
Signed-off-by: Junio C Hamano <>;

Comments (0)

Files changed (2)


-	if (!$override) { return @defaults; }
+	# project specific override is possible only if we have project
+	our $git_dir; # global variable, declared later
+	if (!$override || !defined $git_dir) {
+		return @defaults;
+	}
 	if (!defined $sub) {
 		warn "feature $name is not overridable";
 		return @defaults;
 sub git_get_project_config {
 	my ($key, $type) = @_;
+	# do we have project
+	return unless (defined $project && defined $git_dir);
 	# key sanity check
 	return unless ($key);
 	$key =~ s/^gitweb\.//;


 # ----------------------------------------------------------------------
 # gitweb config and repo config
-cat >>gitweb_config.perl <<EOF
-\$feature{'blame'}{'override'} = 1;
-\$feature{'snapshot'}{'override'} = 1;
-\$feature{'avatar'}{'override'} = 1;
+cat >>gitweb_config.perl <<\EOF
+# turn on override for each overridable feature
+foreach my $key (keys %feature) {
+	if ($feature{$key}{'sub'}) {
+		$feature{$key}{'override'} = 1;
+	}
 test_expect_success \
+	'config override: projects list (implicit)' \
+	'gitweb_run'
+test_debug 'cat gitweb.log'
+test_expect_success \
 	'config override: tree view, features not overridden in repo config' \
 	'gitweb_run "p=.git;a=tree"'
 test_debug 'cat gitweb.log'
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.