git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] gitweb: Deal with HEAD pointing to unborn branch in "heads" view

From
Jakub Narebski <jnareb@gmail.com>
Date
Feb 3, 2012, 21:33 UTC
Message-ID
<201202032233.05324.jnareb@gmail.com>
In-Reply-To
<CA+EqV8y3dhR8+PJbMxMNEsGjDOx6dxtPYjn8kDvAZxCAO7iS5w@mail.gmail.com>
On Mon, 30 Jan 2012, rajesh boyapati wrote:
> 
> Thank you for your Suggestions in finding the error in my case.
> Do you have a blog, so that, I can know your updates about gitweb.

No, I don't have a blog, though I might use Git page on Google+ to announce larger changes.

I am posting this to you to announce partial fix for your problem in the form of patch to gitweb, which would hopefully made it to next git version.

> 2012/1/30 Jakub Narebski <jnareb@gmail.com>
>> On Mon, 30 Jan 2012, rajesh boyapati wrote:
>>> 2012/1/28 Jakub Narebski <jnareb@gmail.com>
>>>> On Fri, 27 Jan 2012, rajesh boyapati wrote:
Show 16 quoted lines
>>>>>     my $alternate = 1;
>>>>>     for (my $i = $from; $i <= $to; $i++) {
>>>>>         my $entry = $headlist->[$i];
>>>>>         my %ref = %$entry;
>>>>>         my $curr = $ref{'id'} eq $head;
>>>>>         if ($alternate) {
>>>>>             print "<tr class=\"dark\">\n";
>>>>>         } else {
>>>>>             print "<tr class=\"light\">\n";
>>>>>         }
>>>>>         $alternate ^= 1;
>>>>
>>>> Hmmmm... I see that we do not check if $head is defined here before using
>>>> it.  This can happen legitimately if we are on yet to be born orphan branch
>>>> (so $head, which should be named $head_at, is undefined) but there exist
>>>> other branches (so $headlist is not empty).
This was simple to fix.
>>>>>>> [2012-01-25 18:50:35,658] ERROR
>>>>>>> com.google.gerrit.httpd.gitweb.GitWebServlet : CGI: [Wed Jan 25
>>>>>>> 18:50:35 2012] gitweb.cgi: Use of uninitialized value $commit_id
>>>>>>> in open at /usr/lib/cgi-bin/gitweb.cgi line 2817.
Show 19 quoted lines
>>>>> sub parse_commits {
>>>>>     my ($commit_id, $maxcount, $skip, $filename, @args) = @_;
>>>>>     my @cos;
>>>>>
>>>>>     $maxcount ||= 1;
>>>>>     $skip ||= 0;
>>>>>
>>>>>     local $/ = "\0";
>>>>>
>>>>>     open my $fd, "-|", git_cmd(), "rev-list",
>>>>>         "--header",
>>>>>         @args,
>>>>>         ("--max-count=" . $maxcount),
>>>>>         ("--skip=" . $skip),
>>>>>         @extra_options,
>>>>>         $commit_id,
>>>>>         "--",
>>>>>         ($filename ? ($filename) : ())
>>>>>         or die_error(500, "Open git-rev-list failed");

But I was not able to fix this, at least not currently. I wrote a failing test case for "commit" and similar views on unborn HEAD... but they fail _without_ error message like the one quoted.

I'd have to go slower route of examining gitweb code in how it deals with "invalid" HEAD (i.e. HEAD not pointing to commit, being on unborn branch).

Show 20 quoted lines
>>> For my git projects on gerrit, our main branch name is "base".
>>> We don't have any code on "master" branch.
>>> May be the $HEAD is looking for master branch(or checked out branch in git
>>> project).--> In our case, "master" is an empty branch.
>>> Also, In the git projects, the HEAD file is pointing to "ref:
>>> refs/heads/master".
>>> So, I think that's the reason for errors.
>>>
>>> How can I make $HEAD to point to a branch other than "master"?.
>>>   a) I can do this by pointing HEAD file in git projects to other branch
>> [...]
>>>   b) Is there any way, other than doing above step (a) ?.
>>>      I mean I don't want to have a code on "master" branch and also I
>>>      don't want to point HEAD file in git projects to some other branch.
>>>      Do I need to make any modifications to "gitweb.cgi" for this?
>>
>> Now that I know the source of this error, I can write test case
>> for it, and fix it.  I'll try to do it soon.
>>
>> So finally what you would need for (b) is just upgrade gitweb.
And here is the patch:
-- >8 ------------ >8 ---
From: Jakub Narebski <jnareb@gmail.com>
Subject: [PATCH] gitweb: Deal with HEAD pointing to unborn branch in "heads"
 view

Gitweb has problems if HEAD points to an unborn branch, with no commits on it yet, but there are other branches present (so it is not newly initialized repository).

This can happen if non-bare repository (with default 'master' branch) is updated not via committing but by other means like push to it, or Gerrit. It can happen also just after running "git checkout --orphan <new branch>" but before creating any new commit on this branch.

This commit adds test and fixes the issue of being on unborn branch (of HEAD not pointing to a commit) in "heads" view, and also in "summary" view -- which includes "heads" excerpt as subview.

While at it rename local variable $head to $head_at, as it points to current commit rather than current branch name (HEAD contents).

Reported-by: rajesh boyapati <boyapatisrajesh@gmail.com>
Signed-off-by: Jakub Narebski <jnareb@gmail.com>
---
 gitweb/gitweb.perl                     |    4 ++--
 t/t9500-gitweb-standalone-no-errors.sh |    9 +++++++++
 2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 9cf7e71..1f0ec12 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -5570,7 +5570,7 @@ sub git_tags_body {
 
 sub git_heads_body {
 	# uses global variable $project
-	my ($headlist, $head, $from, $to, $extra) = @_;
+	my ($headlist, $head_at, $from, $to, $extra) = @_;
 	$from = 0 unless defined $from;
 	$to = $#{$headlist} if (!defined $to || $#{$headlist} < $to);
 
@@ -5579,7 +5579,7 @@ sub git_heads_body {
 	for (my $i = $from; $i <= $to; $i++) {
 		my $entry = $headlist->[$i];
 		my %ref = %$entry;
-		my $curr = $ref{'id'} eq $head;
+		my $curr = defined $head_at && $ref{'id'} eq $head_at;
 		if ($alternate) {
 			print "<tr class=\"dark\">\n";
 		} else {
diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh
index 0f771c6..81246a6 100755
--- a/t/t9500-gitweb-standalone-no-errors.sh
+++ b/t/t9500-gitweb-standalone-no-errors.sh
@@ -739,4 +739,13 @@ test_expect_success \
 	'echo "\$projects_list_group_categories = 1;" >>gitweb_config.perl &&
 	 gitweb_run'
 
+# ----------------------------------------------------------------------
+# unborn branches
+
+test_expect_success \
+	'unborn HEAD: "summary" page (with "heads" subview)' \
+	'git checkout orphan_branch || git checkout --orphan orphan_branch &&
+	 test_when_finished "git checkout master" &&
+	 gitweb_run "p=.git;a=summary"'
+
 test_done
-- 
1.7.9
Previous: Jakub NarebskiNext: Jakub Narebski
Message 5 of 14 in “Fwd: Git-web error”
  1. rajesh boyapatiJan 27, 2012
  2. Jakub NarebskiJan 27, 2012
  3. Jakub NarebskiJan 29, 2012
  4. Jakub NarebskiJan 30, 2012
  5. gitweb: Deal with HEAD pointing to unborn branch in "heads" viewJakub Narebski, Feb 3, 2012
  6. Jakub NarebskiFeb 7, 2012
  7. gitweb: Harden parse_commit and parse_commitsJakub Narebski, Feb 8, 2012
  8. Jakub NarebskiFeb 9, 2012
  9. gitweb: Silence stderr in parse_commit*() subroutinesJakub Narebski, Feb 11, 2012
  10. Junio C HamanoFeb 13, 2012
  11. Jakub NarebskiFeb 13, 2012
  12. Jakub NarebskiFeb 13, 2012
  13. Jakub NarebskiFeb 13, 2012
  14. Jakub NarebskiFeb 15, 2012

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.