Git development
 help / color / mirror / Atom feed
* Re: [PATCH 19] gitweb: No need to quote path for list version of open "-|"
From: Jakub Narebski @ 2006-07-31 19:00 UTC (permalink / raw)
  To: git
In-Reply-To: <7v3bch7gf8.fsf@assigned-by-dhcp.cox.net>

<opublikowany i wysłany>

Junio C Hamano wrote:

> I suspect the patch title is wrong -- it is not "no need to" but
> "quoting path breaks so do not do it" ;-).
> 
> I guess this fixes the problem I saw last night?

If I remember correctly it worked without this patch, for git 1.4.1.1 
(i.e. with --full-history option, although not working as advertised: see my
comment earlier in thread).

How to do sane fallback to version without "--full-history", if git binaries
used do not support "--full-history"?

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply

* Re: Fix double "close()" in ce_compare_data
From: Junio C Hamano @ 2006-07-31 19:05 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0607310945490.4168@g5.osdl.org>

Linus Torvalds <torvalds@osdl.org> writes:

> The way I found this also showed a potential performance problem: if you 
> do a "git reset --hard" (or similar) after you have changes in your tree, 
> it will write the index file with the same timestamp as the checked out 
> files that it re-wrote.
>...
> We should really try to have some way to re-generate the index 
> automatically when this case triggers, so that we only need to do it 
> _once_ rather than keep doing it forever while the index is "potentially 
> stale".
>
> Any ideas?

Just before writing the index out, we could do a gettimeofday()
and wait for 1 second (or two if you are on FAT) if we have many
many paths that have the same timestamp.  Ugly and would not
work on NFS I suspect.

We could do gratuitous "update-index --refresh" but that is
uglier especially if done at the core level; the caller does not
expect the index file to be updated.

Or we could remove the check and tell the user not to touch the
working tree after calling update-index (I am not seriously
suggesting this).

^ permalink raw reply

* [PATCH 20 (amend)] gitweb: Reordering code and dividing it into categories
From: Jakub Narebski @ 2006-07-31 19:22 UTC (permalink / raw)
  To: git
In-Reply-To: <200607312048.44075.jnareb@gmail.com>

Reorder gitweb code around, divide it into sections (categories) and
add some comments.

Signed-off-by: Jakub Narebski <jnareb@gmail.com>
---
 gitweb/gitweb.cgi | 1616 ++++++++++++++++++++++++++++-------------------------
 1 files changed, 840 insertions(+), 776 deletions(-)

diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi
index cb6af39..c1ee79e 100755
--- a/gitweb/gitweb.cgi
+++ b/gitweb/gitweb.cgi
@@ -160,21 +160,7 @@ if (defined $searchtext) {
 	$searchtext = quotemeta $searchtext;
 }
 
-sub validate_input {
-	my $input = shift;
-
-	if ($input =~ m/^[0-9a-fA-F]{40}$/) {
-		return $input;
-	}
-	if ($input =~ m/(^|\/)(|\.|\.\.)($|\/)/) {
-		return undef;
-	}
-	if ($input =~ m/[^a-zA-Z0-9_\x80-\xff\ \t\.\/\-\+\#\~\%]/) {
-		return undef;
-	}
-	return $input;
-}
-
+# dispatch
 if (!defined $action || $action eq "summary") {
 	git_summary();
 	exit;
@@ -235,6 +221,24 @@ if (!defined $action || $action eq "summ
 	exit;
 }
 
+## ======================================================================
+## validation, quoting/unquoting and escaping
+
+sub validate_input {
+	my $input = shift;
+
+	if ($input =~ m/^[0-9a-fA-F]{40}$/) {
+		return $input;
+	}
+	if ($input =~ m/(^|\/)(|\.|\.\.)($|\/)/) {
+		return undef;
+	}
+	if ($input =~ m/[^a-zA-Z0-9_\x80-\xff\ \t\.\/\-\+\#\~\%]/) {
+		return undef;
+	}
+	return $input;
+}
+
 # quote unsafe chars, but keep the slash, even when it's not
 # correct, but quoted slashes look too horrible in bookmarks
 sub esc_param {
@@ -264,6 +268,29 @@ sub unquote {
 	return $str;
 }
 
+## ----------------------------------------------------------------------
+## HTML aware string manipulation
+
+sub chop_str {
+	my $str = shift;
+	my $len = shift;
+	my $add_len = shift || 10;
+
+	# allow only $len chars, but don't cut a word if it would fit in $add_len
+	# if it doesn't fit, cut it if it's still longer than the dots we would add
+	$str =~ m/^(.{0,$len}[^ \/\-_:\.@]{0,$add_len})(.*)/;
+	my $body = $1;
+	my $tail = $2;
+	if (length($tail) > 4) {
+		$tail = " ...";
+		$body =~ s/&[^;]*$//; # remove chopped character entities
+	}
+	return "$body$tail";
+}
+
+## ----------------------------------------------------------------------
+## functions returning short strings
+
 # CSS class for given age value (in seconds)
 sub age_class {
 	my $age = shift;
@@ -277,202 +304,108 @@ sub age_class {
 	}
 }
 
-sub git_header_html {
-	my $status = shift || "200 OK";
-	my $expires = shift;
+# convert age in seconds to "nn units ago" string
+sub age_string {
+	my $age = shift;
+	my $age_str;
 
-	my $title = "$site_name git";
-	if (defined $project) {
-		$title .= " - $project";
-		if (defined $action) {
-			$title .= "/$action";
-			if (defined $file_name) {
-				$title .= " - $file_name";
-				if ($action eq "tree" && $file_name !~ m|/$|) {
-					$title .= "/";
-				}
-			}
-		}
-	}
-	my $content_type;
-	# require explicit support from the UA if we are to send the page as
-	# 'application/xhtml+xml', otherwise send it as plain old 'text/html'.
-	# we have to do this because MSIE sometimes globs '*/*', pretending to
-	# support xhtml+xml but choking when it gets what it asked for.
-	if ($cgi->http('HTTP_ACCEPT') =~ m/(,|;|\s|^)application\/xhtml\+xml(,|;|\s|$)/ && $cgi->Accept('application/xhtml+xml') != 0) {
-		$content_type = 'application/xhtml+xml';
+	if ($age > 60*60*24*365*2) {
+		$age_str = (int $age/60/60/24/365);
+		$age_str .= " years ago";
+	} elsif ($age > 60*60*24*(365/12)*2) {
+		$age_str = int $age/60/60/24/(365/12);
+		$age_str .= " months ago";
+	} elsif ($age > 60*60*24*7*2) {
+		$age_str = int $age/60/60/24/7;
+		$age_str .= " weeks ago";
+	} elsif ($age > 60*60*24*2) {
+		$age_str = int $age/60/60/24;
+		$age_str .= " days ago";
+	} elsif ($age > 60*60*2) {
+		$age_str = int $age/60/60;
+		$age_str .= " hours ago";
+	} elsif ($age > 60*2) {
+		$age_str = int $age/60;
+		$age_str .= " min ago";
+	} elsif ($age > 2) {
+		$age_str = int $age;
+		$age_str .= " sec ago";
 	} else {
-		$content_type = 'text/html';
-	}
-	print $cgi->header(-type=>$content_type, -charset => 'utf-8', -status=> $status, -expires => $expires);
-	print <<EOF;
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
-<!-- git web interface v$version, (C) 2005-2006, Kay Sievers <kay.sievers\@vrfy.org>, Christian Gierke -->
-<!-- git core binaries version $git_version -->
-<head>
-<meta http-equiv="content-type" content="$content_type; charset=utf-8"/>
-<meta name="robots" content="index, nofollow"/>
-<title>$title</title>
-<link rel="stylesheet" type="text/css" href="$stylesheet"/>
-$rss_link
-</head>
-<body>
-EOF
-	print "<div class=\"page_header\">\n" .
-	      "<a href=\"http://www.kernel.org/pub/software/scm/git/docs/\" title=\"git documentation\">" .
-	      "<img src=\"$my_uri?" . esc_param("a=git-logo.png") . "\" width=\"72\" height=\"27\" alt=\"git\" style=\"float:right; border-width:0px;\"/>" .
-	      "</a>\n";
-	print $cgi->a({-href => esc_param($home_link)}, "projects") . " / ";
-	if (defined $project) {
-		print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary")}, esc_html($project));
-		if (defined $action) {
-			print " / $action";
-		}
-		print "\n";
-		if (!defined $searchtext) {
-			$searchtext = "";
-		}
-		my $search_hash;
-		if (defined $hash_base) {
-			$search_hash = $hash_base;
-		} elsif (defined $hash) {
-			$search_hash = $hash;
-		} else {
-			$search_hash = "HEAD";
-		}
-		$cgi->param("a", "search");
-		$cgi->param("h", $search_hash);
-		print $cgi->startform(-method => "get", -action => $my_uri) .
-		      "<div class=\"search\">\n" .
-		      $cgi->hidden(-name => "p") . "\n" .
-		      $cgi->hidden(-name => "a") . "\n" .
-		      $cgi->hidden(-name => "h") . "\n" .
-		      $cgi->textfield(-name => "s", -value => $searchtext) . "\n" .
-		      "</div>" .
-		      $cgi->end_form() . "\n";
+		$age_str .= " right now";
 	}
-	print "</div>\n";
+	return $age_str;
 }
 
-sub git_footer_html {
-	print "<div class=\"page_footer\">\n";
-	if (defined $project) {
-		my $descr = git_read_description($project);
-		if (defined $descr) {
-			print "<div class=\"page_footer_text\">" . esc_html($descr) . "</div>\n";
-		}
-		print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=rss"), -class => "rss_logo"}, "RSS") . "\n";
+# convert file mode in octal to symbolic file mode string
+sub mode_str {
+	my $mode = oct shift;
+
+	if (S_ISDIR($mode & S_IFMT)) {
+		return 'drwxr-xr-x';
+	} elsif (S_ISLNK($mode)) {
+		return 'lrwxrwxrwx';
+	} elsif (S_ISREG($mode)) {
+		# git cares only about the executable bit
+		if ($mode & S_IXUSR) {
+			return '-rwxr-xr-x';
+		} else {
+			return '-rw-r--r--';
+		};
 	} else {
-		print $cgi->a({-href => "$my_uri?" . esc_param("a=opml"), -class => "rss_logo"}, "OPML") . "\n";
+		return '----------';
 	}
-	print "</div>\n" .
-	      "</body>\n" .
-	      "</html>";
 }
 
-sub die_error {
-	my $status = shift || "403 Forbidden";
-	my $error = shift || "Malformed query, file missing or permission denied";
+# convert file mode in octal to file type string
+sub file_type {
+	my $mode = oct shift;
 
-	git_header_html($status);
-	print "<div class=\"page_body\">\n" .
-	      "<br/><br/>\n" .
-	      "$status - $error\n" .
-	      "<br/>\n" .
-	      "</div>\n";
-	git_footer_html();
-	exit;
+	if (S_ISDIR($mode & S_IFMT)) {
+		return "directory";
+	} elsif (S_ISLNK($mode)) {
+		return "symlink";
+	} elsif (S_ISREG($mode)) {
+		return "file";
+	} else {
+		return "unknown";
+	}
 }
 
-sub git_page_nav {
-	my ($current, $suppress, $head, $treehead, $treebase, $extra) = @_;
-	$extra = '' if !defined $extra; # pager or formats
+## ----------------------------------------------------------------------
+## functions returning short HTML fragments, or transforming HTML fragments
+## which don't beling to other sections
 
-	my @navs = qw(summary shortlog log commit commitdiff tree);
-	if ($suppress) {
-		@navs = grep { $_ ne $suppress } @navs;
-	}
+# format line of commit message or tag comment
+sub format_log_line_html {
+	my $line = shift;
 
-	my %arg = map { $_, ''} @navs;
-	if (defined $head) {
-		for (qw(commit commitdiff)) {
-			$arg{$_} = ";h=$head";
-		}
-		if ($current =~ m/^(tree | log | shortlog | commit | commitdiff | search)$/x) {
-			for (qw(shortlog log)) {
-				$arg{$_} = ";h=$head";
-			}
+	$line = esc_html($line);
+	$line =~ s/ /&nbsp;/g;
+	if ($line =~ m/([0-9a-fA-F]{40})/) {
+		my $hash_text = $1;
+		if (git_get_type($hash_text) eq "commit") {
+			my $link = $cgi->a({-class => "text", -href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_text")}, $hash_text);
+			$line =~ s/$hash_text/$link/;
 		}
 	}
-	$arg{tree} .= ";h=$treehead" if defined $treehead;
-	$arg{tree} .= ";hb=$treebase" if defined $treebase;
-
-	print "<div class=\"page_nav\">\n" .
-		(join " | ",
-		 map { $_ eq $current
-					 ? $_
-					 : $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$_$arg{$_}")}, "$_")
-				 }
-		 @navs);
-	print "<br/>\n$extra<br/>\n" .
-	      "</div>\n";
-}
-
-sub git_header_div {
-	my ($action, $title, $hash, $hash_base) = @_;
-	my $rest = '';
-
-	$rest .= ";h=$hash" if $hash;
-	$rest .= ";hb=$hash_base" if $hash_base;
-
-	print "<div class=\"header\">\n" .
-	      $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$action$rest"),
-	               -class => "title"}, $title ? $title : $action) . "\n" .
-	      "</div>\n";
+	return $line;
 }
 
-sub git_get_paging_nav {
-	my ($action, $hash, $head, $page, $nrevs) = @_;
-	my $paging_nav;
-
-
-	if ($hash ne $head || $page) {
-		$paging_nav .= $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$action")}, "HEAD");
-	} else {
-		$paging_nav .= "HEAD";
-	}
-
-	if ($page > 0) {
-		$paging_nav .= " &sdot; " .
-			$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$action;h=$hash;pg=" . ($page-1)),
-							 -accesskey => "p", -title => "Alt-p"}, "prev");
-	} else {
-		$paging_nav .= " &sdot; prev";
-	}
+# format marker of refs pointing to given object
+sub git_get_referencing {
+	my ($refs, $id) = @_;
 
-	if ($nrevs >= (100 * ($page+1)-1)) {
-		$paging_nav .= " &sdot; " .
-			$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$action;h=$hash;pg=" . ($page+1)),
-							 -accesskey => "n", -title => "Alt-n"}, "next");
+	if (defined $refs->{$id}) {
+		return ' <span class="tag">' . esc_html($refs->{$id}) . '</span>';
 	} else {
-		$paging_nav .= " &sdot; next";
+		return "";
 	}
-
-	return $paging_nav;
 }
 
-sub git_get_type {
-	my $hash = shift;
-
-	open my $fd, "-|", $GIT, "cat-file", '-t', $hash or return;
-	my $type = <$fd>;
-	close $fd or return;
-	chomp $type;
-	return $type;
-}
+## ----------------------------------------------------------------------
+## git utility subroutines, invoking git commands
 
+# get HEAD ref of given project as hash
 sub git_read_head {
 	my $project = shift;
 	my $oENV = $ENV{'GIT_DIR'};
@@ -491,6 +424,57 @@ sub git_read_head {
 	return $retval;
 }
 
+# get type of given object
+sub git_get_type {
+	my $hash = shift;
+
+	open my $fd, "-|", $GIT, "cat-file", '-t', $hash or return;
+	my $type = <$fd>;
+	close $fd or return;
+	chomp $type;
+	return $type;
+}
+
+sub git_get_project_config {
+	my $key = shift;
+
+	return unless ($key);
+	$key =~ s/^gitweb\.//;
+	return if ($key =~ m/\W/);
+
+	my $val = qx($GIT repo-config --get gitweb.$key);
+	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;
+	my $path = shift || return undef;
+
+	my $tree = $base;
+
+	open my $fd, "-|", $GIT, "ls-tree", $base, "--", $path
+		or die_error(undef, "Open git-ls-tree failed.");
+	my $line = <$fd>;
+	close $fd or return undef;
+
+	#'100644 blob 0fa3f3a66fb6a137f6ec2c19351ed4d807070ffa	panic.c'
+	$line =~ m/^([0-9]+) (.+) ([0-9a-fA-F]{40})\t(.+)$/;
+	return $3;
+}
+
+## ......................................................................
+## git utility functions, directly accessing git repository
+
+# assumes that PATH is not symref
 sub git_read_hash {
 	my $path = shift;
 
@@ -513,6 +497,100 @@ sub git_read_description {
 	return $descr;
 }
 
+sub git_read_projects {
+	my @list;
+
+	if (-d $projects_list) {
+		# search in directory
+		my $dir = $projects_list;
+		opendir my ($dh), $dir or return undef;
+		while (my $dir = readdir($dh)) {
+			if (-e "$projectroot/$dir/HEAD") {
+				my $pr = {
+					path => $dir,
+				};
+				push @list, $pr
+			}
+		}
+		closedir($dh);
+	} elsif (-f $projects_list) {
+		# read from file(url-encoded):
+		# 'git%2Fgit.git Linus+Torvalds'
+		# 'libs%2Fklibc%2Fklibc.git H.+Peter+Anvin'
+		# 'linux%2Fhotplug%2Fudev.git Greg+Kroah-Hartman'
+		open my ($fd), $projects_list or return undef;
+		while (my $line = <$fd>) {
+			chomp $line;
+			my ($path, $owner) = split ' ', $line;
+			$path = unescape($path);
+			$owner = unescape($owner);
+			if (!defined $path) {
+				next;
+			}
+			if (-e "$projectroot/$path/HEAD") {
+				my $pr = {
+					path => $path,
+					owner => decode("utf8", $owner, Encode::FB_DEFAULT),
+				};
+				push @list, $pr
+			}
+		}
+		close $fd;
+	}
+	@list = sort {$a->{'path'} cmp $b->{'path'}} @list;
+	return @list;
+}
+
+sub read_info_ref {
+	my $type = shift || "";
+	my %refs;
+	# 5dc01c595e6c6ec9ccda4f6f69c131c0dd945f8c	refs/tags/v2.6.11
+	# c39ae07f393806ccf406ef966e9a15afc43cc36a	refs/tags/v2.6.11^{}
+	open my $fd, "$projectroot/$project/info/refs" or return;
+	while (my $line = <$fd>) {
+		chomp $line;
+		# attention: for $type == "" it saves only last path part of ref name
+		# e.g. from 'refs/heads/jn/gitweb' it would leave only 'gitweb'
+		if ($line =~ m/^([0-9a-fA-F]{40})\t.*$type\/([^\^]+)/) {
+			if (defined $refs{$1}) {
+				$refs{$1} .= " / $2";
+			} else {
+				$refs{$1} = $2;
+			}
+		}
+	}
+	close $fd or return;
+	return \%refs;
+}
+
+## ----------------------------------------------------------------------
+## parse to hash functions
+
+sub date_str {
+	my $epoch = shift;
+	my $tz = shift || "-0000";
+
+	my %date;
+	my @months = ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
+	my @days = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");
+	my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday) = gmtime($epoch);
+	$date{'hour'} = $hour;
+	$date{'minute'} = $min;
+	$date{'mday'} = $mday;
+	$date{'day'} = $days[$wday];
+	$date{'month'} = $months[$mon];
+	$date{'rfc2822'} = sprintf "%s, %d %s %4d %02d:%02d:%02d +0000", $days[$wday], $mday, $months[$mon], 1900+$year, $hour ,$min, $sec;
+	$date{'mday-time'} = sprintf "%d %s %02d:%02d", $mday, $months[$mon], $hour ,$min;
+
+	$tz =~ m/^([+\-][0-9][0-9])([0-9][0-9])$/;
+	my $local = $epoch + ((int $1 + ($2/60)) * 3600);
+	($sec, $min, $hour, $mday, $mon, $year, $wday, $yday) = gmtime($local);
+	$date{'hour_local'} = $hour;
+	$date{'minute_local'} = $min;
+	$date{'tz_local'} = $tz;
+	return %date;
+}
+
 sub git_read_tag {
 	my $tag_id = shift;
 	my %tag;
@@ -548,37 +626,6 @@ sub git_read_tag {
 	return %tag
 }
 
-sub age_string {
-	my $age = shift;
-	my $age_str;
-
-	if ($age > 60*60*24*365*2) {
-		$age_str = (int $age/60/60/24/365);
-		$age_str .= " years ago";
-	} elsif ($age > 60*60*24*(365/12)*2) {
-		$age_str = int $age/60/60/24/(365/12);
-		$age_str .= " months ago";
-	} elsif ($age > 60*60*24*7*2) {
-		$age_str = int $age/60/60/24/7;
-		$age_str .= " weeks ago";
-	} elsif ($age > 60*60*24*2) {
-		$age_str = int $age/60/60/24;
-		$age_str .= " days ago";
-	} elsif ($age > 60*60*2) {
-		$age_str = int $age/60/60;
-		$age_str .= " hours ago";
-	} elsif ($age > 60*2) {
-		$age_str = int $age/60;
-		$age_str .= " min ago";
-	} elsif ($age > 2) {
-		$age_str = int $age;
-		$age_str .= " sec ago";
-	} else {
-		$age_str .= " right now";
-	}
-	return $age_str;
-}
-
 sub git_read_commit {
 	my $commit_id = shift;
 	my $commit_text = shift;
@@ -673,380 +720,8 @@ sub git_read_commit {
 	return %co;
 }
 
-sub git_diff_print {
-	my $from = shift;
-	my $from_name = shift;
-	my $to = shift;
-	my $to_name = shift;
-	my $format = shift || "html";
-
-	my $from_tmp = "/dev/null";
-	my $to_tmp = "/dev/null";
-	my $pid = $$;
-
-	# create tmp from-file
-	if (defined $from) {
-		$from_tmp = "$git_temp/gitweb_" . $$ . "_from";
-		open my $fd2, "> $from_tmp";
-		open my $fd, "-|", $GIT, "cat-file", "blob", $from;
-		my @file = <$fd>;
-		print $fd2 @file;
-		close $fd2;
-		close $fd;
-	}
-
-	# create tmp to-file
-	if (defined $to) {
-		$to_tmp = "$git_temp/gitweb_" . $$ . "_to";
-		open my $fd2, "> $to_tmp";
-		open my $fd, "-|", $GIT, "cat-file", "blob", $to;
-		my @file = <$fd>;
-		print $fd2 @file;
-		close $fd2;
-		close $fd;
-	}
-
-	open my $fd, "-|", "/usr/bin/diff -u -p -L \'$from_name\' -L \'$to_name\' $from_tmp $to_tmp";
-	if ($format eq "plain") {
-		undef $/;
-		print <$fd>;
-		$/ = "\n";
-	} else {
-		while (my $line = <$fd>) {
-			chomp $line;
-			my $char = substr($line, 0, 1);
-			my $diff_class = "";
-			if ($char eq '+') {
-				$diff_class = " add";
-			} elsif ($char eq "-") {
-				$diff_class = " rem";
-			} elsif ($char eq "@") {
-				$diff_class = " chunk_header";
-			} elsif ($char eq "\\") {
-				# skip errors
-				next;
-			}
-			while ((my $pos = index($line, "\t")) != -1) {
-				if (my $count = (8 - (($pos-1) % 8))) {
-					my $spaces = ' ' x $count;
-					$line =~ s/\t/$spaces/;
-				}
-			}
-			print "<div class=\"diff$diff_class\">" . esc_html($line) . "</div>\n";
-		}
-	}
-	close $fd;
-
-	if (defined $from) {
-		unlink($from_tmp);
-	}
-	if (defined $to) {
-		unlink($to_tmp);
-	}
-}
-
-sub mode_str {
-	my $mode = oct shift;
-
-	if (S_ISDIR($mode & S_IFMT)) {
-		return 'drwxr-xr-x';
-	} elsif (S_ISLNK($mode)) {
-		return 'lrwxrwxrwx';
-	} elsif (S_ISREG($mode)) {
-		# git cares only about the executable bit
-		if ($mode & S_IXUSR) {
-			return '-rwxr-xr-x';
-		} else {
-			return '-rw-r--r--';
-		};
-	} else {
-		return '----------';
-	}
-}
-
-sub chop_str {
-	my $str = shift;
-	my $len = shift;
-	my $add_len = shift || 10;
-
-	# allow only $len chars, but don't cut a word if it would fit in $add_len
-	# if it doesn't fit, cut it if it's still longer than the dots we would add
-	$str =~ m/^(.{0,$len}[^ \/\-_:\.@]{0,$add_len})(.*)/;
-	my $body = $1;
-	my $tail = $2;
-	if (length($tail) > 4) {
-		$tail = " ...";
-		$body =~ s/&[^;]*$//; # remove chopped character entities
-	}
-	return "$body$tail";
-}
-
-sub file_type {
-	my $mode = oct shift;
-
-	if (S_ISDIR($mode & S_IFMT)) {
-		return "directory";
-	} elsif (S_ISLNK($mode)) {
-		return "symlink";
-	} elsif (S_ISREG($mode)) {
-		return "file";
-	} else {
-		return "unknown";
-	}
-}
-
-sub format_log_line_html {
-	my $line = shift;
-
-	$line = esc_html($line);
-	$line =~ s/ /&nbsp;/g;
-	if ($line =~ m/([0-9a-fA-F]{40})/) {
-		my $hash_text = $1;
-		if (git_get_type($hash_text) eq "commit") {
-			my $link = $cgi->a({-class => "text", -href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_text")}, $hash_text);
-			$line =~ s/$hash_text/$link/;
-		}
-	}
-	return $line;
-}
-
-sub date_str {
-	my $epoch = shift;
-	my $tz = shift || "-0000";
-
-	my %date;
-	my @months = ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
-	my @days = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");
-	my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday) = gmtime($epoch);
-	$date{'hour'} = $hour;
-	$date{'minute'} = $min;
-	$date{'mday'} = $mday;
-	$date{'day'} = $days[$wday];
-	$date{'month'} = $months[$mon];
-	$date{'rfc2822'} = sprintf "%s, %d %s %4d %02d:%02d:%02d +0000", $days[$wday], $mday, $months[$mon], 1900+$year, $hour ,$min, $sec;
-	$date{'mday-time'} = sprintf "%d %s %02d:%02d", $mday, $months[$mon], $hour ,$min;
-
-	$tz =~ m/^([+\-][0-9][0-9])([0-9][0-9])$/;
-	my $local = $epoch + ((int $1 + ($2/60)) * 3600);
-	($sec, $min, $hour, $mday, $mon, $year, $wday, $yday) = gmtime($local);
-	$date{'hour_local'} = $hour;
-	$date{'minute_local'} = $min;
-	$date{'tz_local'} = $tz;
-	return %date;
-}
-
-# git-logo (cached in browser for one day)
-sub git_logo {
-	binmode STDOUT, ':raw';
-	print $cgi->header(-type => 'image/png', -expires => '+1d');
-	# cat git-logo.png | hexdump -e '16/1 " %02x"  "\n"' | sed 's/ /\\x/g'
-	print	"\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52" .
-		"\x00\x00\x00\x48\x00\x00\x00\x1b\x04\x03\x00\x00\x00\x2d\xd9\xd4" .
-		"\x2d\x00\x00\x00\x18\x50\x4c\x54\x45\xff\xff\xff\x60\x60\x5d\xb0" .
-		"\xaf\xaa\x00\x80\x00\xce\xcd\xc7\xc0\x00\x00\xe8\xe8\xe6\xf7\xf7" .
-		"\xf6\x95\x0c\xa7\x47\x00\x00\x00\x73\x49\x44\x41\x54\x28\xcf\x63" .
-		"\x48\x67\x20\x04\x4a\x5c\x18\x0a\x08\x2a\x62\x53\x61\x20\x02\x08" .
-		"\x0d\x69\x45\xac\xa1\xa1\x01\x30\x0c\x93\x60\x36\x26\x52\x91\xb1" .
-		"\x01\x11\xd6\xe1\x55\x64\x6c\x6c\xcc\x6c\x6c\x0c\xa2\x0c\x70\x2a" .
-		"\x62\x06\x2a\xc1\x62\x1d\xb3\x01\x02\x53\xa4\x08\xe8\x00\x03\x18" .
-		"\x26\x56\x11\xd4\xe1\x20\x97\x1b\xe0\xb4\x0e\x35\x24\x71\x29\x82" .
-		"\x99\x30\xb8\x93\x0a\x11\xb9\x45\x88\xc1\x8d\xa0\xa2\x44\x21\x06" .
-		"\x27\x41\x82\x40\x85\xc1\x45\x89\x20\x70\x01\x00\xa4\x3d\x21\xc5" .
-		"\x12\x1c\x9a\xfe\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82";
-}
-
-sub get_file_owner {
-	my $path = shift;
-
-	my ($dev, $ino, $mode, $nlink, $st_uid, $st_gid, $rdev, $size) = stat($path);
-	my ($name, $passwd, $uid, $gid, $quota, $comment, $gcos, $dir, $shell) = getpwuid($st_uid);
-	if (!defined $gcos) {
-		return undef;
-	}
-	my $owner = $gcos;
-	$owner =~ s/[,;].*$//;
-	return decode("utf8", $owner, Encode::FB_DEFAULT);
-}
-
-sub git_read_projects {
-	my @list;
-
-	if (-d $projects_list) {
-		# search in directory
-		my $dir = $projects_list;
-		opendir my ($dh), $dir or return undef;
-		while (my $dir = readdir($dh)) {
-			if (-e "$projectroot/$dir/HEAD") {
-				my $pr = {
-					path => $dir,
-				};
-				push @list, $pr
-			}
-		}
-		closedir($dh);
-	} elsif (-f $projects_list) {
-		# read from file(url-encoded):
-		# 'git%2Fgit.git Linus+Torvalds'
-		# 'libs%2Fklibc%2Fklibc.git H.+Peter+Anvin'
-		# 'linux%2Fhotplug%2Fudev.git Greg+Kroah-Hartman'
-		open my ($fd), $projects_list or return undef;
-		while (my $line = <$fd>) {
-			chomp $line;
-			my ($path, $owner) = split ' ', $line;
-			$path = unescape($path);
-			$owner = unescape($owner);
-			if (!defined $path) {
-				next;
-			}
-			if (-e "$projectroot/$path/HEAD") {
-				my $pr = {
-					path => $path,
-					owner => decode("utf8", $owner, Encode::FB_DEFAULT),
-				};
-				push @list, $pr
-			}
-		}
-		close $fd;
-	}
-	@list = sort {$a->{'path'} cmp $b->{'path'}} @list;
-	return @list;
-}
-
-sub git_get_project_config {
-	my $key = shift;
-
-	return unless ($key);
-	$key =~ s/^gitweb\.//;
-	return if ($key =~ m/\W/);
-
-	my $val = qx($GIT repo-config --get gitweb.$key);
-	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
-}
-
-sub git_project_list {
-	my @list = git_read_projects();
-	my @projects;
-	if (!@list) {
-		die_error(undef, "No project found.");
-	}
-	foreach my $pr (@list) {
-		my $head = git_read_head($pr->{'path'});
-		if (!defined $head) {
-			next;
-		}
-		$ENV{'GIT_DIR'} = "$projectroot/$pr->{'path'}";
-		my %co = git_read_commit($head);
-		if (!%co) {
-			next;
-		}
-		$pr->{'commit'} = \%co;
-		if (!defined $pr->{'descr'}) {
-			my $descr = git_read_description($pr->{'path'}) || "";
-			$pr->{'descr'} = chop_str($descr, 25, 5);
-		}
-		if (!defined $pr->{'owner'}) {
-			$pr->{'owner'} = get_file_owner("$projectroot/$pr->{'path'}") || "";
-		}
-		push @projects, $pr;
-	}
-	git_header_html();
-	if (-f $home_text) {
-		print "<div class=\"index_include\">\n";
-		open (my $fd, $home_text);
-		print <$fd>;
-		close $fd;
-		print "</div>\n";
-	}
-	print "<table class=\"project_list\">\n" .
-	      "<tr>\n";
-	if (!defined($order) || (defined($order) && ($order eq "project"))) {
-		@projects = sort {$a->{'path'} cmp $b->{'path'}} @projects;
-		print "<th>Project</th>\n";
-	} else {
-		print "<th>" . $cgi->a({-class => "header", -href => "$my_uri?" . esc_param("o=project")}, "Project") . "</th>\n";
-	}
-	if (defined($order) && ($order eq "descr")) {
-		@projects = sort {$a->{'descr'} cmp $b->{'descr'}} @projects;
-		print "<th>Description</th>\n";
-	} else {
-		print "<th>" . $cgi->a({-class => "header", -href => "$my_uri?" . esc_param("o=descr")}, "Description") . "</th>\n";
-	}
-	if (defined($order) && ($order eq "owner")) {
-		@projects = sort {$a->{'owner'} cmp $b->{'owner'}} @projects;
-		print "<th>Owner</th>\n";
-	} else {
-		print "<th>" . $cgi->a({-class => "header", -href => "$my_uri?" . esc_param("o=owner")}, "Owner") . "</th>\n";
-	}
-	if (defined($order) && ($order eq "age")) {
-		@projects = sort {$a->{'commit'}{'age'} <=> $b->{'commit'}{'age'}} @projects;
-		print "<th>Last Change</th>\n";
-	} else {
-		print "<th>" . $cgi->a({-class => "header", -href => "$my_uri?" . esc_param("o=age")}, "Last Change") . "</th>\n";
-	}
-	print "<th></th>\n" .
-	      "</tr>\n";
-	my $alternate = 0;
-	foreach my $pr (@projects) {
-		if ($alternate) {
-			print "<tr class=\"dark\">\n";
-		} else {
-			print "<tr class=\"light\">\n";
-		}
-		$alternate ^= 1;
-		print "<td>" . $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=summary"), -class => "list"}, esc_html($pr->{'path'})) . "</td>\n" .
-		      "<td>" . esc_html($pr->{'descr'}) . "</td>\n" .
-		      "<td><i>" . chop_str($pr->{'owner'}, 15) . "</i></td>\n";
-		print "<td class=\"". age_class($pr->{'commit'}{'age'}) . "\">" . $pr->{'commit'}{'age_string'} . "</td>\n" .
-		      "<td class=\"link\">" .
-		      $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=summary")}, "summary") .
-		      " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=shortlog")}, "shortlog") .
-		      " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=log")}, "log") .
-		      "</td>\n" .
-		      "</tr>\n";
-	}
-	print "</table>\n";
-	git_footer_html();
-}
-
-sub read_info_ref {
-	my $type = shift || "";
-	my %refs;
-	# 5dc01c595e6c6ec9ccda4f6f69c131c0dd945f8c	refs/tags/v2.6.11
-	# c39ae07f393806ccf406ef966e9a15afc43cc36a	refs/tags/v2.6.11^{}
-	open my $fd, "$projectroot/$project/info/refs" or return;
-	while (my $line = <$fd>) {
-		chomp $line;
-		# attention: for $type == "" it saves only last path part of ref name
-		# e.g. from 'refs/heads/jn/gitweb' it would leave only 'gitweb'
-		if ($line =~ m/^([0-9a-fA-F]{40})\t.*$type\/([^\^]+)/) {
-			if (defined $refs{$1}) {
-				$refs{$1} .= " / $2";
-			} else {
-				$refs{$1} = $2;
-			}
-		}
-	}
-	close $fd or return;
-	return \%refs;
-}
-
-sub git_get_referencing {
-	my ($refs, $id) = @_;
-
-	if (defined $refs->{$id}) {
-		return ' <span class="tag">' . esc_html($refs->{$id}) . '</span>';
-	} else {
-		return "";
-	}
-}
+## ......................................................................
+## parse to array of hashes functions
 
 sub git_read_refs {
 	my $ref_dir = shift;
@@ -1115,6 +790,299 @@ sub git_read_refs {
 	return \@reflist;
 }
 
+## ----------------------------------------------------------------------
+## filesystem-related functions
+
+sub get_file_owner {
+	my $path = shift;
+
+	my ($dev, $ino, $mode, $nlink, $st_uid, $st_gid, $rdev, $size) = stat($path);
+	my ($name, $passwd, $uid, $gid, $quota, $comment, $gcos, $dir, $shell) = getpwuid($st_uid);
+	if (!defined $gcos) {
+		return undef;
+	}
+	my $owner = $gcos;
+	$owner =~ s/[,;].*$//;
+	return decode("utf8", $owner, Encode::FB_DEFAULT);
+}
+
+## ......................................................................
+## mimetype related functions
+
+sub mimetype_guess_file {
+	my $filename = shift;
+	my $mimemap = shift;
+	-r $mimemap or return undef;
+
+	my %mimemap;
+	open(MIME, $mimemap) or return undef;
+	while (<MIME>) {
+		my ($mime, $exts) = split(/\t+/);
+		my @exts = split(/\s+/, $exts);
+		foreach my $ext (@exts) {
+			$mimemap{$ext} = $mime;
+		}
+	}
+	close(MIME);
+
+	$filename =~ /\.(.*?)$/;
+	return $mimemap{$1};
+}
+
+sub mimetype_guess {
+	my $filename = shift;
+	my $mime;
+	$filename =~ /\./ or return undef;
+
+	if ($mimetypes_file) {
+		my $file = $mimetypes_file;
+		#$file =~ m#^/# or $file = "$projectroot/$path/$file";
+		$mime = mimetype_guess_file($filename, $file);
+	}
+	$mime ||= mimetype_guess_file($filename, '/etc/mime.types');
+	return $mime;
+}
+
+sub git_blob_plain_mimetype {
+	my $fd = shift;
+	my $filename = shift;
+
+	if ($filename) {
+		my $mime = mimetype_guess($filename);
+		$mime and return $mime;
+	}
+
+	# just in case
+	return $default_blob_plain_mimetype unless $fd;
+
+	if (-T $fd) {
+		return 'text/plain' .
+		       ($default_text_plain_charset ? '; charset='.$default_text_plain_charset : '');
+	} elsif (! $filename) {
+		return 'application/octet-stream';
+	} elsif ($filename =~ m/\.png$/i) {
+		return 'image/png';
+	} elsif ($filename =~ m/\.gif$/i) {
+		return 'image/gif';
+	} elsif ($filename =~ m/\.jpe?g$/i) {
+		return 'image/jpeg';
+	} else {
+		return 'application/octet-stream';
+	}
+}
+
+## ======================================================================
+## functions printing HTML: header, footer, error page
+
+sub git_header_html {
+	my $status = shift || "200 OK";
+	my $expires = shift;
+
+	my $title = "$site_name git";
+	if (defined $project) {
+		$title .= " - $project";
+		if (defined $action) {
+			$title .= "/$action";
+			if (defined $file_name) {
+				$title .= " - $file_name";
+				if ($action eq "tree" && $file_name !~ m|/$|) {
+					$title .= "/";
+				}
+			}
+		}
+	}
+	my $content_type;
+	# require explicit support from the UA if we are to send the page as
+	# 'application/xhtml+xml', otherwise send it as plain old 'text/html'.
+	# we have to do this because MSIE sometimes globs '*/*', pretending to
+	# support xhtml+xml but choking when it gets what it asked for.
+	if ($cgi->http('HTTP_ACCEPT') =~ m/(,|;|\s|^)application\/xhtml\+xml(,|;|\s|$)/ && $cgi->Accept('application/xhtml+xml') != 0) {
+		$content_type = 'application/xhtml+xml';
+	} else {
+		$content_type = 'text/html';
+	}
+	print $cgi->header(-type=>$content_type, -charset => 'utf-8', -status=> $status, -expires => $expires);
+	print <<EOF;
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
+<!-- git web interface v$version, (C) 2005-2006, Kay Sievers <kay.sievers\@vrfy.org>, Christian Gierke -->
+<!-- git core binaries version $git_version -->
+<head>
+<meta http-equiv="content-type" content="$content_type; charset=utf-8"/>
+<meta name="robots" content="index, nofollow"/>
+<title>$title</title>
+<link rel="stylesheet" type="text/css" href="$stylesheet"/>
+$rss_link
+</head>
+<body>
+EOF
+	print "<div class=\"page_header\">\n" .
+	      "<a href=\"http://www.kernel.org/pub/software/scm/git/docs/\" title=\"git documentation\">" .
+	      "<img src=\"$my_uri?" . esc_param("a=git-logo.png") . "\" width=\"72\" height=\"27\" alt=\"git\" style=\"float:right; border-width:0px;\"/>" .
+	      "</a>\n";
+	print $cgi->a({-href => esc_param($home_link)}, "projects") . " / ";
+	if (defined $project) {
+		print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary")}, esc_html($project));
+		if (defined $action) {
+			print " / $action";
+		}
+		print "\n";
+		if (!defined $searchtext) {
+			$searchtext = "";
+		}
+		my $search_hash;
+		if (defined $hash_base) {
+			$search_hash = $hash_base;
+		} elsif (defined $hash) {
+			$search_hash = $hash;
+		} else {
+			$search_hash = "HEAD";
+		}
+		$cgi->param("a", "search");
+		$cgi->param("h", $search_hash);
+		print $cgi->startform(-method => "get", -action => $my_uri) .
+		      "<div class=\"search\">\n" .
+		      $cgi->hidden(-name => "p") . "\n" .
+		      $cgi->hidden(-name => "a") . "\n" .
+		      $cgi->hidden(-name => "h") . "\n" .
+		      $cgi->textfield(-name => "s", -value => $searchtext) . "\n" .
+		      "</div>" .
+		      $cgi->end_form() . "\n";
+	}
+	print "</div>\n";
+}
+
+sub git_footer_html {
+	print "<div class=\"page_footer\">\n";
+	if (defined $project) {
+		my $descr = git_read_description($project);
+		if (defined $descr) {
+			print "<div class=\"page_footer_text\">" . esc_html($descr) . "</div>\n";
+		}
+		print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=rss"), -class => "rss_logo"}, "RSS") . "\n";
+	} else {
+		print $cgi->a({-href => "$my_uri?" . esc_param("a=opml"), -class => "rss_logo"}, "OPML") . "\n";
+	}
+	print "</div>\n" .
+	      "</body>\n" .
+	      "</html>";
+}
+
+sub die_error {
+	my $status = shift || "403 Forbidden";
+	my $error = shift || "Malformed query, file missing or permission denied";
+
+	git_header_html($status);
+	print "<div class=\"page_body\">\n" .
+	      "<br/><br/>\n" .
+	      "$status - $error\n" .
+	      "<br/>\n" .
+	      "</div>\n";
+	git_footer_html();
+	exit;
+}
+
+## ----------------------------------------------------------------------
+## functions printing or outputting HTML: navigation
+
+sub git_page_nav {
+	my ($current, $suppress, $head, $treehead, $treebase, $extra) = @_;
+	$extra = '' if !defined $extra; # pager or formats
+
+	my @navs = qw(summary shortlog log commit commitdiff tree);
+	if ($suppress) {
+		@navs = grep { $_ ne $suppress } @navs;
+	}
+
+	my %arg = map { $_, ''} @navs;
+	if (defined $head) {
+		for (qw(commit commitdiff)) {
+			$arg{$_} = ";h=$head";
+		}
+		if ($current =~ m/^(tree | log | shortlog | commit | commitdiff | search)$/x) {
+			for (qw(shortlog log)) {
+				$arg{$_} = ";h=$head";
+			}
+		}
+	}
+	$arg{tree} .= ";h=$treehead" if defined $treehead;
+	$arg{tree} .= ";hb=$treebase" if defined $treebase;
+
+	print "<div class=\"page_nav\">\n" .
+		(join " | ",
+		 map { $_ eq $current
+					 ? $_
+					 : $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$_$arg{$_}")}, "$_")
+				 }
+		 @navs);
+	print "<br/>\n$extra<br/>\n" .
+	      "</div>\n";
+}
+
+sub git_get_paging_nav {
+	my ($action, $hash, $head, $page, $nrevs) = @_;
+	my $paging_nav;
+
+
+	if ($hash ne $head || $page) {
+		$paging_nav .= $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$action")}, "HEAD");
+	} else {
+		$paging_nav .= "HEAD";
+	}
+
+	if ($page > 0) {
+		$paging_nav .= " &sdot; " .
+			$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$action;h=$hash;pg=" . ($page-1)),
+							 -accesskey => "p", -title => "Alt-p"}, "prev");
+	} else {
+		$paging_nav .= " &sdot; prev";
+	}
+
+	if ($nrevs >= (100 * ($page+1)-1)) {
+		$paging_nav .= " &sdot; " .
+			$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$action;h=$hash;pg=" . ($page+1)),
+							 -accesskey => "n", -title => "Alt-n"}, "next");
+	} else {
+		$paging_nav .= " &sdot; next";
+	}
+
+	return $paging_nav;
+}
+
+## ......................................................................
+## functions printing or outputting HTML: div
+
+sub git_header_div {
+	my ($action, $title, $hash, $hash_base) = @_;
+	my $rest = '';
+
+	$rest .= ";h=$hash" if $hash;
+	$rest .= ";hb=$hash_base" if $hash_base;
+
+	print "<div class=\"header\">\n" .
+	      $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$action$rest"),
+	               -class => "title"}, $title ? $title : $action) . "\n" .
+	      "</div>\n";
+}
+
+sub git_print_page_path {
+	my $name = shift;
+	my $type = shift;
+
+	if (!defined $name) {
+		print "<div class=\"page_path\"><b>/</b></div>\n";
+	} elsif ($type =~ "blob") {
+		print "<div class=\"page_path\"><b>" .
+			$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;f=$file_name")}, esc_html($name)) . "</b><br/></div>\n";
+	} else {
+		print "<div class=\"page_path\"><b>" . esc_html($name) . "</b><br/></div>\n";
+	}
+}
+
+## ......................................................................
+## functions printing large fragments of HTML
+
 sub git_shortlog_body {
 	# uses global variable $project
 	my ($revlist, $from, $to, $refs, $extra) = @_;
@@ -1265,6 +1233,191 @@ sub git_heads_body {
 	print "</table>\n";
 }
 
+## ----------------------------------------------------------------------
+## functions printing large fragments, format as one of arguments
+
+sub git_diff_print {
+	my $from = shift;
+	my $from_name = shift;
+	my $to = shift;
+	my $to_name = shift;
+	my $format = shift || "html";
+
+	my $from_tmp = "/dev/null";
+	my $to_tmp = "/dev/null";
+	my $pid = $$;
+
+	# create tmp from-file
+	if (defined $from) {
+		$from_tmp = "$git_temp/gitweb_" . $$ . "_from";
+		open my $fd2, "> $from_tmp";
+		open my $fd, "-|", $GIT, "cat-file", "blob", $from;
+		my @file = <$fd>;
+		print $fd2 @file;
+		close $fd2;
+		close $fd;
+	}
+
+	# create tmp to-file
+	if (defined $to) {
+		$to_tmp = "$git_temp/gitweb_" . $$ . "_to";
+		open my $fd2, "> $to_tmp";
+		open my $fd, "-|", $GIT, "cat-file", "blob", $to;
+		my @file = <$fd>;
+		print $fd2 @file;
+		close $fd2;
+		close $fd;
+	}
+
+	open my $fd, "-|", "/usr/bin/diff -u -p -L \'$from_name\' -L \'$to_name\' $from_tmp $to_tmp";
+	if ($format eq "plain") {
+		undef $/;
+		print <$fd>;
+		$/ = "\n";
+	} else {
+		while (my $line = <$fd>) {
+			chomp $line;
+			my $char = substr($line, 0, 1);
+			my $diff_class = "";
+			if ($char eq '+') {
+				$diff_class = " add";
+			} elsif ($char eq "-") {
+				$diff_class = " rem";
+			} elsif ($char eq "@") {
+				$diff_class = " chunk_header";
+			} elsif ($char eq "\\") {
+				# skip errors
+				next;
+			}
+			while ((my $pos = index($line, "\t")) != -1) {
+				if (my $count = (8 - (($pos-1) % 8))) {
+					my $spaces = ' ' x $count;
+					$line =~ s/\t/$spaces/;
+				}
+			}
+			print "<div class=\"diff$diff_class\">" . esc_html($line) . "</div>\n";
+		}
+	}
+	close $fd;
+
+	if (defined $from) {
+		unlink($from_tmp);
+	}
+	if (defined $to) {
+		unlink($to_tmp);
+	}
+}
+
+
+## ======================================================================
+## ======================================================================
+## actions
+
+# git-logo (cached in browser for one day)
+sub git_logo {
+	binmode STDOUT, ':raw';
+	print $cgi->header(-type => 'image/png', -expires => '+1d');
+	# cat git-logo.png | hexdump -e '16/1 " %02x"  "\n"' | sed 's/ /\\x/g'
+	print	"\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52" .
+		"\x00\x00\x00\x48\x00\x00\x00\x1b\x04\x03\x00\x00\x00\x2d\xd9\xd4" .
+		"\x2d\x00\x00\x00\x18\x50\x4c\x54\x45\xff\xff\xff\x60\x60\x5d\xb0" .
+		"\xaf\xaa\x00\x80\x00\xce\xcd\xc7\xc0\x00\x00\xe8\xe8\xe6\xf7\xf7" .
+		"\xf6\x95\x0c\xa7\x47\x00\x00\x00\x73\x49\x44\x41\x54\x28\xcf\x63" .
+		"\x48\x67\x20\x04\x4a\x5c\x18\x0a\x08\x2a\x62\x53\x61\x20\x02\x08" .
+		"\x0d\x69\x45\xac\xa1\xa1\x01\x30\x0c\x93\x60\x36\x26\x52\x91\xb1" .
+		"\x01\x11\xd6\xe1\x55\x64\x6c\x6c\xcc\x6c\x6c\x0c\xa2\x0c\x70\x2a" .
+		"\x62\x06\x2a\xc1\x62\x1d\xb3\x01\x02\x53\xa4\x08\xe8\x00\x03\x18" .
+		"\x26\x56\x11\xd4\xe1\x20\x97\x1b\xe0\xb4\x0e\x35\x24\x71\x29\x82" .
+		"\x99\x30\xb8\x93\x0a\x11\xb9\x45\x88\xc1\x8d\xa0\xa2\x44\x21\x06" .
+		"\x27\x41\x82\x40\x85\xc1\x45\x89\x20\x70\x01\x00\xa4\x3d\x21\xc5" .
+		"\x12\x1c\x9a\xfe\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82";
+}
+
+sub git_project_list {
+	my @list = git_read_projects();
+	my @projects;
+	if (!@list) {
+		die_error(undef, "No project found.");
+	}
+	foreach my $pr (@list) {
+		my $head = git_read_head($pr->{'path'});
+		if (!defined $head) {
+			next;
+		}
+		$ENV{'GIT_DIR'} = "$projectroot/$pr->{'path'}";
+		my %co = git_read_commit($head);
+		if (!%co) {
+			next;
+		}
+		$pr->{'commit'} = \%co;
+		if (!defined $pr->{'descr'}) {
+			my $descr = git_read_description($pr->{'path'}) || "";
+			$pr->{'descr'} = chop_str($descr, 25, 5);
+		}
+		if (!defined $pr->{'owner'}) {
+			$pr->{'owner'} = get_file_owner("$projectroot/$pr->{'path'}") || "";
+		}
+		push @projects, $pr;
+	}
+	git_header_html();
+	if (-f $home_text) {
+		print "<div class=\"index_include\">\n";
+		open (my $fd, $home_text);
+		print <$fd>;
+		close $fd;
+		print "</div>\n";
+	}
+	print "<table class=\"project_list\">\n" .
+	      "<tr>\n";
+	if (!defined($order) || (defined($order) && ($order eq "project"))) {
+		@projects = sort {$a->{'path'} cmp $b->{'path'}} @projects;
+		print "<th>Project</th>\n";
+	} else {
+		print "<th>" . $cgi->a({-class => "header", -href => "$my_uri?" . esc_param("o=project")}, "Project") . "</th>\n";
+	}
+	if (defined($order) && ($order eq "descr")) {
+		@projects = sort {$a->{'descr'} cmp $b->{'descr'}} @projects;
+		print "<th>Description</th>\n";
+	} else {
+		print "<th>" . $cgi->a({-class => "header", -href => "$my_uri?" . esc_param("o=descr")}, "Description") . "</th>\n";
+	}
+	if (defined($order) && ($order eq "owner")) {
+		@projects = sort {$a->{'owner'} cmp $b->{'owner'}} @projects;
+		print "<th>Owner</th>\n";
+	} else {
+		print "<th>" . $cgi->a({-class => "header", -href => "$my_uri?" . esc_param("o=owner")}, "Owner") . "</th>\n";
+	}
+	if (defined($order) && ($order eq "age")) {
+		@projects = sort {$a->{'commit'}{'age'} <=> $b->{'commit'}{'age'}} @projects;
+		print "<th>Last Change</th>\n";
+	} else {
+		print "<th>" . $cgi->a({-class => "header", -href => "$my_uri?" . esc_param("o=age")}, "Last Change") . "</th>\n";
+	}
+	print "<th></th>\n" .
+	      "</tr>\n";
+	my $alternate = 0;
+	foreach my $pr (@projects) {
+		if ($alternate) {
+			print "<tr class=\"dark\">\n";
+		} else {
+			print "<tr class=\"light\">\n";
+		}
+		$alternate ^= 1;
+		print "<td>" . $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=summary"), -class => "list"}, esc_html($pr->{'path'})) . "</td>\n" .
+		      "<td>" . esc_html($pr->{'descr'}) . "</td>\n" .
+		      "<td><i>" . chop_str($pr->{'owner'}, 15) . "</i></td>\n";
+		print "<td class=\"". age_class($pr->{'commit'}{'age'}) . "\">" . $pr->{'commit'}{'age_string'} . "</td>\n" .
+		      "<td class=\"link\">" .
+		      $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=summary")}, "summary") .
+		      " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=shortlog")}, "shortlog") .
+		      " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=log")}, "log") .
+		      "</td>\n" .
+		      "</tr>\n";
+	}
+	print "</table>\n";
+	git_footer_html();
+}
+
 sub git_summary {
 	my $descr = git_read_description($project) || "none";
 	my $head = git_read_head($project);
@@ -1326,20 +1479,6 @@ sub git_summary {
 	git_footer_html();
 }
 
-sub git_print_page_path {
-	my $name = shift;
-	my $type = shift;
-
-	if (!defined $name) {
-		print "<div class=\"page_path\"><b>/</b></div>\n";
-	} elsif ($type =~ "blob") {
-		print "<div class=\"page_path\"><b>" .
-			$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;f=$file_name")}, esc_html($name)) . "</b><br/></div>\n";
-	} else {
-		print "<div class=\"page_path\"><b>" . esc_html($name) . "</b><br/></div>\n";
-	}
-}
-
 sub git_tag {
 	my $head = git_read_head($project);
 	git_header_html();
@@ -1546,84 +1685,6 @@ sub git_heads {
 	git_footer_html();
 }
 
-sub git_get_hash_by_path {
-	my $base = shift;
-	my $path = shift || return undef;
-
-	my $tree = $base;
-
-	open my $fd, "-|", $GIT, "ls-tree", $base, "--", $path
-		or die_error(undef, "Open git-ls-tree failed.");
-	my $line = <$fd>;
-	close $fd or return undef;
-
-	#'100644 blob 0fa3f3a66fb6a137f6ec2c19351ed4d807070ffa	panic.c'
-	$line =~ m/^([0-9]+) (.+) ([0-9a-fA-F]{40})\t(.+)$/;
-	return $3;
-}
-
-sub mimetype_guess_file {
-	my $filename = shift;
-	my $mimemap = shift;
-	-r $mimemap or return undef;
-
-	my %mimemap;
-	open(MIME, $mimemap) or return undef;
-	while (<MIME>) {
-		my ($mime, $exts) = split(/\t+/);
-		my @exts = split(/\s+/, $exts);
-		foreach my $ext (@exts) {
-			$mimemap{$ext} = $mime;
-		}
-	}
-	close(MIME);
-
-	$filename =~ /\.(.*?)$/;
-	return $mimemap{$1};
-}
-
-sub mimetype_guess {
-	my $filename = shift;
-	my $mime;
-	$filename =~ /\./ or return undef;
-
-	if ($mimetypes_file) {
-		my $file = $mimetypes_file;
-		#$file =~ m#^/# or $file = "$projectroot/$path/$file";
-		$mime = mimetype_guess_file($filename, $file);
-	}
-	$mime ||= mimetype_guess_file($filename, '/etc/mime.types');
-	return $mime;
-}
-
-sub git_blob_plain_mimetype {
-	my $fd = shift;
-	my $filename = shift;
-
-	if ($filename) {
-		my $mime = mimetype_guess($filename);
-		$mime and return $mime;
-	}
-
-	# just in case
-	return $default_blob_plain_mimetype unless $fd;
-
-	if (-T $fd) {
-		return 'text/plain' .
-		       ($default_text_plain_charset ? '; charset='.$default_text_plain_charset : '');
-	} elsif (! $filename) {
-		return 'application/octet-stream';
-	} elsif ($filename =~ m/\.png$/i) {
-		return 'image/png';
-	} elsif ($filename =~ m/\.gif$/i) {
-		return 'image/gif';
-	} elsif ($filename =~ m/\.jpe?g$/i) {
-		return 'image/jpeg';
-	} else {
-		return 'application/octet-stream';
-	}
-}
-
 sub git_blob_plain {
 	if (!defined $hash) {
 		if (defined $file_name) {
@@ -1793,98 +1854,6 @@ #			      " | " . $cgi->a({-href => "$my
 	git_footer_html();
 }
 
-sub git_rss {
-	# http://www.notestips.com/80256B3A007F2692/1/NAMO5P9UPQ
-	open my $fd, "-|", $GIT, "rev-list", "--max-count=150", git_read_head($project) 
-		or die_error(undef, "Open git-rev-list failed.");
-	my @revlist = map { chomp; $_ } <$fd>;
-	close $fd or die_error(undef, "Reading rev-list failed.");
-	print $cgi->header(-type => 'text/xml', -charset => 'utf-8');
-	print "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n".
-	      "<rss version=\"2.0\" xmlns:content=\"http://purl.org/rss/1.0/modules/content/\">\n";
-	print "<channel>\n";
-	print "<title>$project</title>\n".
-	      "<link>" . esc_html("$my_url?p=$project;a=summary") . "</link>\n".
-	      "<description>$project log</description>\n".
-	      "<language>en</language>\n";
-
-	for (my $i = 0; $i <= $#revlist; $i++) {
-		my $commit = $revlist[$i];
-		my %co = git_read_commit($commit);
-		# we read 150, we always show 30 and the ones more recent than 48 hours
-		if (($i >= 20) && ((time - $co{'committer_epoch'}) > 48*60*60)) {
-			last;
-		}
-		my %cd = date_str($co{'committer_epoch'});
-		open $fd, "-|", $GIT, "diff-tree", '-r', $co{'parent'}, $co{'id'} or next;
-		my @difftree = map { chomp; $_ } <$fd>;
-		close $fd or next;
-		print "<item>\n" .
-		      "<title>" .
-		      sprintf("%d %s %02d:%02d", $cd{'mday'}, $cd{'month'}, $cd{'hour'}, $cd{'minute'}) . " - " . esc_html($co{'title'}) .
-		      "</title>\n" .
-		      "<author>" . esc_html($co{'author'}) . "</author>\n" .
-		      "<pubDate>$cd{'rfc2822'}</pubDate>\n" .
-		      "<guid isPermaLink=\"true\">" . esc_html("$my_url?p=$project;a=commit;h=$commit") . "</guid>\n" .
-		      "<link>" . esc_html("$my_url?p=$project;a=commit;h=$commit") . "</link>\n" .
-		      "<description>" . esc_html($co{'title'}) . "</description>\n" .
-		      "<content:encoded>" .
-		      "<![CDATA[\n";
-		my $comment = $co{'comment'};
-		foreach my $line (@$comment) {
-			$line = decode("utf8", $line, Encode::FB_DEFAULT);
-			print "$line<br/>\n";
-		}
-		print "<br/>\n";
-		foreach my $line (@difftree) {
-			if (!($line =~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)([0-9]{0,3})\t(.*)$/)) {
-				next;
-			}
-			my $file = validate_input(unquote($7));
-			$file = decode("utf8", $file, Encode::FB_DEFAULT);
-			print "$file<br/>\n";
-		}
-		print "]]>\n" .
-		      "</content:encoded>\n" .
-		      "</item>\n";
-	}
-	print "</channel></rss>";
-}
-
-sub git_opml {
-	my @list = git_read_projects();
-
-	print $cgi->header(-type => 'text/xml', -charset => 'utf-8');
-	print "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n".
-	      "<opml version=\"1.0\">\n".
-	      "<head>".
-	      "  <title>$site_name Git OPML Export</title>\n".
-	      "</head>\n".
-	      "<body>\n".
-	      "<outline text=\"git RSS feeds\">\n";
-
-	foreach my $pr (@list) {
-		my %proj = %$pr;
-		my $head = git_read_head($proj{'path'});
-		if (!defined $head) {
-			next;
-		}
-		$ENV{'GIT_DIR'} = "$projectroot/$proj{'path'}";
-		my %co = git_read_commit($head);
-		if (!%co) {
-			next;
-		}
-
-		my $path = esc_html(chop_str($proj{'path'}, 25, 5));
-		my $rss  = "$my_url?p=$proj{'path'};a=rss";
-		my $html = "$my_url?p=$proj{'path'};a=summary";
-		print "<outline type=\"rss\" text=\"$path\" title=\"$path\" xmlUrl=\"$rss\" htmlUrl=\"$html\"/>\n";
-	}
-	print "</outline>\n".
-	      "</body>\n".
-	      "</opml>\n";
-}
-
 sub git_log {
 	my $head = git_read_head($project);
 	if (!defined $hash) {
@@ -2556,3 +2525,98 @@ sub git_shortlog {
 
 	git_footer_html();
 }
+
+## ......................................................................
+## feeds (RSS, OPML)
+
+sub git_rss {
+	# http://www.notestips.com/80256B3A007F2692/1/NAMO5P9UPQ
+	open my $fd, "-|", $GIT, "rev-list", "--max-count=150", git_read_head($project)
+		or die_error(undef, "Open git-rev-list failed.");
+	my @revlist = map { chomp; $_ } <$fd>;
+	close $fd or die_error(undef, "Reading rev-list failed.");
+	print $cgi->header(-type => 'text/xml', -charset => 'utf-8');
+	print "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n".
+	      "<rss version=\"2.0\" xmlns:content=\"http://purl.org/rss/1.0/modules/content/\">\n";
+	print "<channel>\n";
+	print "<title>$project</title>\n".
+	      "<link>" . esc_html("$my_url?p=$project;a=summary") . "</link>\n".
+	      "<description>$project log</description>\n".
+	      "<language>en</language>\n";
+
+	for (my $i = 0; $i <= $#revlist; $i++) {
+		my $commit = $revlist[$i];
+		my %co = git_read_commit($commit);
+		# we read 150, we always show 30 and the ones more recent than 48 hours
+		if (($i >= 20) && ((time - $co{'committer_epoch'}) > 48*60*60)) {
+			last;
+		}
+		my %cd = date_str($co{'committer_epoch'});
+		open $fd, "-|", $GIT, "diff-tree", '-r', $co{'parent'}, $co{'id'} or next;
+		my @difftree = map { chomp; $_ } <$fd>;
+		close $fd or next;
+		print "<item>\n" .
+		      "<title>" .
+		      sprintf("%d %s %02d:%02d", $cd{'mday'}, $cd{'month'}, $cd{'hour'}, $cd{'minute'}) . " - " . esc_html($co{'title'}) .
+		      "</title>\n" .
+		      "<author>" . esc_html($co{'author'}) . "</author>\n" .
+		      "<pubDate>$cd{'rfc2822'}</pubDate>\n" .
+		      "<guid isPermaLink=\"true\">" . esc_html("$my_url?p=$project;a=commit;h=$commit") . "</guid>\n" .
+		      "<link>" . esc_html("$my_url?p=$project;a=commit;h=$commit") . "</link>\n" .
+		      "<description>" . esc_html($co{'title'}) . "</description>\n" .
+		      "<content:encoded>" .
+		      "<![CDATA[\n";
+		my $comment = $co{'comment'};
+		foreach my $line (@$comment) {
+			$line = decode("utf8", $line, Encode::FB_DEFAULT);
+			print "$line<br/>\n";
+		}
+		print "<br/>\n";
+		foreach my $line (@difftree) {
+			if (!($line =~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)([0-9]{0,3})\t(.*)$/)) {
+				next;
+			}
+			my $file = validate_input(unquote($7));
+			$file = decode("utf8", $file, Encode::FB_DEFAULT);
+			print "$file<br/>\n";
+		}
+		print "]]>\n" .
+		      "</content:encoded>\n" .
+		      "</item>\n";
+	}
+	print "</channel></rss>";
+}
+
+sub git_opml {
+	my @list = git_read_projects();
+
+	print $cgi->header(-type => 'text/xml', -charset => 'utf-8');
+	print "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n".
+	      "<opml version=\"1.0\">\n".
+	      "<head>".
+	      "  <title>$site_name Git OPML Export</title>\n".
+	      "</head>\n".
+	      "<body>\n".
+	      "<outline text=\"git RSS feeds\">\n";
+
+	foreach my $pr (@list) {
+		my %proj = %$pr;
+		my $head = git_read_head($proj{'path'});
+		if (!defined $head) {
+			next;
+		}
+		$ENV{'GIT_DIR'} = "$projectroot/$proj{'path'}";
+		my %co = git_read_commit($head);
+		if (!%co) {
+			next;
+		}
+
+		my $path = esc_html(chop_str($proj{'path'}, 25, 5));
+		my $rss  = "$my_url?p=$proj{'path'};a=rss";
+		my $html = "$my_url?p=$proj{'path'};a=summary";
+		print "<outline type=\"rss\" text=\"$path\" title=\"$path\" xmlUrl=\"$rss\" htmlUrl=\"$html\"/>\n";
+	}
+	print "</outline>\n".
+	      "</body>\n".
+	      "</opml>\n";
+}
-- 
1.4.1.1

^ permalink raw reply related

* Fix up some fallout from "setup_git_directory()" cleanups
From: Linus Torvalds @ 2006-07-31 20:13 UTC (permalink / raw)
  To: Junio C Hamano, Git Mailing List


git-ls-files was broken by the setup_git_directory() calling changes, 
because I had missed the fact that the "prefix" variable in that file was 
static to the whole file, and unlike git-ls-tree (where I had fixed it 
up), it ended up using two different variables with the same name 
depending on what the scoping happened to be.

This fixes it up properly (by just removing the static variable, and 
passing the automatic one around properly), and git-ls-files should work 
again.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---

Sorry about that.

diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index 79ffe8f..11386c4 100644
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
@@ -24,7 +24,6 @@ static int show_valid_bit = 0;
 static int line_terminator = '\n';
 
 static int prefix_len = 0, prefix_offset = 0;
-static const char *prefix = NULL;
 static const char **pathspec = NULL;
 static int error_unmatch = 0;
 static char *ps_matched = NULL;
@@ -207,7 +206,7 @@ static void show_ce_entry(const char *ta
 	}
 }
 
-static void show_files(struct dir_struct *dir)
+static void show_files(struct dir_struct *dir, const char *prefix)
 {
 	int i;
 
@@ -253,7 +252,7 @@ static void show_files(struct dir_struct
 /*
  * Prune the index to only contain stuff starting with "prefix"
  */
-static void prune_cache(void)
+static void prune_cache(const char *prefix)
 {
 	int pos = cache_name_pos(prefix, prefix_len);
 	unsigned int first, last;
@@ -276,7 +275,7 @@ static void prune_cache(void)
 	active_nr = last;
 }
 
-static void verify_pathspec(void)
+static const char *verify_pathspec(const char *prefix)
 {
 	const char **p, *n, *prev;
 	char *real_prefix;
@@ -313,7 +312,7 @@ static void verify_pathspec(void)
 		memcpy(real_prefix, prev, max);
 		real_prefix[max] = 0;
 	}
-	prefix = real_prefix;
+	return real_prefix;
 }
 
 static const char ls_files_usage[] =
@@ -453,7 +452,7 @@ int cmd_ls_files(int argc, const char **
 
 	/* Verify that the pathspec matches the prefix */
 	if (pathspec)
-		verify_pathspec();
+		prefix = verify_pathspec(prefix);
 
 	/* Treat unmatching pathspec elements as errors */
 	if (pathspec && error_unmatch) {
@@ -476,8 +475,8 @@ int cmd_ls_files(int argc, const char **
 
 	read_cache();
 	if (prefix)
-		prune_cache();
-	show_files(&dir);
+		prune_cache(prefix);
+	show_files(&dir, prefix);
 
 	if (ps_matched) {
 		/* We need to make sure all pathspec matched otherwise

^ permalink raw reply related

* Re: gitweb: how to name main "action" subroutines?
From: Josef Weidendorfer @ 2006-07-31 20:41 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <ealj3h$to2$1@sea.gmane.org>

On Monday 31 July 2006 20:45, Jakub Narebski wrote:
> Josef Weidendorfer wrote:
> 
> > On Monday 31 July 2006 16:03, you wrote:
> >> I'm going to rename some gitweb subroutines to better correspond to what
> >> given subroutine does. I have problem: how to name main "action"
> >> subroutines? Currently they use git_ prefix, e.g. git_logo.
> >> git_project_list, git_rss, git_summary, git_heads,...
> > 
> > print_* or write_* ?
> > At least, the functions print/write the HTML code to stdout of the script.
> 
> The problem is that there are subroutines which print _fragments_ of HTML
> code (like git_header_html or git_print_page_path) which would use probably
> print_ prefix. Action subroutines output always whole page.

Why not "print_*_page", if they print out a whole page?
I would "git_header_html" rename to "print_header"; it's clear that
it prints out HTML ;-)
And "git_print_page_path" only needs stripping of "git_" prefix.

Josef

^ permalink raw reply

* Diff format in packs
From: Jon Smirl @ 2006-07-31 21:08 UTC (permalink / raw)
  To: git

I see how the diffs are encoded into the pack, but what did they look
like before compressing? It would be great if they looked like CVS
diffs. I poked around in the doc and I don't see anything. Is this
specified somewhere and I missed it? I see that the diff code is from
libxdiff  but I haven't figured out how it is being used yet.

I'm trying to build a small app that takes a CVS ,v and writes out a
pack corresponding to the versions. Suggestions on the most efficient
strategy for doing this by calling straight into the git C code?
Forking off git commands is not very efficient when done a million
times.

-- 
Jon Smirl
jonsmirl@gmail.com

^ permalink raw reply

* Re: Diff format in packs
From: Jakub Narebski @ 2006-07-31 21:16 UTC (permalink / raw)
  To: git
In-Reply-To: <9e4733910607311408i10e17dse776920de7c5076a@mail.gmail.com>

Jon Smirl wrote:

> I'm trying to build a small app that takes a CVS ,v and writes out a
> pack corresponding to the versions. Suggestions on the most efficient
> strategy for doing this by calling straight into the git C code?
> Forking off git commands is not very efficient when done a million
> times.

Something akin to parsecvs by Keith Packard?

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply

* Re: Diff format in packs
From: Jon Smirl @ 2006-07-31 21:20 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <ealruh$sq9$1@sea.gmane.org>

On 7/31/06, Jakub Narebski <jnareb@gmail.com> wrote:
> Jon Smirl wrote:
>
> > I'm trying to build a small app that takes a CVS ,v and writes out a
> > pack corresponding to the versions. Suggestions on the most efficient
> > strategy for doing this by calling straight into the git C code?
> > Forking off git commands is not very efficient when done a million
> > times.
>
> Something akin to parsecvs by Keith Packard?

I see the error in my thoughts now, I need the fully expanded delta to
compute the sha-1 so I might as well use the parsecvs code.

I am working on combining cvs2svn, parsecvs and cvsps into something
that can handle Mozilla CVS.

-- 
Jon Smirl
jonsmirl@gmail.com

^ permalink raw reply

* Re: [PATCH] gitweb: fill in gitweb configuration by Makefile
From: Jon Loeliger @ 2006-07-31 21:33 UTC (permalink / raw)
  To: ltuikov; +Cc: Martin Waitz, Git List
In-Reply-To: <20060731035737.24181.qmail@web31803.mail.mud.yahoo.com>

On Sun, 2006-07-30 at 22:57, Luben Tuikov wrote:
> --- Martin Waitz <tali@admingilde.org> wrote:
> > Generate gitweb/gitweb.cgi to reduce the need to patch gitweb.cgi by
> > the end user.
> > The GIT installation directory and version are already known by the
> > Makefile, they can be inserted directly into gitweb.
> > All other gitweb configuration parameters can now be specified
> > by providing GITWEB_* variables while building GIT.
> > These are described in gitweb/README.
> 
> NACK.
> 
> I don't like it.  While this method works, it is too much effort
> to have to run make to do this, plus it pollutes your tree.
> 
> Instead, what you can do is make gitweb.cgi read a text file
> from . which has those variables defined.
> 
> This way, I can just copy gitweb.cgi into my web-server directory
> and voila it works, since the variable definition file would
> always be there.  This way:
>   - no need to run make to build "gitweb.cgi" or "gitweb.pl" whatever
>     you call it,
>   - no need to pollute your tree with site defined variables,
>   - simple copy (cp) would install a working version, instead of
>     the current cp + patch with local settings method.
> 
>    Luben

Which sounds frighteningly similar to a patch I submitted
quite a while ago, and brought up again twice, and have
had stomped on once.

So what now? :-)

jdl

^ permalink raw reply

* [PATCH] gitweb: use a hash to lookup the sub for an action
From: Matthias Lederhofer @ 2006-07-31 21:46 UTC (permalink / raw)
  To: git
In-Reply-To: <200607292239.11034.jnareb@gmail.com>

Signed-off-by: Matthias Lederhofer <matled@gmx.net>
---
 gitweb/gitweb.cgi |   81 ++++++++++++++++-------------------------------------
 1 files changed, 25 insertions(+), 56 deletions(-)

diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi
index c1ee79e..75390c8 100755
--- a/gitweb/gitweb.cgi
+++ b/gitweb/gitweb.cgi
@@ -161,65 +161,34 @@ if (defined $searchtext) {
 }
 
 # dispatch
-if (!defined $action || $action eq "summary") {
-	git_summary();
-	exit;
-} elsif ($action eq "heads") {
-	git_heads();
-	exit;
-} elsif ($action eq "tags") {
-	git_tags();
-	exit;
-} elsif ($action eq "blob") {
-	git_blob();
-	exit;
-} elsif ($action eq "blob_plain") {
-	git_blob_plain();
-	exit;
-} elsif ($action eq "tree") {
-	git_tree();
-	exit;
-} elsif ($action eq "rss") {
-	git_rss();
-	exit;
-} elsif ($action eq "commit") {
-	git_commit();
-	exit;
-} elsif ($action eq "log") {
-	git_log();
-	exit;
-} elsif ($action eq "blobdiff") {
-	git_blobdiff();
-	exit;
-} elsif ($action eq "blobdiff_plain") {
-	git_blobdiff_plain();
-	exit;
-} elsif ($action eq "commitdiff") {
-	git_commitdiff();
-	exit;
-} elsif ($action eq "commitdiff_plain") {
-	git_commitdiff_plain();
-	exit;
-} elsif ($action eq "history") {
-	git_history();
-	exit;
-} elsif ($action eq "search") {
-	git_search();
-	exit;
-} elsif ($action eq "shortlog") {
-	git_shortlog();
-	exit;
-} elsif ($action eq "tag") {
-	git_tag();
-	exit;
-} elsif ($action eq "blame") {
-	git_blame2();
-	exit;
-} else {
+my %actions = (
+	"blame" => \&git_blame2,
+	"blobdiff" => \&git_blobdiff,
+	"blobdiff_plain" => \&git_blobdiff_plain,
+	"blob" => \&git_blob,
+	"blob_plain" => \&git_blob_plain,
+	"commitdiff" => \&git_commitdiff,
+	"commitdiff_plain" => \&git_commitdiff_plain,
+	"commit" => \&git_commit,
+	"heads" => \&git_heads,
+	"history" => \&git_history,
+	"log" => \&git_log,
+	"rss" => \&git_rss,
+	"search" => \&git_search,
+	"shortlog" => \&git_shortlog,
+	"summary" => \&git_summary,
+	"tag" => \&git_tag,
+	"tags" => \&git_tags,
+	"tree" => \&git_tree,
+);
+
+$action = 'summary' if (!defined($action));
+if (!defined($actions{$action})) {
 	undef $action;
 	die_error(undef, "Unknown action.");
-	exit;
 }
+$actions{$action}->();
+exit;
 
 ## ======================================================================
 ## validation, quoting/unquoting and escaping
-- 
1.4.2.rc2.ge0bed

^ permalink raw reply related

* Re: Fix up some fallout from "setup_git_directory()" cleanups
From: Junio C Hamano @ 2006-07-31 21:56 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0607311311060.4168@g5.osdl.org>

Linus Torvalds <torvalds@osdl.org> writes:

> git-ls-files was broken by the setup_git_directory() calling changes, 
> because I had missed the fact that the "prefix" variable in that file was 
> static to the whole file, and unlike git-ls-tree (where I had fixed it 
> up), it ended up using two different variables with the same name 
> depending on what the scoping happened to be.

This would have been prevented if the rest of the sources were -Wshadow
clean.  I once tried to clean things up, but there are tons of
warnings in the current code [*1*].

Another thing that would help us is to have more tests that run
things from subdirectories.  Any takers?


[Footnote]

*1* They are mostly local variables masking unrelated system
    library function names.


This deletes more lines than it adds, but I am not sure if it is
worth it.

-- >8 --
Subject: [PATCH] -Wshadow

This renames local variables and parameters to avoid -Wshadow warnings.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---
 blame.c                 |    9 ++--
 builtin-apply.c         |   36 ++++++++--------
 builtin-diff.c          |    1 
 builtin-fmt-merge-msg.c |    8 ++--
 builtin-grep.c          |    2 -
 builtin-help.c          |    6 +--
 builtin-ls-files.c      |   10 ++---
 builtin-mailinfo.c      |  103 ++++++++++++++++++++++++-----------------------
 builtin-mv.c            |    6 +--
 builtin-prune.c         |    8 ++--
 builtin-push.c          |   10 ++---
 builtin-read-tree.c     |   78 ++++++++++++++++++------------------
 builtin-rev-list.c      |    8 ++--
 builtin-show-branch.c   |    9 ++--
 cache.h                 |    6 +--
 config.c                |    4 +-
 convert-objects.c       |   10 ++---
 daemon.c                |    2 -
 date.c                  |   30 +++++++-------
 delta.h                 |   12 +++--
 diff-delta.c            |   34 ++++++++--------
 fetch-clone.c           |   14 +++---
 fetch.c                 |    6 +--
 fsck-objects.c          |    1 
 git.c                   |    6 +--
 http-fetch.c            |   26 ++++++------
 http-push.c             |   28 ++++++-------
 merge-tree.c            |   18 ++++----
 pack-check.c            |    1 
 pack-objects.c          |   36 ++++++++--------
 path-list.c             |   24 +++++------
 revision.c              |    2 -
 setup.c                 |    2 -
 sha1_file.c             |   60 ++++++++++++++-------------
 tree-walk.c             |   10 ++---
 xdiff/xprepare.c        |    8 ++--
 36 files changed, 315 insertions(+), 319 deletions(-)

diff --git a/blame.c b/blame.c
index 76712b5..2e8bbe7 100644
--- a/blame.c
+++ b/blame.c
@@ -428,7 +428,6 @@ static void process_commits(struct rev_i
 	do {
 		struct commit_list *parents;
 		int num_parents;
-		struct util_info *util;
 
 		if (DEBUG)
 			printf("\nProcessing commit: %d %s\n", num_commits,
@@ -682,16 +681,16 @@ static void get_commit_info(struct commi
 	*tmp = 0;
 }
 
-static const char* format_time(unsigned long time, const char* tz_str,
+static const char* format_time(unsigned long unix_time, const char* tz_str,
 			       int show_raw_time)
 {
 	static char time_buf[128];
-	time_t t = time;
+	time_t t = unix_time;
 	int minutes, tz;
 	struct tm *tm;
 
 	if (show_raw_time) {
-		sprintf(time_buf, "%lu %s", time, tz_str);
+		sprintf(time_buf, "%lu %s", unix_time, tz_str);
 		return time_buf;
 	}
 
@@ -699,7 +698,7 @@ static const char* format_time(unsigned 
 	minutes = tz < 0 ? -tz : tz;
 	minutes = (minutes / 100)*60 + (minutes % 100);
 	minutes = tz < 0 ? -minutes : minutes;
-	t = time + minutes * 60;
+	t = unix_time + minutes * 60;
 	tm = gmtime(&t);
 
 	strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S ", tm);
diff --git a/builtin-apply.c b/builtin-apply.c
index f8c6763..25454dd 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -199,7 +199,7 @@ static int name_terminate(const char *na
 	return 1;
 }
 
-static char * find_name(const char *line, char *def, int p_value, int terminate)
+static char * find_name(const char *line, char *def, int p_val, int terminate)
 {
 	int len;
 	const char *start = line;
@@ -212,12 +212,12 @@ static char * find_name(const char *line
 		name = unquote_c_style(line, NULL);
 		if (name) {
 			char *cp = name;
-			while (p_value) {
+			while (p_val) {
 				cp = strchr(name, '/');
 				if (!cp)
 					break;
 				cp++;
-				p_value--;
+				p_val--;
 			}
 			if (cp) {
 				/* name can later be freed, so we need
@@ -244,7 +244,7 @@ static char * find_name(const char *line
 				break;
 		}
 		line++;
-		if (c == '/' && !--p_value)
+		if (c == '/' && !--p_val)
 			start = line;
 	}
 	if (!start)
@@ -601,7 +601,7 @@ static char *git_header_name(char *line,
 		case '\t': case ' ':
 			second = name+len;
 			for (;;) {
-				char c = *second++;
+				c = *second++;
 				if (c == '\n')
 					return NULL;
 				if (c == '/')
@@ -1152,7 +1152,7 @@ static const char minuses[]= "----------
 
 static void show_stats(struct patch *patch)
 {
-	const char *prefix = "";
+	const char *leading = "";
 	char *name = patch->new_name;
 	char *qname = NULL;
 	int len, max, add, del, total;
@@ -1175,7 +1175,7 @@ static void show_stats(struct patch *pat
 		max = 50;
 	if (len > max) {
 		char *slash;
-		prefix = "...";
+		leading = "...";
 		max -= 3;
 		name += len - max;
 		slash = strchr(name, '/');
@@ -1201,9 +1201,9 @@ static void show_stats(struct patch *pat
 		del = total - add;
 	}
 	if (patch->is_binary)
-		printf(" %s%-*s |  Bin\n", prefix, len, name);
+		printf(" %s%-*s |  Bin\n", leading, len, name);
 	else
-		printf(" %s%-*s |%5d %.*s%.*s\n", prefix,
+		printf(" %s%-*s |%5d %.*s%.*s\n", leading,
 		       len, name, patch->lines_added + patch->lines_deleted,
 		       add, pluses, del, minuses);
 	if (qname)
@@ -1453,7 +1453,7 @@ static int apply_one_fragment(struct buf
 			offset = -1;
 		if (offset >= 0) {
 			int diff = newsize - oldsize;
-			unsigned long size = desc->size + diff;
+			unsigned long sz = desc->size + diff;
 			unsigned long alloc = desc->alloc;
 
 			/* Warn if it was necessary to reduce the number
@@ -1463,14 +1463,14 @@ static int apply_one_fragment(struct buf
 				fprintf(stderr, "Context reduced to (%ld/%ld) to apply fragment at %d\n",
 					leading, trailing, pos + lines);
 
-			if (size > alloc) {
-				alloc = size + 8192;
+			if (sz > alloc) {
+				alloc = sz + 8192;
 				desc->alloc = alloc;
 				buf = xrealloc(buf, alloc);
 				desc->buffer = buf;
 			}
-			desc->size = size;
-			memmove(buf + offset + newsize, buf + offset + oldsize, size - offset - newsize);
+			desc->size = sz;
+			memmove(buf + offset + newsize, buf + offset + oldsize, sz - offset - newsize);
 			memcpy(buf + offset, newlines, newsize);
 			offset = 0;
 
@@ -1827,13 +1827,13 @@ static int check_patch(struct patch *pat
 static int check_patch_list(struct patch *patch)
 {
 	struct patch *prev_patch = NULL;
-	int error = 0;
+	int err = 0;
 
 	for (prev_patch = NULL; patch ; patch = patch->next) {
-		error |= check_patch(patch, prev_patch);
+		err |= check_patch(patch, prev_patch);
 		prev_patch = patch;
 	}
-	return error;
+	return err;
 }
 
 static inline int is_null_sha1(const unsigned char *sha1)
@@ -2268,7 +2268,7 @@ static int git_apply_config(const char *
 }
 
 
-int cmd_apply(int argc, const char **argv, const char *prefix)
+int cmd_apply(int argc, const char **argv, const char *unused_prefix)
 {
 	int i;
 	int read_stdin = 1;
diff --git a/builtin-diff.c b/builtin-diff.c
index 48d2fd0..44c39b0 100644
--- a/builtin-diff.c
+++ b/builtin-diff.c
@@ -263,7 +263,6 @@ int cmd_diff(int argc, const char **argv
 	 * default to HEAD by hand.  Eek.
 	 */
 	if (!rev.pending.nr) {
-		int i;
 		for (i = 1; i < argc; i++) {
 			const char *arg = argv[i];
 			if (!strcmp(arg, "--"))
diff --git a/builtin-fmt-merge-msg.c b/builtin-fmt-merge-msg.c
index c84224e..0c8d50d 100644
--- a/builtin-fmt-merge-msg.c
+++ b/builtin-fmt-merge-msg.c
@@ -138,7 +138,7 @@ static int handle_line(char *line)
 	}
 
 	if (!strcmp(".", src) || !strcmp(src, origin)) {
-		int len = strlen(origin);
+		len = strlen(origin);
 		if (origin[0] == '\'' && origin[len - 1] == '\'') {
 			char *new_origin = malloc(len - 1);
 			memcpy(new_origin, origin + 1, len - 2);
@@ -338,10 +338,10 @@ int cmd_fmt_merge_msg(int argc, char **a
 		printf(" into %s\n", current_branch);
 
 	if (merge_summary) {
-		struct commit *head;
+		struct commit *head_commit;
 		struct rev_info rev;
 
-		head = lookup_commit(head_sha1);
+		head_commit = lookup_commit(head_sha1);
 		init_revisions(&rev, prefix);
 		rev.commit_format = CMIT_FMT_ONELINE;
 		rev.ignore_merges = 1;
@@ -349,7 +349,7 @@ int cmd_fmt_merge_msg(int argc, char **a
 
 		for (i = 0; i < origins.nr; i++)
 			shortlog(origins.list[i], origins.payload[i],
-					head, &rev, limit);
+				 head_commit, &rev, limit);
 	}
 
 	/* No cleanup yet; is standalone anyway */
diff --git a/builtin-grep.c b/builtin-grep.c
index 69b7c48..64cb1eb 100644
--- a/builtin-grep.c
+++ b/builtin-grep.c
@@ -783,7 +783,7 @@ static int external_grep(struct grep_opt
 			continue;
 		name = ce->name;
 		if (name[0] == '-') {
-			int len = ce_namelen(ce);
+			len = ce_namelen(ce);
 			name = xmalloc(len + 3);
 			memcpy(name, "./", 2);
 			memcpy(name + 2, ce->name, len + 1);
diff --git a/builtin-help.c b/builtin-help.c
index bb0b03f..f86a7c7 100644
--- a/builtin-help.c
+++ b/builtin-help.c
@@ -77,7 +77,7 @@ static int cmdname_compare(const void *a
 	return strcmp(a->name, b->name);
 }
 
-static void pretty_print_string_list(struct cmdname **cmdname, int longest)
+static void pretty_print_string_list(struct cmdname **name, int longest)
 {
 	int cols = 1, rows;
 	int space = longest + 1; /* min 1 SP between words */
@@ -88,7 +88,7 @@ static void pretty_print_string_list(str
 		cols = max_cols / space;
 	rows = (cmdname_cnt + cols - 1) / cols;
 
-	qsort(cmdname, cmdname_cnt, sizeof(*cmdname), cmdname_compare);
+	qsort(name, cmdname_cnt, sizeof(*name), cmdname_compare);
 
 	for (i = 0; i < rows; i++) {
 		printf("  ");
@@ -100,7 +100,7 @@ static void pretty_print_string_list(str
 				break;
 			if (j == cols-1 || n + rows >= cmdname_cnt)
 				size = 1;
-			printf("%-*s", size, cmdname[n]->name);
+			printf("%-*s", size, name[n]->name);
 		}
 		putchar('\n');
 	}
diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index 11386c4..17ec3d2 100644
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
@@ -40,7 +40,7 @@ static const char *tag_modified = "";
  * Match a pathspec against a filename. The first "len" characters
  * are the common prefix
  */
-static int match(const char **spec, char *ps_matched,
+static int match(const char **spec, char *matched,
 		 const char *filename, int len)
 {
 	const char *m;
@@ -60,12 +60,12 @@ static int match(const char **spec, char
 		}
 		if (!fnmatch(m + len, filename + len, 0))
 			goto matched;
-		if (ps_matched)
-			ps_matched++;
+		if (matched)
+			matched++;
 		continue;
 	matched:
-		if (ps_matched)
-			*ps_matched = 1;
+		if (matched)
+			*matched = 1;
 		return 1;
 	}
 	return 0;
diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
index 24a4fc6..612f8cf 100644
--- a/builtin-mailinfo.c
+++ b/builtin-mailinfo.c
@@ -18,16 +18,16 @@ static FILE *cmitmsg, *patchfile, *fin, 
 
 static int keep_subject = 0;
 static const char *metainfo_charset = NULL;
-static char line[1000];
-static char date[1000];
-static char name[1000];
-static char email[1000];
-static char subject[1000];
+static char line_buf[1000];
+static char date_buf[1000];
+static char name_buf[1000];
+static char email_buf[1000];
+static char subject_buf[1000];
 
 static enum  {
 	TE_DONTCARE, TE_QP, TE_BASE64,
 } transfer_encoding;
-static char charset[256];
+static char charset_buf[256];
 
 static char multipart_boundary[1000];
 static int multipart_boundary_len;
@@ -51,7 +51,7 @@ static int bogus_from(char *line)
 	/* This is fallback, so do not bother if we already have an
 	 * e-mail address.
 	 */
-	if (*email)
+	if (*email_buf)
 		return 0;
 
 	bra = strchr(line, '<');
@@ -61,15 +61,15 @@ static int bogus_from(char *line)
 	if (!ket)
 		return 0;
 
-	for (dst = email, cp = bra+1; cp < ket; )
+	for (dst = email_buf, cp = bra+1; cp < ket; )
 		*dst++ = *cp++;
 	*dst = 0;
 	for (cp = line; isspace(*cp); cp++)
 		;
 	for (bra--; isspace(*bra); bra--)
 		*bra = 0;
-	cp = sanity_check(cp, email);
-	strcpy(name, cp);
+	cp = sanity_check(cp, email_buf);
+	strcpy(name_buf, cp);
 	return 1;
 }
 
@@ -87,7 +87,7 @@ static int handle_from(char *in_line)
 	/*
 	 * If we already have one email, don't take any confusing lines
 	 */
-	if (*email && strchr(at+1, '@'))
+	if (*email_buf && strchr(at+1, '@'))
 		return 0;
 
 	/* Pick up the string around '@', possibly delimited with <>
@@ -103,7 +103,7 @@ static int handle_from(char *in_line)
 		}
 		at--;
 	}
-	dst = email;
+	dst = email_buf;
 	for (;;) {
 		unsigned char c = *at;
 		if (!c || c == '>' || isspace(c)) {
@@ -140,20 +140,20 @@ static int handle_from(char *in_line)
 		}
 		at++;
 	}
-	at = sanity_check(at, email);
-	strcpy(name, at);
+	at = sanity_check(at, email_buf);
+	strcpy(name_buf, at);
 	return 1;
 }
 
 static int handle_date(char *line)
 {
-	strcpy(date, line);
+	strcpy(date_buf, line);
 	return 0;
 }
 
 static int handle_subject(char *line)
 {
-	strcpy(subject, line);
+	strcpy(subject_buf, line);
 	return 0;
 }
 
@@ -194,11 +194,11 @@ static int handle_subcontent_type(char *
 		fprintf(stderr, "Not handling nested multipart message.\n");
 		exit(1);
 	}
-	slurp_attr(line, "charset=", charset);
-	if (*charset) {
+	slurp_attr(line, "charset=", charset_buf);
+	if (*charset_buf) {
 		int i, c;
-		for (i = 0; (c = charset[i]) != 0; i++)
-			charset[i] = tolower(c);
+		for (i = 0; (c = charset_buf[i]) != 0; i++)
+			charset_buf[i] = tolower(c);
 	}
 	return 0;
 }
@@ -210,7 +210,7 @@ static int handle_content_type(char *lin
 		memcpy(multipart_boundary, "--", 2);
 		multipart_boundary_len = strlen(multipart_boundary);
 	}
-	slurp_attr(line, "charset=", charset);
+	slurp_attr(line, "charset=", charset_buf);
 	return 0;
 }
 
@@ -300,7 +300,7 @@ static char *cleanup_subject(char *subje
 		return subject;
 	for (;;) {
 		char *p;
-		int len, remove;
+		int len, strip_len;
 		switch (*subject) {
 		case 'r': case 'R':
 			if (!memcmp("e:", subject+1, 2)) {
@@ -319,8 +319,8 @@ static char *cleanup_subject(char *subje
 				continue;
 			}
 			len = strlen(p);
-			remove = p - subject;
-			if (remove <= len *2) {
+			strip_len = p - subject;
+			if (strip_len <= len *2) {
 				subject = p+1;
 				continue;
 			}
@@ -659,14 +659,14 @@ static void handle_info(void)
 {
 	char *sub;
 
-	sub = cleanup_subject(subject);
-	cleanup_space(name);
-	cleanup_space(date);
-	cleanup_space(email);
+	sub = cleanup_subject(subject_buf);
+	cleanup_space(name_buf);
+	cleanup_space(date_buf);
+	cleanup_space(email_buf);
 	cleanup_space(sub);
 
 	fprintf(fout, "Author: %s\nEmail: %s\nSubject: %s\nDate: %s\n\n",
-	       name, email, sub, date);
+	       name_buf, email_buf, sub, date_buf);
 }
 
 /* We are inside message body and have read line[] already.
@@ -677,11 +677,12 @@ static int handle_commit_msg(int *seen)
 	if (!cmitmsg)
 		return 0;
 	do {
-		if (!memcmp("diff -", line, 6) ||
-		    !memcmp("---", line, 3) ||
-		    !memcmp("Index: ", line, 7))
+		if (!memcmp("diff -", line_buf, 6) ||
+		    !memcmp("---", line_buf, 3) ||
+		    !memcmp("Index: ", line_buf, 7))
 			break;
-		if ((multipart_boundary[0] && is_multipart_boundary(line))) {
+		if ((multipart_boundary[0] &&
+		     is_multipart_boundary(line_buf))) {
 			/* We come here when the first part had only
 			 * the commit message without any patch.  We
 			 * pretend we have not seen this line yet, and
@@ -693,16 +694,16 @@ static int handle_commit_msg(int *seen)
 		/* Unwrap transfer encoding and optionally
 		 * normalize the log message to UTF-8.
 		 */
-		decode_transfer_encoding(line);
+		decode_transfer_encoding(line_buf);
 		if (metainfo_charset)
-			convert_to_utf8(line, charset);
+			convert_to_utf8(line_buf, charset_buf);
 
-		handle_inbody_header(seen, line);
+		handle_inbody_header(seen, line_buf);
 		if (!(*seen & SEEN_PREFIX))
 			continue;
 
-		fputs(line, cmitmsg);
-	} while (fgets(line, sizeof(line), fin) != NULL);
+		fputs(line_buf, cmitmsg);
+	} while (fgets(line_buf, sizeof(line_buf), fin) != NULL);
 	fclose(cmitmsg);
 	cmitmsg = NULL;
 	return 0;
@@ -714,16 +715,16 @@ static int handle_commit_msg(int *seen)
 static void handle_patch(void)
 {
 	do {
-		if (multipart_boundary[0] && is_multipart_boundary(line))
+		if (multipart_boundary[0] && is_multipart_boundary(line_buf))
 			break;
 		/* Only unwrap transfer encoding but otherwise do not
 		 * do anything.  We do *NOT* want UTF-8 conversion
 		 * here; we are dealing with the user payload.
 		 */
-		decode_transfer_encoding(line);
-		fputs(line, patchfile);
+		decode_transfer_encoding(line_buf);
+		fputs(line_buf, patchfile);
 		patch_lines++;
-	} while (fgets(line, sizeof(line), fin) != NULL);
+	} while (fgets(line_buf, sizeof(line_buf), fin) != NULL);
 }
 
 /* multipart boundary and transfer encoding are set up for us, and we
@@ -736,10 +737,10 @@ static int handle_multipart_one_part(int
 {
 	int n = 0;
 
-	while (fgets(line, sizeof(line), fin) != NULL) {
+	while (fgets(line_buf, sizeof(line_buf), fin) != NULL) {
 	again:
 		n++;
-		if (is_multipart_boundary(line))
+		if (is_multipart_boundary(line_buf))
 			break;
 		if (handle_commit_msg(seen))
 			goto again;
@@ -757,8 +758,8 @@ static void handle_multipart_body(void)
 	int part_num = 0;
 
 	/* Skip up to the first boundary */
-	while (fgets(line, sizeof(line), fin) != NULL)
-		if (is_multipart_boundary(line)) {
+	while (fgets(line_buf, sizeof(line_buf), fin) != NULL)
+		if (is_multipart_boundary(line_buf)) {
 			part_num = 1;
 			break;
 		}
@@ -766,16 +767,16 @@ static void handle_multipart_body(void)
 		return;
 	/* We are on boundary line.  Start slurping the subhead. */
 	while (1) {
-		int hdr = read_one_header_line(line, sizeof(line), fin);
+		int hdr = read_one_header_line(line_buf, sizeof(line_buf), fin);
 		if (!hdr) {
 			if (handle_multipart_one_part(&seen) < 0)
 				return;
 			/* Reset per part headers */
 			transfer_encoding = TE_DONTCARE;
-			charset[0] = 0;
+			charset_buf[0] = 0;
 		}
 		else
-			check_subheader_line(line);
+			check_subheader_line(line_buf);
 	}
 	fclose(patchfile);
 	if (!patch_lines) {
@@ -818,7 +819,7 @@ int mailinfo(FILE *in, FILE *out, int ks
 		return -1;
 	}
 	while (1) {
-		int hdr = read_one_header_line(line, sizeof(line), fin);
+		int hdr = read_one_header_line(line_buf, sizeof(line_buf), fin);
 		if (!hdr) {
 			if (multipart_boundary[0])
 				handle_multipart_body();
@@ -827,7 +828,7 @@ int mailinfo(FILE *in, FILE *out, int ks
 			handle_info();
 			break;
 		}
-		check_header_line(line);
+		check_header_line(line_buf);
 	}
 
 	return 0;
diff --git a/builtin-mv.c b/builtin-mv.c
index 62ae937..fdaf051 100644
--- a/builtin-mv.c
+++ b/builtin-mv.c
@@ -267,10 +267,10 @@ next:
 	} else {
 		for (i = 0; i < changed.nr; i++) {
 			const char *path = changed.items[i].path;
-			int i = cache_name_pos(path, strlen(path));
-			struct cache_entry *ce = active_cache[i];
+			int pos = cache_name_pos(path, strlen(path));
+			struct cache_entry *ce = active_cache[pos];
 
-			if (i < 0)
+			if (pos < 0)
 				die ("Huh? Cache entry for %s unknown?", path);
 			refresh_cache_entry(ce, 0);
 		}
diff --git a/builtin-prune.c b/builtin-prune.c
index 6a86eb5..717e5dd 100644
--- a/builtin-prune.c
+++ b/builtin-prune.c
@@ -143,19 +143,19 @@ static void process_tag(struct tag *tag,
 	add_object(tag->tagged, p, NULL, name);
 }
 
-static void walk_commit_list(struct rev_info *revs)
+static void walk_commit_list(struct rev_info *rev)
 {
 	int i;
 	struct commit *commit;
 	struct object_array objects = { 0, 0, NULL };
 
 	/* Walk all commits, process their trees */
-	while ((commit = get_revision(revs)) != NULL)
+	while ((commit = get_revision(rev)) != NULL)
 		process_tree(commit->tree, &objects, NULL, "");
 
 	/* Then walk all the pending objects, recursively processing them too */
-	for (i = 0; i < revs->pending.nr; i++) {
-		struct object_array_entry *pending = revs->pending.objects + i;
+	for (i = 0; i < rev->pending.nr; i++) {
+		struct object_array_entry *pending = rev->pending.objects + i;
 		struct object *obj = pending->item;
 		const char *name = pending->name;
 		if (obj->type == OBJ_TAG) {
diff --git a/builtin-push.c b/builtin-push.c
index a824171..e768923 100644
--- a/builtin-push.c
+++ b/builtin-push.c
@@ -234,7 +234,7 @@ static int do_push(const char *repo)
 	common_argc = argc;
 
 	for (i = 0; i < n; i++) {
-		int error;
+		int err;
 		int dest_argc = common_argc;
 		int dest_refspec_nr = refspec_nr;
 		const char **dest_refspec = refspec;
@@ -250,10 +250,10 @@ static int do_push(const char *repo)
 		while (dest_refspec_nr--)
 			argv[dest_argc++] = *dest_refspec++;
 		argv[dest_argc] = NULL;
-		error = run_command_v(argc, argv);
-		if (!error)
+		err = run_command_v(argc, argv);
+		if (!err)
 			continue;
-		switch (error) {
+		switch (err) {
 		case -ERR_RUN_COMMAND_FORK:
 			die("unable to fork for %s", sender);
 		case -ERR_RUN_COMMAND_EXEC:
@@ -264,7 +264,7 @@ static int do_push(const char *repo)
 		case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
 			die("%s died with strange error", sender);
 		default:
-			return -error;
+			return -err;
 		}
 	}
 	return 0;
diff --git a/builtin-read-tree.c b/builtin-read-tree.c
index 49c10bf..7fb0bbc 100644
--- a/builtin-read-tree.c
+++ b/builtin-read-tree.c
@@ -483,9 +483,9 @@ static void verify_absent(const char *pa
 		    "would be %s by merge.", path, action);
 }
 
-static int merged_entry(struct cache_entry *merge, struct cache_entry *old)
+static int merged_entry(struct cache_entry *result, struct cache_entry *old)
 {
-	merge->ce_flags |= htons(CE_UPDATE);
+	result->ce_flags |= htons(CE_UPDATE);
 	if (old) {
 		/*
 		 * See if we can re-use the old CE directly?
@@ -494,20 +494,20 @@ static int merged_entry(struct cache_ent
 		 * This also removes the UPDATE flag on
 		 * a match.
 		 */
-		if (same(old, merge)) {
-			*merge = *old;
+		if (same(old, result)) {
+			*result = *old;
 		} else {
 			verify_uptodate(old);
 			invalidate_ce_path(old);
 		}
 	}
 	else {
-		verify_absent(merge->name, "overwritten");
-		invalidate_ce_path(merge);
+		verify_absent(result->name, "overwritten");
+		invalidate_ce_path(result);
 	}
 
-	merge->ce_flags &= ~htons(CE_STAGEMASK);
-	add_cache_entry(merge, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE);
+	result->ce_flags &= ~htons(CE_STAGEMASK);
+	add_cache_entry(result, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE);
 	return 1;
 }
 
@@ -547,7 +547,7 @@ #endif
 
 static int threeway_merge(struct cache_entry **stages)
 {
-	struct cache_entry *index;
+	struct cache_entry *cached;
 	struct cache_entry *head; 
 	struct cache_entry *remote = stages[head_idx + 1];
 	int count;
@@ -572,7 +572,7 @@ static int threeway_merge(struct cache_e
 		}
 	}
 
-	index = stages[0];
+	cached = stages[0];
 	head = stages[head_idx];
 
 	if (head == &df_conflict_entry) {
@@ -585,8 +585,8 @@ static int threeway_merge(struct cache_e
 		remote = NULL;
 	}
 
-	if (!path && index)
-		path = index->name;
+	if (!path && cached)
+		path = cached->name;
 	if (!path && head)
 		path = head->name;
 	if (!path && remote)
@@ -612,25 +612,25 @@ static int threeway_merge(struct cache_e
 	 */
 	/* #14, #14ALT, #2ALT */
 	if (remote && !df_conflict_head && head_match && !remote_match) {
-		if (index && !same(index, remote) && !same(index, head))
-			reject_merge(index);
-		return merged_entry(remote, index);
+		if (cached && !same(cached, remote) && !same(cached, head))
+			reject_merge(cached);
+		return merged_entry(remote, cached);
 	}
 	/*
 	 * If we have an entry in the index cache, then we want to
 	 * make sure that it matches head.
 	 */
-	if (index && !same(index, head)) {
-		reject_merge(index);
+	if (cached && !same(cached, head)) {
+		reject_merge(cached);
 	}
 
 	if (head) {
 		/* #5ALT, #15 */
 		if (same(head, remote))
-			return merged_entry(head, index);
+			return merged_entry(head, cached);
 		/* #13, #3ALT */
 		if (!df_conflict_remote && remote_match && !head_match)
-			return merged_entry(head, index);
+			return merged_entry(head, cached);
 	}
 
 	/* #1 */
@@ -650,8 +650,8 @@ static int threeway_merge(struct cache_e
 		if ((head_deleted && remote_deleted) ||
 		    (head_deleted && remote && remote_match) ||
 		    (remote_deleted && head && head_match)) {
-			if (index)
-				return deleted_entry(index, index);
+			if (cached)
+				return deleted_entry(cached, cached);
 			else if (path)
 				verify_absent(path, "removed");
 			return 0;
@@ -660,7 +660,7 @@ static int threeway_merge(struct cache_e
 		 * Added in both, identically.
 		 */
 		if (no_anc_exists && head && remote && same(head, remote))
-			return merged_entry(head, index);
+			return merged_entry(head, cached);
 
 	}
 
@@ -668,8 +668,8 @@ static int threeway_merge(struct cache_e
 	 * up-to-date to avoid the files getting overwritten with
 	 * conflict resolution files. 
 	 */
-	if (index) {
-		verify_uptodate(index);
+	if (cached) {
+		verify_uptodate(cached);
 	}
 	else if (path)
 		verify_absent(path, "overwritten");
@@ -870,7 +870,7 @@ static const char read_tree_usage[] = "g
 
 static struct lock_file lock_file;
 
-int cmd_read_tree(int argc, const char **argv, const char *prefix)
+int cmd_read_tree(int argc, const char **argv, const char *pfx)
 {
 	int i, newfd, stage = 0;
 	unsigned char sha1[20];
@@ -921,9 +921,9 @@ int cmd_read_tree(int argc, const char *
 		 * given subdirectory.
 		 */
 		if (!strncmp(arg, "--prefix=", 9)) {
-			if (stage || merge || prefix)
+			if (stage || merge || pfx)
 				usage(read_tree_usage);
-			prefix = arg + 9;
+			pfx = arg + 9;
 			merge = 1;
 			stage = 1;
 			if (read_cache_unmerged())
@@ -936,7 +936,7 @@ int cmd_read_tree(int argc, const char *
 		 * correspond to them.
 		 */
 		if (!strcmp(arg, "--reset")) {
-			if (stage || merge || prefix)
+			if (stage || merge || pfx)
 				usage(read_tree_usage);
 			reset = 1;
 			merge = 1;
@@ -957,7 +957,7 @@ int cmd_read_tree(int argc, const char *
 
 		/* "-m" stands for "merge", meaning we start in stage 1 */
 		if (!strcmp(arg, "-m")) {
-			if (stage || merge || prefix)
+			if (stage || merge || pfx)
 				usage(read_tree_usage);
 			if (read_cache_unmerged())
 				die("you need to resolve your current index first");
@@ -979,23 +979,23 @@ int cmd_read_tree(int argc, const char *
 	if ((update||index_only) && !merge)
 		usage(read_tree_usage);
 
-	if (prefix) {
-		int pfxlen = strlen(prefix);
+	if (pfx) {
+		int pfxlen = strlen(pfx);
 		int pos;
-		if (prefix[pfxlen-1] != '/')
+		if (pfx[pfxlen-1] != '/')
 			die("prefix must end with /");
 		if (stage != 2)
 			die("binding merge takes only one tree");
-		pos = cache_name_pos(prefix, pfxlen);
+		pos = cache_name_pos(pfx, pfxlen);
 		if (0 <= pos)
 			die("corrupt index file");
 		pos = -pos-1;
 		if (pos < active_nr &&
-		    !strncmp(active_cache[pos]->name, prefix, pfxlen))
-			die("subdirectory '%s' already exists.", prefix);
-		pos = cache_name_pos(prefix, pfxlen-1);
+		    !strncmp(active_cache[pos]->name, pfx, pfxlen))
+			die("subdirectory '%s' already exists.", pfx);
+		pos = cache_name_pos(pfx, pfxlen-1);
 		if (0 <= pos)
-			die("file '%.*s' already exists.", pfxlen-1, prefix);
+			die("file '%.*s' already exists.", pfxlen-1, pfx);
 	}
 
 	if (merge) {
@@ -1003,7 +1003,7 @@ int cmd_read_tree(int argc, const char *
 			die("just how do you expect me to merge %d trees?", stage-1);
 		switch (stage - 1) {
 		case 1:
-			fn = prefix ? bind_merge : oneway_merge;
+			fn = pfx ? bind_merge : oneway_merge;
 			break;
 		case 2:
 			fn = twoway_merge;
@@ -1029,7 +1029,7 @@ int cmd_read_tree(int argc, const char *
 	 * valid cache-tree because the index must match exactly
 	 * what came from the tree.
 	 */
-	if (trees && trees->item && !prefix && (!merge || (stage == 2))) {
+	if (trees && trees->item && !pfx && (!merge || (stage == 2))) {
 		cache_tree_free(&active_cache_tree);
 		prime_cache_tree();
 	}
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 0dee173..5223504 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -151,18 +151,18 @@ static void process_tree(struct tree *tr
 	tree->buffer = NULL;
 }
 
-static void show_commit_list(struct rev_info *revs)
+static void show_commit_list(struct rev_info *rev)
 {
 	int i;
 	struct commit *commit;
 	struct object_array objects = { 0, 0, NULL };
 
-	while ((commit = get_revision(revs)) != NULL) {
+	while ((commit = get_revision(rev)) != NULL) {
 		process_tree(commit->tree, &objects, NULL, "");
 		show_commit(commit);
 	}
-	for (i = 0; i < revs->pending.nr; i++) {
-		struct object_array_entry *pending = revs->pending.objects + i;
+	for (i = 0; i < rev->pending.nr; i++) {
+		struct object_array_entry *pending = rev->pending.objects + i;
 		struct object *obj = pending->item;
 		const char *name = pending->name;
 		if (obj->flags & (UNINTERESTING | SEEN))
diff --git a/builtin-show-branch.c b/builtin-show-branch.c
index 2a1b848..8bcf4e3 100644
--- a/builtin-show-branch.c
+++ b/builtin-show-branch.c
@@ -475,7 +475,7 @@ static int show_merge_base(struct commit
 
 static int show_independent(struct commit **rev,
 			    int num_rev,
-			    char **ref_name,
+			    char **unused_ref_name,
 			    unsigned int *rev_mask)
 {
 	int i;
@@ -752,9 +752,10 @@ int cmd_show_branch(int ac, const char *
 	all_revs = all_mask & ~((1u << REV_SHIFT) - 1);
 
 	while (seen) {
-		struct commit *commit = pop_one_commit(&seen);
-		int this_flag = commit->object.flags;
-		int is_merge_point = ((this_flag & all_revs) == all_revs);
+		int this_flag, is_merge_point;
+		commit = pop_one_commit(&seen);
+		this_flag = commit->object.flags;
+		is_merge_point = ((this_flag & all_revs) == all_revs);
 
 		shown_merge_point |= is_merge_point;
 
diff --git a/cache.h b/cache.h
index c575b8a..eb9a403 100644
--- a/cache.h
+++ b/cache.h
@@ -240,7 +240,7 @@ extern int check_sha1_signature(const un
 extern int write_sha1_from_fd(const unsigned char *sha1, int fd, char *buffer,
 			      size_t bufsize, size_t *bufposn);
 extern int write_sha1_to_fd(int fd, const unsigned char *sha1);
-extern int move_temp_to_file(const char *tmpfile, char *filename);
+extern int move_temp_to_file(const char *tmp_file, char *filename);
 
 extern int has_sha1_pack(const unsigned char *sha1);
 extern int has_sha1_file(const unsigned char *sha1);
@@ -268,8 +268,8 @@ extern void *read_object_with_reference(
 					unsigned long *size,
 					unsigned char *sha1_ret);
 
-const char *show_date(unsigned long time, int timezone);
-const char *show_rfc2822_date(unsigned long time, int timezone);
+const char *show_date(unsigned long unix_time, int time_zone);
+const char *show_rfc2822_date(unsigned long unix_time, int time_zone);
 int parse_date(const char *date, char *buf, int bufsize);
 void datestamp(char *buf, int bufsize);
 unsigned long approxidate(const char *);
diff --git a/config.c b/config.c
index 0ac6aeb..49c993e 100644
--- a/config.c
+++ b/config.c
@@ -148,7 +148,7 @@ static int get_extended_base_var(char *n
 	name[baselen++] = '.';
 
 	for (;;) {
-		int c = get_next_char();
+		c = get_next_char();
 		if (c == '\n')
 			return -1;
 		if (c == '"')
@@ -618,7 +618,7 @@ int git_config_set_multivar(const char* 
 	} else{
 		struct stat st;
 		char* contents;
-		int i, copy_begin, copy_end, new_line = 0;
+		int copy_begin, copy_end, new_line = 0;
 
 		if (value_regex == NULL)
 			store.value_regex = NULL;
diff --git a/convert-objects.c b/convert-objects.c
index ebea8e4..9b92560 100644
--- a/convert-objects.c
+++ b/convert-objects.c
@@ -183,15 +183,15 @@ static unsigned long parse_oldstyle_date
 				return mktime(&tm);
 			buf = next;
 		} else {
-			const char **p = timezones;
+			const char **tzp = timezones;
 			while (isspace(*buf))
 				buf++;
-			while (*p) {
-				if (!memcmp(buf, *p, strlen(*p))) {
-					buf += strlen(*p);
+			while (*tzp) {
+				if (!memcmp(buf, *tzp, strlen(*tzp))) {
+					buf += strlen(*tzp);
 					break;
 				}
-				p++;
+				tzp++;
 			}
 		}
 		fmt++;
diff --git a/daemon.c b/daemon.c
index 810837f..ff21a43 100644
--- a/daemon.c
+++ b/daemon.c
@@ -630,8 +630,6 @@ static int service_loop(int socknum, int
 	signal(SIGCHLD, child_handler);
 
 	for (;;) {
-		int i;
-
 		if (poll(pfd, socknum, -1) < 0) {
 			if (errno != EINTR) {
 				error("poll failed, resuming: %s",
diff --git a/date.c b/date.c
index 66be23a..c792a90 100644
--- a/date.c
+++ b/date.c
@@ -42,7 +42,7 @@ static const char *weekday_names[] = {
  * thing, which means that tz -0100 is passed in as the integer -100,
  * even though it means "sixty minutes off"
  */
-static struct tm *time_to_tm(unsigned long time, int tz)
+static struct tm *time_to_tm(unsigned long unix_time, int tz)
 {
 	time_t t;
 	int minutes;
@@ -50,16 +50,16 @@ static struct tm *time_to_tm(unsigned lo
 	minutes = tz < 0 ? -tz : tz;
 	minutes = (minutes / 100)*60 + (minutes % 100);
 	minutes = tz < 0 ? -minutes : minutes;
-	t = time + minutes * 60;
+	t = unix_time + minutes * 60;
 	return gmtime(&t);
 }
 
-const char *show_date(unsigned long time, int tz)
+const char *show_date(unsigned long unix_time, int tz)
 {
 	struct tm *tm;
 	static char timebuf[200];
 
-	tm = time_to_tm(time, tz);
+	tm = time_to_tm(unix_time, tz);
 	if (!tm)
 		return NULL;
 	sprintf(timebuf, "%.3s %.3s %d %02d:%02d:%02d %d %+05d",
@@ -71,12 +71,12 @@ const char *show_date(unsigned long time
 	return timebuf;
 }
 
-const char *show_rfc2822_date(unsigned long time, int tz)
+const char *show_rfc2822_date(unsigned long unix_time, int tz)
 {
 	struct tm *tm;
 	static char timebuf[200];
 
-	tm = time_to_tm(time, tz);
+	tm = time_to_tm(unix_time, tz);
 	if (!tm)
 		return NULL;
 	sprintf(timebuf, "%.3s, %d %.3s %d %02d:%02d:%02d %+05d",
@@ -335,8 +335,8 @@ static int match_digit(const char *date,
 	 * Seconds since 1970? We trigger on that for anything after Jan 1, 2000
 	 */
 	if (num > 946684800) {
-		time_t time = num;
-		if (gmtime_r(&time, tm)) {
+		time_t unix_time = num;
+		if (gmtime_r(&unix_time, tm)) {
 			*tm_gmt = 1;
 			return end - date;
 		}
@@ -632,13 +632,13 @@ static const char *approxidate_alpha(con
 	for (i = 0; i < 7; i++) {
 		int match = match_string(date, weekday_names[i]);
 		if (match >= 3) {
-			int diff, n = *num -1;
+			int diff, wk = *num -1;
 			*num = 0;
 
 			diff = tm->tm_wday - i;
 			if (diff <= 0)
-				n++;
-			diff += 7*n;
+				wk++;
+			diff += 7*wk;
 
 			update_tm(tm, diff * 24 * 60 * 60);
 			return end;
@@ -646,13 +646,13 @@ static const char *approxidate_alpha(con
 	}
 
 	if (match_string(date, "months") >= 5) {
-		int n = tm->tm_mon - *num;
+		int mo = tm->tm_mon - *num;
 		*num = 0;
-		while (n < 0) {
-			n += 12;
+		while (mo < 0) {
+			mo += 12;
 			tm->tm_year--;
 		}
-		tm->tm_mon = n;
+		tm->tm_mon = mo;
 		return end;
 	}
 
diff --git a/delta.h b/delta.h
index 7b3f86d..ae8cc47 100644
--- a/delta.h
+++ b/delta.h
@@ -21,7 +21,7 @@ create_delta_index(const void *buf, unsi
  *
  * Given pointer must be what create_delta_index() returned, or NULL.
  */
-extern void free_delta_index(struct delta_index *index);
+extern void free_delta_index(struct delta_index *);
 
 /*
  * create_delta: create a delta from given index for the given buffer
@@ -34,7 +34,7 @@ extern void free_delta_index(struct delt
  * must be freed by the caller.
  */
 extern void *
-create_delta(const struct delta_index *index,
+create_delta(const struct delta_index *,
 	     const void *buf, unsigned long bufsize,
 	     unsigned long *delta_size, unsigned long max_delta_size);
 
@@ -51,11 +51,11 @@ diff_delta(const void *src_buf, unsigned
 	   const void *trg_buf, unsigned long trg_bufsize,
 	   unsigned long *delta_size, unsigned long max_delta_size)
 {
-	struct delta_index *index = create_delta_index(src_buf, src_bufsize);
-	if (index) {
-		void *delta = create_delta(index, trg_buf, trg_bufsize,
+	struct delta_index *delta_index = create_delta_index(src_buf, src_bufsize);
+	if (delta_index) {
+		void *delta = create_delta(delta_index, trg_buf, trg_bufsize,
 					   delta_size, max_delta_size);
-		free_delta_index(index);
+		free_delta_index(delta_index);
 		return delta;
 	}
 	return NULL;
diff --git a/diff-delta.c b/diff-delta.c
index 7da9205..dbefc2b 100644
--- a/diff-delta.c
+++ b/diff-delta.c
@@ -139,7 +139,7 @@ struct delta_index * create_delta_index(
 {
 	unsigned int i, hsize, hmask, entries, prev_val, *hash_count;
 	const unsigned char *data, *buffer = buf;
-	struct delta_index *index;
+	struct delta_index *delta_index;
 	struct index_entry *entry, **hash;
 	void *mem;
 	unsigned long memsize;
@@ -157,27 +157,27 @@ struct delta_index * create_delta_index(
 	hmask = hsize - 1;
 
 	/* allocate lookup index */
-	memsize = sizeof(*index) +
+	memsize = sizeof(*delta_index) +
 		  sizeof(*hash) * hsize +
 		  sizeof(*entry) * entries;
 	mem = malloc(memsize);
 	if (!mem)
 		return NULL;
-	index = mem;
-	mem = index + 1;
+	delta_index = mem;
+	mem = delta_index + 1;
 	hash = mem;
 	mem = hash + hsize;
 	entry = mem;
 
-	index->src_buf = buf;
-	index->src_size = bufsize;
-	index->hash_mask = hmask;
+	delta_index->src_buf = buf;
+	delta_index->src_size = bufsize;
+	delta_index->hash_mask = hmask;
 	memset(hash, 0, hsize * sizeof(*hash));
 
 	/* allocate an array to count hash entries */
 	hash_count = calloc(hsize, sizeof(*hash_count));
 	if (!hash_count) {
-		free(index);
+		free(delta_index);
 		return NULL;
 	}
 
@@ -230,12 +230,12 @@ struct delta_index * create_delta_index(
 	}
 	free(hash_count);
 
-	return index;
+	return delta_index;
 }
 
-void free_delta_index(struct delta_index *index)
+void free_delta_index(struct delta_index *delta_index)
 {
-	free(index);
+	free(delta_index);
 }
 
 /*
@@ -245,7 +245,7 @@ void free_delta_index(struct delta_index
 #define MAX_OP_SIZE	(5 + 5 + 1 + RABIN_WINDOW + 7)
 
 void *
-create_delta(const struct delta_index *index,
+create_delta(const struct delta_index *delta_index,
 	     const void *trg_buf, unsigned long trg_size,
 	     unsigned long *delta_size, unsigned long max_size)
 {
@@ -266,7 +266,7 @@ create_delta(const struct delta_index *i
 		return NULL;
 
 	/* store reference buffer size */
-	i = index->src_size;
+	i = delta_index->src_size;
 	while (i >= 0x80) {
 		out[outpos++] = i | 0x80;
 		i >>= 7;
@@ -281,8 +281,8 @@ create_delta(const struct delta_index *i
 	}
 	out[outpos++] = i;
 
-	ref_data = index->src_buf;
-	ref_top = ref_data + index->src_size;
+	ref_data = delta_index->src_buf;
+	ref_top = ref_data + delta_index->src_size;
 	data = trg_buf;
 	top = (const unsigned char *) trg_buf + trg_size;
 
@@ -299,8 +299,8 @@ create_delta(const struct delta_index *i
 		struct index_entry *entry;
 		val ^= U[data[-RABIN_WINDOW]];
 		val = ((val << 8) | *data) ^ T[val >> RABIN_SHIFT];
-		i = val & index->hash_mask;
-		for (entry = index->hash[i]; entry; entry = entry->next) {
+		i = val & delta_index->hash_mask;
+		for (entry = delta_index->hash[i]; entry; entry = entry->next) {
 			const unsigned char *ref = entry->ptr;
 			const unsigned char *src = data;
 			unsigned int ref_size = ref_top - ref;
diff --git a/fetch-clone.c b/fetch-clone.c
index 81d1371..7eab54e 100644
--- a/fetch-clone.c
+++ b/fetch-clone.c
@@ -208,7 +208,7 @@ #define usec_to_binarymsec(x) ((int)(x) 
 
 int receive_keep_pack(int xd[2], const char *me, int quiet, int sideband)
 {
-	char tmpfile[PATH_MAX];
+	char tmp_file[PATH_MAX];
 	int ofd, ifd, fd[2];
 	unsigned long total;
 	static struct timeval prev_tv;
@@ -222,11 +222,11 @@ int receive_keep_pack(int xd[2], const c
 	setup_sideband(sideband, me, fd, xd);
 
 	ifd = fd[0];
-	snprintf(tmpfile, sizeof(tmpfile),
+	snprintf(tmp_file, sizeof(tmp_file),
 		 "%s/pack/tmp-XXXXXX", get_object_directory());
-	ofd = mkstemp(tmpfile);
+	ofd = mkstemp(tmp_file);
 	if (ofd < 0)
-		return error("unable to create temporary file %s", tmpfile);
+		return error("unable to create temporary file %s", tmp_file);
 
 	gettimeofday(&prev_tv, NULL);
 	total = 0;
@@ -242,7 +242,7 @@ int receive_keep_pack(int xd[2], const c
 			if (errno != EINTR && errno != EAGAIN) {
 				error("error reading pack (%s)", strerror(errno));
 				close(ofd);
-				unlink(tmpfile);
+				unlink(tmp_file);
 				return -1;
 			}
 			sz = 0;
@@ -254,7 +254,7 @@ int receive_keep_pack(int xd[2], const c
 				error("error writing pack (%s)",
 				      strerror(errno));
 				close(ofd);
-				unlink(tmpfile);
+				unlink(tmp_file);
 				return -1;
 			}
 			pos += wsz;
@@ -295,5 +295,5 @@ int receive_keep_pack(int xd[2], const c
 		}
 	}
 	close(ofd);
-	return finish_pack(tmpfile, me);
+	return finish_pack(tmp_file, me);
 }
diff --git a/fetch.c b/fetch.c
index aeb6bf2..d9cc155 100644
--- a/fetch.c
+++ b/fetch.c
@@ -48,9 +48,9 @@ static int process_tree(struct tree *tre
 		struct object *obj = NULL;
 
 		if (S_ISDIR(entry.mode)) {
-			struct tree *tree = lookup_tree(entry.sha1);
-			if (tree)
-				obj = &tree->object;
+			struct tree *subtree = lookup_tree(entry.sha1);
+			if (subtree)
+				obj = &subtree->object;
 		}
 		else {
 			struct blob *blob = lookup_blob(entry.sha1);
diff --git a/fsck-objects.c b/fsck-objects.c
index e167f41..8432f5b 100644
--- a/fsck-objects.c
+++ b/fsck-objects.c
@@ -579,7 +579,6 @@ int main(int argc, char **argv)
 	}
 
 	if (keep_cache_objects) {
-		int i;
 		read_cache();
 		for (i = 0; i < active_nr; i++) {
 			struct blob *blob = lookup_blob(active_cache[i]->sha1);
diff --git a/git.c b/git.c
index 7321d6c..876cdee 100644
--- a/git.c
+++ b/git.c
@@ -278,11 +278,11 @@ static void handle_internal_command(int 
 		if (p->prefix)
 			prefix = setup_git_directory();
 		if (getenv("GIT_TRACE")) {
-			int i;
+			int j;
 			fprintf(stderr, "trace: built-in: git");
-			for (i = 0; i < argc; ++i) {
+			for (j = 0; j < argc; j++) {
 				fputc(' ', stderr);
-				sq_quote_print(stderr, argv[i]);
+				sq_quote_print(stderr, argv[j]);
 			}
 			putc('\n', stderr);
 			fflush(stderr);
diff --git a/http-fetch.c b/http-fetch.c
index 1aad39b..b8a2ee4 100644
--- a/http-fetch.c
+++ b/http-fetch.c
@@ -425,7 +425,7 @@ static int fetch_index(struct alt_base *
 	char *hex = sha1_to_hex(sha1);
 	char *filename;
 	char *url;
-	char tmpfile[PATH_MAX];
+	char tmp_file[PATH_MAX];
 	long prev_posn = 0;
 	char range[RANGE_HEADER_SIZE];
 	struct curl_slist *range_header = NULL;
@@ -444,8 +444,8 @@ static int fetch_index(struct alt_base *
 	sprintf(url, "%s/objects/pack/pack-%s.idx", repo->base, hex);
 
 	filename = sha1_pack_index_name(sha1);
-	snprintf(tmpfile, sizeof(tmpfile), "%s.temp", filename);
-	indexfile = fopen(tmpfile, "a");
+	snprintf(tmp_file, sizeof(tmp_file), "%s.temp", filename);
+	indexfile = fopen(tmp_file, "a");
 	if (!indexfile)
 		return error("Unable to open local file %s for pack index",
 			     filename);
@@ -485,7 +485,7 @@ static int fetch_index(struct alt_base *
 
 	fclose(indexfile);
 
-	return move_temp_to_file(tmpfile, filename);
+	return move_temp_to_file(tmp_file, filename);
 }
 
 static int setup_index(struct alt_base *repo, unsigned char *sha1)
@@ -966,7 +966,7 @@ static int fetch_pack(struct alt_base *r
 	struct packed_git **lst;
 	FILE *packfile;
 	char *filename;
-	char tmpfile[PATH_MAX];
+	char tmp_file[PATH_MAX];
 	int ret;
 	long prev_posn = 0;
 	char range[RANGE_HEADER_SIZE];
@@ -993,8 +993,8 @@ static int fetch_pack(struct alt_base *r
 		repo->base, sha1_to_hex(target->sha1));
 
 	filename = sha1_pack_name(target->sha1);
-	snprintf(tmpfile, sizeof(tmpfile), "%s.temp", filename);
-	packfile = fopen(tmpfile, "a");
+	snprintf(tmp_file, sizeof(tmp_file), "%s.temp", filename);
+	packfile = fopen(tmp_file, "a");
 	if (!packfile)
 		return error("Unable to open local file %s for pack",
 			     filename);
@@ -1034,7 +1034,7 @@ static int fetch_pack(struct alt_base *r
 
 	fclose(packfile);
 
-	ret = move_temp_to_file(tmpfile, filename);
+	ret = move_temp_to_file(tmp_file, filename);
 	if (ret)
 		return ret;
 
@@ -1185,15 +1185,15 @@ static char *quote_ref_url(const char *b
 int fetch_ref(char *ref, unsigned char *sha1)
 {
         char *url;
-        char hex[42];
+        char ref_hex[42];
         struct buffer buffer;
 	const char *base = alt->base;
 	struct active_request_slot *slot;
 	struct slot_results results;
         buffer.size = 41;
         buffer.posn = 0;
-        buffer.buffer = hex;
-        hex[41] = '\0';
+        buffer.buffer = ref_hex;
+        ref_hex[41] = '\0';
 
 	url = quote_ref_url(base, ref);
 	slot = get_active_slot();
@@ -1211,8 +1211,8 @@ int fetch_ref(char *ref, unsigned char *
 		return error("Unable to start request");
 	}
 
-        hex[40] = '\0';
-        get_sha1_hex(hex, sha1);
+        ref_hex[40] = '\0';
+        get_sha1_hex(ref_hex, sha1);
         return 0;
 }
 
diff --git a/http-push.c b/http-push.c
index 4021e7d..6bfba58 100644
--- a/http-push.c
+++ b/http-push.c
@@ -908,7 +908,7 @@ static int fetch_index(unsigned char *sh
 	char *hex = sha1_to_hex(sha1);
 	char *filename;
 	char *url;
-	char tmpfile[PATH_MAX];
+	char tmp_file[PATH_MAX];
 	long prev_posn = 0;
 	char range[RANGE_HEADER_SIZE];
 	struct curl_slist *range_header = NULL;
@@ -944,8 +944,8 @@ static int fetch_index(unsigned char *sh
 	sprintf(url, "%sobjects/pack/pack-%s.idx", remote->url, hex);
 
 	filename = sha1_pack_index_name(sha1);
-	snprintf(tmpfile, sizeof(tmpfile), "%s.temp", filename);
-	indexfile = fopen(tmpfile, "a");
+	snprintf(tmp_file, sizeof(tmp_file), "%s.temp", filename);
+	indexfile = fopen(tmp_file, "a");
 	if (!indexfile)
 		return error("Unable to open local file %s for pack index",
 			     filename);
@@ -990,7 +990,7 @@ static int fetch_index(unsigned char *sh
 	free(url);
 	fclose(indexfile);
 
-	return move_temp_to_file(tmpfile, filename);
+	return move_temp_to_file(tmp_file, filename);
 }
 
 static int setup_index(unsigned char *sha1)
@@ -1123,15 +1123,15 @@ static char *quote_ref_url(const char *b
 int fetch_ref(char *ref, unsigned char *sha1)
 {
         char *url;
-        char hex[42];
+        char ref_hex[42];
         struct buffer buffer;
 	char *base = remote->url;
 	struct active_request_slot *slot;
 	struct slot_results results;
         buffer.size = 41;
         buffer.posn = 0;
-        buffer.buffer = hex;
-        hex[41] = '\0';
+        buffer.buffer = ref_hex;
+        ref_hex[41] = '\0';
 
 	url = quote_ref_url(base, ref);
 	slot = get_active_slot();
@@ -1149,17 +1149,17 @@ int fetch_ref(char *ref, unsigned char *
 		return error("Unable to start request");
 	}
 
-        hex[40] = '\0';
-        get_sha1_hex(hex, sha1);
+        ref_hex[40] = '\0';
+        get_sha1_hex(ref_hex, sha1);
         return 0;
 }
 
-static void one_remote_object(const char *hex)
+static void one_remote_object(const char *hex_name)
 {
 	unsigned char sha1[20];
 	struct object *obj;
 
-	if (get_sha1_hex(hex, sha1) != 0)
+	if (get_sha1_hex(hex_name, sha1) != 0)
 		return;
 
 	obj = lookup_object(sha1);
@@ -1614,11 +1614,11 @@ static void remote_ls(const char *path, 
 static void get_remote_object_list(unsigned char parent)
 {
 	char path[] = "objects/XX/";
-	static const char hex[] = "0123456789abcdef";
+	static const char lc_hex[] = "0123456789abcdef";
 	unsigned int val = parent;
 
-	path[8] = hex[val >> 4];
-	path[9] = hex[val & 0xf];
+	path[8] = lc_hex[val >> 4];
+	path[9] = lc_hex[val & 0xf];
 	remote_dir_exists[val] = 0;
 	remote_ls(path, (PROCESS_FILES | PROCESS_DIRS),
 		  process_ls_object, &val);
diff --git a/merge-tree.c b/merge-tree.c
index 7cf00be..cd932a1 100644
--- a/merge-tree.c
+++ b/merge-tree.c
@@ -128,10 +128,10 @@ static void show_result_list(struct merg
 {
 	printf("%s\n", explanation(entry));
 	do {
-		struct merge_list *link = entry->link;
+		struct merge_list *lnk = entry->link;
 		static const char *desc[4] = { "result", "base", "our", "their" };
 		printf("  %-6s %o %s %s\n", desc[entry->stage], entry->mode, sha1_to_hex(entry->blob->object.sha1), entry->path);
-		entry = link;
+		entry = lnk;
 	} while (entry);
 }
 
@@ -168,7 +168,7 @@ static struct merge_list *create_entry(u
 	return res;
 }
 
-static void resolve(const char *base, struct name_entry *branch1, struct name_entry *result)
+static void resolve(const char *base, struct name_entry *branch1, struct name_entry *res)
 {
 	struct merge_list *orig, *final;
 	const char *path;
@@ -177,9 +177,9 @@ static void resolve(const char *base, st
 	if (!branch1)
 		return;
 
-	path = strdup(mkpath("%s%s", base, result->path));
+	path = strdup(mkpath("%s%s", base, res->path));
 	orig = create_entry(2, branch1->mode, branch1->sha1, path);
-	final = create_entry(0, result->mode, result->sha1, path);
+	final = create_entry(0, res->mode, res->sha1, path);
 
 	final->link = orig;
 
@@ -226,7 +226,7 @@ static int unresolved_directory(const ch
 static struct merge_list *link_entry(unsigned stage, const char *base, struct name_entry *n, struct merge_list *entry)
 {
 	const char *path;
-	struct merge_list *link;
+	struct merge_list *lnk;
 
 	if (!n->mode)
 		return entry;
@@ -234,9 +234,9 @@ static struct merge_list *link_entry(uns
 		path = entry->path;
 	else
 		path = strdup(mkpath("%s%s", base, n->path));
-	link = create_entry(stage, n->mode, n->sha1, path);
-	link->link = entry;
-	return link;
+	lnk = create_entry(stage, n->mode, n->sha1, path);
+	lnk->link = entry;
+	return lnk;
 }
 
 static void unresolved(const char *base, struct name_entry n[3])
diff --git a/pack-check.c b/pack-check.c
index 3a62e1b..2188382 100644
--- a/pack-check.c
+++ b/pack-check.c
@@ -41,7 +41,6 @@ static int verify_packfile(struct packed
 	 * we do not do scan-streaming check on the pack file.
 	 */
 	for (i = err = 0; i < nr_objects; i++) {
-		unsigned char sha1[20];
 		struct pack_entry e;
 		void *data;
 		char type[20];
diff --git a/pack-objects.c b/pack-objects.c
index 861c7f0..f13dc74 100644
--- a/pack-objects.c
+++ b/pack-objects.c
@@ -153,11 +153,11 @@ static void prepare_pack_revindex(struct
 	struct packed_git *p = rix->p;
 	int num_ent = num_packed_objects(p);
 	int i;
-	void *index = p->index_base + 256;
+	void *idx = p->index_base + 256;
 
 	rix->revindex = xmalloc(sizeof(unsigned long) * (num_ent + 1));
 	for (i = 0; i < num_ent; i++) {
-		unsigned int hl = *((unsigned int *)((char *) index + 24*i));
+		unsigned int hl = *((unsigned int *)((char *) idx + 24*i));
 		rix->revindex[i] = ntohl(hl);
 	}
 	/* This knows the pack format -- the 20-byte trailer
@@ -682,18 +682,18 @@ static void add_pbase_object(struct tree
 		}
 		if (!strcmp(type, tree_type)) {
 			struct tree_desc sub;
-			struct pbase_tree_cache *tree;
+			struct pbase_tree_cache *subtree;
 			const char *down = name+cmplen+1;
 			int downlen = name_cmp_len(down);
 
-			tree = pbase_tree_get(entry.sha1);
-			if (!tree)
+			subtree = pbase_tree_get(entry.sha1);
+			if (!subtree)
 				return;
-			sub.buf = tree->tree_data;
-			sub.size = tree->tree_size;
+			sub.buf = subtree->tree_data;
+			sub.size = subtree->tree_size;
 
 			add_pbase_object(&sub, down, downlen, fullname);
-			pbase_tree_put(tree);
+			pbase_tree_put(subtree);
 		}
 	}
 }
@@ -1058,10 +1058,10 @@ static void progress_interval(int signum
 	progress_update = 1;
 }
 
-static void find_deltas(struct object_entry **list, int window, int depth)
+static void find_deltas(struct object_entry **list, int win, int depth)
 {
 	int i, idx;
-	unsigned int array_size = window * sizeof(struct unpacked);
+	unsigned int array_size = win * sizeof(struct unpacked);
 	struct unpacked *array = xmalloc(array_size);
 	unsigned processed = 0;
 	unsigned last_percent = 999;
@@ -1104,12 +1104,12 @@ static void find_deltas(struct object_en
 		n->data = NULL;
 		n->entry = entry;
 
-		j = window;
+		j = win;
 		while (--j > 0) {
 			unsigned int other_idx = idx + j;
 			struct unpacked *m;
-			if (other_idx >= window)
-				other_idx -= window;
+			if (other_idx >= win)
+				other_idx -= win;
 			m = array + other_idx;
 			if (!m->entry)
 				break;
@@ -1124,26 +1124,26 @@ static void find_deltas(struct object_en
 			continue;
 
 		idx++;
-		if (idx >= window)
+		if (idx >= win)
 			idx = 0;
 	}
 
 	if (progress)
 		fputc('\n', stderr);
 
-	for (i = 0; i < window; ++i) {
+	for (i = 0; i < win; ++i) {
 		free_delta_index(array[i].index);
 		free(array[i].data);
 	}
 	free(array);
 }
 
-static void prepare_pack(int window, int depth)
+static void prepare_pack(int win, int depth)
 {
 	get_object_details();
 	sorted_by_type = create_sorted_list(type_size_sort);
-	if (window && depth)
-		find_deltas(sorted_by_type, window+1, depth);
+	if (win && depth)
+		find_deltas(sorted_by_type, win+1, depth);
 }
 
 static int reuse_cached_pack(unsigned char *sha1, int pack_to_stdout)
diff --git a/path-list.c b/path-list.c
index f15a10d..38aac10 100644
--- a/path-list.c
+++ b/path-list.c
@@ -30,36 +30,36 @@ static int get_entry_index(const struct 
 static int add_entry(struct path_list *list, const char *path)
 {
 	int exact_match;
-	int index = get_entry_index(list, path, &exact_match);
+	int idx = get_entry_index(list, path, &exact_match);
 
 	if (exact_match)
-		return -1 - index;
+		return -1 - idx;
 
 	if (list->nr + 1 >= list->alloc) {
 		list->alloc += 32;
 		list->items = xrealloc(list->items, list->alloc
 				* sizeof(struct path_list_item));
 	}
-	if (index < list->nr)
-		memmove(list->items + index + 1, list->items + index,
-				(list->nr - index)
+	if (idx < list->nr)
+		memmove(list->items + idx + 1, list->items + idx,
+				(list->nr - idx)
 				* sizeof(struct path_list_item));
-	list->items[index].path = list->strdup_paths ?
+	list->items[idx].path = list->strdup_paths ?
 		strdup(path) : (char *)path;
-	list->items[index].util = NULL;
+	list->items[idx].util = NULL;
 	list->nr++;
 
-	return index;
+	return idx;
 }
 
 struct path_list_item *path_list_insert(const char *path, struct path_list *list)
 {
-	int index = add_entry(list, path);
+	int idx = add_entry(list, path);
 
-	if (index < 0)
-		index = 1 - index;
+	if (idx < 0)
+		idx = 1 - idx;
 
-	return list->items + index;
+	return list->items + idx;
 }
 
 int path_list_has_path(const struct path_list *list, const char *path)
diff --git a/revision.c b/revision.c
index a58257a..225913b 100644
--- a/revision.c
+++ b/revision.c
@@ -82,7 +82,7 @@ void mark_parents_uninteresting(struct c
 	struct commit_list *parents = commit->parents;
 
 	while (parents) {
-		struct commit *commit = parents->item;
+		commit = parents->item;
 		if (!(commit->object.flags & UNINTERESTING)) {
 			commit->object.flags |= UNINTERESTING;
 
diff --git a/setup.c b/setup.c
index 358e139..62d77df 100644
--- a/setup.c
+++ b/setup.c
@@ -162,7 +162,7 @@ const char *setup_git_directory_gently(i
 	 */
 	if (getenv(GIT_DIR_ENVIRONMENT)) {
 		char path[PATH_MAX];
-		int len = strlen(getenv(GIT_DIR_ENVIRONMENT));
+		len = strlen(getenv(GIT_DIR_ENVIRONMENT));
 		if (sizeof(path) - 40 < len)
 			die("'$%s' too big", GIT_DIR_ENVIRONMENT);
 		memcpy(path, getenv(GIT_DIR_ENVIRONMENT), len);
diff --git a/sha1_file.c b/sha1_file.c
index 43bc2ea..08ddf7a 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -382,7 +382,7 @@ static int check_packed_git_idx(const ch
 				void **idx_map_)
 {
 	void *idx_map;
-	unsigned int *index;
+	unsigned int *idx;
 	unsigned long idx_size;
 	int nr, i;
 	int fd = open(path, O_RDONLY);
@@ -399,7 +399,7 @@ static int check_packed_git_idx(const ch
 	if (idx_map == MAP_FAILED)
 		return -1;
 
-	index = idx_map;
+	idx = idx_map;
 	*idx_map_ = idx_map;
 	*idx_size_ = idx_size;
 
@@ -408,7 +408,7 @@ static int check_packed_git_idx(const ch
 		return error("index file too small");
 	nr = 0;
 	for (i = 0; i < 256; i++) {
-		unsigned int n = ntohl(index[i]);
+		unsigned int n = ntohl(idx[i]);
 		if (n < nr)
 			return error("non-monotonic index");
 		nr = n;
@@ -689,7 +689,7 @@ static int unpack_sha1_header(z_stream *
 	unsigned char c;
 	unsigned int word, bits;
 	unsigned long size;
-	static const char *typename[8] = {
+	static const char *type_check[8] = {
 		NULL,	/* OBJ_EXT */
 		"commit", "tree", "blob", "tag",
 		NULL, NULL, NULL
@@ -716,7 +716,7 @@ static int unpack_sha1_header(z_stream *
 
 	c = *map++;
 	mapsize--;
-	type = typename[(c >> 4) & 7];
+	type = type_check[(c >> 4) & 7];
 	if (!type)
 		return -1;
 
@@ -1180,10 +1180,10 @@ int num_packed_objects(const struct pack
 int nth_packed_object_sha1(const struct packed_git *p, int n,
 			   unsigned char* sha1)
 {
-	void *index = p->index_base + 256;
+	void *idx = p->index_base + 256;
 	if (n < 0 || num_packed_objects(p) <= n)
 		return -1;
-	memcpy(sha1, (char *) index + (24 * n) + 4, 20);
+	memcpy(sha1, (char *) idx + (24 * n) + 4, 20);
 	return 0;
 }
 
@@ -1193,13 +1193,13 @@ int find_pack_entry_one(const unsigned c
 	unsigned int *level1_ofs = p->index_base;
 	int hi = ntohl(level1_ofs[*sha1]);
 	int lo = ((*sha1 == 0x0) ? 0 : ntohl(level1_ofs[*sha1 - 1]));
-	void *index = p->index_base + 256;
+	void *idx = p->index_base + 256;
 
 	do {
 		int mi = (lo + hi) / 2;
-		int cmp = memcmp((char *) index + (24 * mi) + 4, sha1, 20);
+		int cmp = memcmp((char *) idx + (24 * mi) + 4, sha1, 20);
 		if (!cmp) {
-			e->offset = ntohl(*((unsigned int *) ((char *) index + (24 * mi))));
+			e->offset = ntohl(*((unsigned int *) ((char *) idx + (24 * mi))));
 			memcpy(e->sha1, sha1, 20);
 			e->p = p;
 			return 1;
@@ -1376,12 +1376,12 @@ char *write_sha1_file_prepare(void *buf,
  *
  * Returns the errno on failure, 0 on success.
  */
-static int link_temp_to_file(const char *tmpfile, char *filename)
+static int link_temp_to_file(const char *tmp_file, char *filename)
 {
 	int ret;
 	char *dir;
 
-	if (!link(tmpfile, filename))
+	if (!link(tmp_file, filename))
 		return 0;
 
 	/*
@@ -1399,7 +1399,7 @@ static int link_temp_to_file(const char 
 		if (adjust_shared_perm(filename))
 			return -2;
 		*dir = '/';
-		if (!link(tmpfile, filename))
+		if (!link(tmp_file, filename))
 			return 0;
 		ret = errno;
 	}
@@ -1409,9 +1409,9 @@ static int link_temp_to_file(const char 
 /*
  * Move the just written object into its final resting place
  */
-int move_temp_to_file(const char *tmpfile, char *filename)
+int move_temp_to_file(const char *tmp_file, char *filename)
 {
-	int ret = link_temp_to_file(tmpfile, filename);
+	int ret = link_temp_to_file(tmp_file, filename);
 
 	/*
 	 * Coda hack - coda doesn't like cross-directory links,
@@ -1425,11 +1425,11 @@ int move_temp_to_file(const char *tmpfil
 	 * left to unlink.
 	 */
 	if (ret && ret != EEXIST) {
-		if (!rename(tmpfile, filename))
+		if (!rename(tmp_file, filename))
 			return 0;
 		ret = errno;
 	}
-	unlink(tmpfile);
+	unlink(tmp_file);
 	if (ret) {
 		if (ret != EEXIST) {
 			fprintf(stderr, "unable to write sha1 filename %s: %s\n", filename, strerror(ret));
@@ -1510,7 +1510,7 @@ int write_sha1_file(void *buf, unsigned 
 	z_stream stream;
 	unsigned char sha1[20];
 	char *filename;
-	static char tmpfile[PATH_MAX];
+	static char tmp_file[PATH_MAX];
 	unsigned char hdr[50];
 	int fd, hdrlen;
 
@@ -1537,11 +1537,11 @@ int write_sha1_file(void *buf, unsigned 
 		return -1;
 	}
 
-	snprintf(tmpfile, sizeof(tmpfile), "%s/obj_XXXXXX", get_object_directory());
+	snprintf(tmp_file, sizeof(tmp_file), "%s/obj_XXXXXX", get_object_directory());
 
-	fd = mkstemp(tmpfile);
+	fd = mkstemp(tmp_file);
 	if (fd < 0) {
-		fprintf(stderr, "unable to create temporary sha1 filename %s: %s\n", tmpfile, strerror(errno));
+		fprintf(stderr, "unable to create temporary sha1 filename %s: %s\n", tmp_file, strerror(errno));
 		return -1;
 	}
 
@@ -1574,7 +1574,7 @@ int write_sha1_file(void *buf, unsigned 
 	close(fd);
 	free(compressed);
 
-	return move_temp_to_file(tmpfile, filename);
+	return move_temp_to_file(tmp_file, filename);
 }
 
 /*
@@ -1646,7 +1646,7 @@ int write_sha1_to_fd(int fd, const unsig
 int write_sha1_from_fd(const unsigned char *sha1, int fd, char *buffer,
 		       size_t bufsize, size_t *bufposn)
 {
-	char tmpfile[PATH_MAX];
+	char tmp_file[PATH_MAX];
 	int local;
 	z_stream stream;
 	unsigned char real_sha1[20];
@@ -1654,12 +1654,12 @@ int write_sha1_from_fd(const unsigned ch
 	int ret;
 	SHA_CTX c;
 
-	snprintf(tmpfile, sizeof(tmpfile), "%s/obj_XXXXXX", get_object_directory());
+	snprintf(tmp_file, sizeof(tmp_file), "%s/obj_XXXXXX", get_object_directory());
 
-	local = mkstemp(tmpfile);
+	local = mkstemp(tmp_file);
 	if (local < 0)
 		return error("Couldn't open %s for %s",
-			     tmpfile, sha1_to_hex(sha1));
+			     tmp_file, sha1_to_hex(sha1));
 
 	memset(&stream, 0, sizeof(stream));
 
@@ -1690,7 +1690,7 @@ int write_sha1_from_fd(const unsigned ch
 		size = read(fd, buffer + *bufposn, bufsize - *bufposn);
 		if (size <= 0) {
 			close(local);
-			unlink(tmpfile);
+			unlink(tmp_file);
 			if (!size)
 				return error("Connection closed?");
 			perror("Reading from connection");
@@ -1703,15 +1703,15 @@ int write_sha1_from_fd(const unsigned ch
 	close(local);
 	SHA1_Final(real_sha1, &c);
 	if (ret != Z_STREAM_END) {
-		unlink(tmpfile);
+		unlink(tmp_file);
 		return error("File %s corrupted", sha1_to_hex(sha1));
 	}
 	if (memcmp(sha1, real_sha1, 20)) {
-		unlink(tmpfile);
+		unlink(tmp_file);
 		return error("File %s has bad hash", sha1_to_hex(sha1));
 	}
 
-	return move_temp_to_file(tmpfile, sha1_file_name(sha1));
+	return move_temp_to_file(tmp_file, sha1_file_name(sha1));
 }
 
 int has_pack_index(const unsigned char *sha1)
diff --git a/tree-walk.c b/tree-walk.c
index 3f83e98..9033c94 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -113,7 +113,7 @@ void traverse_trees(int n, struct tree_d
 	struct name_entry *entry = xmalloc(n*sizeof(*entry));
 
 	for (;;) {
-		struct name_entry entry[3];
+		struct name_entry ent[3];
 		unsigned long mask = 0;
 		int i, last;
 
@@ -121,9 +121,9 @@ void traverse_trees(int n, struct tree_d
 		for (i = 0; i < n; i++) {
 			if (!t[i].size)
 				continue;
-			entry_extract(t+i, entry+i);
+			entry_extract(t+i, ent+i);
 			if (last >= 0) {
-				int cmp = entry_compare(entry+i, entry+last);
+				int cmp = entry_compare(ent+i, ent+last);
 
 				/*
 				 * Is the new name bigger than the old one?
@@ -153,9 +153,9 @@ void traverse_trees(int n, struct tree_d
 				update_tree_entry(t+i);
 				continue;
 			}
-			entry_clear(entry + i);
+			entry_clear(ent + i);
 		}
-		callback(n, mask, entry, base);
+		callback(n, mask, ent, base);
 	}
 	free(entry);
 }
diff --git a/xdiff/xprepare.c b/xdiff/xprepare.c
index 1be7b31..4fa55bd 100644
--- a/xdiff/xprepare.c
+++ b/xdiff/xprepare.c
@@ -145,7 +145,7 @@ static int xdl_prepare_ctx(mmfile_t *mf,
 	xrecord_t **rhash;
 	unsigned long *ha;
 	char *rchg;
-	long *rindex;
+	long *r_idx;
 
 	if (xdl_cha_init(&xdf->rcha, sizeof(xrecord_t), narec / 4 + 1) < 0) {
 
@@ -220,7 +220,7 @@ static int xdl_prepare_ctx(mmfile_t *mf,
 	}
 	memset(rchg, 0, (nrec + 2) * sizeof(char));
 
-	if (!(rindex = (long *) xdl_malloc((nrec + 1) * sizeof(long)))) {
+	if (!(r_idx = (long *) xdl_malloc((nrec + 1) * sizeof(long)))) {
 
 		xdl_free(rchg);
 		xdl_free(rhash);
@@ -230,7 +230,7 @@ static int xdl_prepare_ctx(mmfile_t *mf,
 	}
 	if (!(ha = (unsigned long *) xdl_malloc((nrec + 1) * sizeof(unsigned long)))) {
 
-		xdl_free(rindex);
+		xdl_free(r_idx);
 		xdl_free(rchg);
 		xdl_free(rhash);
 		xdl_free(recs);
@@ -243,7 +243,7 @@ static int xdl_prepare_ctx(mmfile_t *mf,
 	xdf->hbits = hbits;
 	xdf->rhash = rhash;
 	xdf->rchg = rchg + 1;
-	xdf->rindex = rindex;
+	xdf->rindex = r_idx;
 	xdf->nreff = 0;
 	xdf->ha = ha;
 	xdf->dstart = 0;
-- 
1.4.2.rc2.gfbfdd

^ permalink raw reply related

* Re: File version at a specific date?
From: Shawn Pearce @ 2006-07-31 22:20 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <ealhrj$pdo$1@sea.gmane.org>

Jakub Narebski <jnareb@gmail.com> wrote:
> Alexander ZVYAGIN wrote:
> 
> > I failed to find in the documentation how to look to a file content
> > at some moment in a past.
> > 
> > Something like this:
> > $ git checkout master~2 Makefile
> > when I specify not the revisions numbers ago the file was (~2),
> > but the time, for example "2005-12-12 00:00:00" or something like this.
> > 
> > Where should I look at?
> 
> Either use git rev-list with --since=datestring, --after=datestring,
> --until=datestring, --before=datestring to find a commit, or if you have
> reflog enabled (you have .git/logs/refs/) you can use @{date} syntax,
> see 'man git-rev-parse'
> 
> "A suffix @ followed by a date specification enclosed in a brace pair  (e.g.
>  {yesterday},  {1  month  2 weeks 3 days 1 hour 1 second ago} or {1979-02-26
>  18:30:00}) to specify the value of the ref at a prior point in  time.  This
>  suffix  may  only be used immediately following a ref name and the ref must
>  have an existing log ($GIT_DIR/logs/<ref>)."

I'd like to add something to the discussion, at least for the
benefit of the archives:

There's a semantic difference between the two date specification/query
styles suggested above:

	git rev-list with --since, --after, --until, --before will
	look at the date of the commit;

	@{date} after a ref name will look at the commit that was
	stored under that ref name at that point in time.

These are two entirely different timelines.  For example someone
could make a commit on Tuesday which you pull into your repository
on Thursday.  The commit will say (and thus git rev-list with
--since will say) that the file version existed on Tuesday, but the
reflog would say that the file version existed only as of Thursday,
as that was when it became available to your repository.

-- 
Shawn.

^ permalink raw reply

* Re: Fix up some fallout from "setup_git_directory()" cleanups
From: Linus Torvalds @ 2006-07-31 22:21 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7v7j1t5tgj.fsf@assigned-by-dhcp.cox.net>



On Mon, 31 Jul 2006, Junio C Hamano wrote:
> 
> This would have been prevented if the rest of the sources were -Wshadow
> clean.

Well, the _real_ problem is that "-Wshadow" is such a crappy switch.

For example, there is absolutely no reason to warn about every local 
variable called "link", just because it shadows the unistd.h "link()" 
function.

So I tend to think that -Wshadow is actively wrong, because it makes 
people write crappier code by forcing them to avoid not just the (few) C 
keywords as variable names, but also the _millions_ of names exported by 
various standard header files.

Which is sad. "-Wshadow" _would_ be useful, if it had been designed right. 
But that definitely implies _not_ warning about name clashes that are also 
obvious type clashes.

For example, there's basically absolutely zero reason to warn about 
something clashing with a function. If you are crazy and use nested 
functions in gcc, it's still obvious _which_ function you'd ever mean. So 
"-Wshadow" simply should _never_ warn about clashing with the external 
"link()" declaration, and certainly not for a regular "int link" kind of 
automatic variable definition.

There's also seldom (if ever) any reason to warn about a pointer variable 
being shadowed by an integer one. If you use the wrong one, you'll get a 
type warning, so why would you really care? 

> I once tried to clean things up, but there are tons of
> warnings in the current code [*1*].

And, looking at your patch, they all (or a huge majority of them) seem to 
be totally bogus (ie the code is fine, the -Wshadow warning is crap).

> Another thing that would help us is to have more tests that run
> things from subdirectories.  Any takers?

This, btw, didn't just hit "git ls-files" when run in a subdirectory, it 
hit pretty much any use of "git ls-files" with a path specifier that 
included a directory. I don't think we have many uses of that, and at 
least one of the few tests for path specifiers (t3002) only tests in the 
current directory, no paths.

			Linus

^ permalink raw reply

* Re: Diff format in packs
From: Shawn Pearce @ 2006-07-31 22:32 UTC (permalink / raw)
  To: Jon Smirl; +Cc: Jakub Narebski, git
In-Reply-To: <9e4733910607311420n8537b76lbde4d60062195403@mail.gmail.com>

Jon Smirl <jonsmirl@gmail.com> wrote:
> On 7/31/06, Jakub Narebski <jnareb@gmail.com> wrote:
> >Jon Smirl wrote:
> >
> >> I'm trying to build a small app that takes a CVS ,v and writes out a
> >> pack corresponding to the versions. Suggestions on the most efficient
> >> strategy for doing this by calling straight into the git C code?
> >> Forking off git commands is not very efficient when done a million
> >> times.
> >
> >Something akin to parsecvs by Keith Packard?
> 
> I see the error in my thoughts now, I need the fully expanded delta to
> compute the sha-1 so I might as well use the parsecvs code.
> 
> I am working on combining cvs2svn, parsecvs and cvsps into something
> that can handle Mozilla CVS.

I think you sort of have the right idea.  Creating a pack file
from scratch without deltas is a very trivial operation.  The pack
format is documented in Documentation/technical/pack-format.txt.
The actual delta format isn't documented here and generating a delta
would be somewhat difficult, but creating a pack with no deltas
and only zlib compression is pretty simple.  And no, GIT doesn't
use the same (horrible) delta format as RCS so you definately are
right, you have to expand it before you can compress it.

Creating trees and commits from scratch is also really easy.  Calling
zlib and a SHA1 routine to create the checksum is the hard part.
I think I wrote the tree and commit construction part of jgit in
a few hours, and that was while I was also being distracted by
someone speaking in the front of the room.  :-)


It should be reasonably simple to extract each revision from a
single ,v file into its full undeltafied form, compute its SHA1,
compress it with zlib, and append it into a pack file.  Do that
for every file and toss the SHA1 values, file names and revision
numbers off into a table somewhere.

Then loop back through and generate trees while playing around only
with the RCS file paths, timestamps and SHA1 pointers.  Again tree
generation is extremely simple; it would be trivial to generate
tree objects and append them into the same (or another) pack.

Finally writing commit objects pointing at the trees is also easy,
without calling git-commit.

When you are all done run a `git-repack -a -d -f` and let the delta
code compress everything down.  That first compression might take
a little while but it should do a reasonably good job despite the
input pack(s) being highly unorganized.

So I think I'm suggesting you find a way to generate the base objects
yourself right into a pack file, rather than using the higher level
GIT executables to do it.  You may be able to reuse some of the
code in GIT but I know its writer code is organized for writing
loose objects, not for appending new objects into a new pack file,
so some surgery would probably be required.

-- 
Shawn.

^ permalink raw reply

* Re: [PATCH] gitweb: use a hash to lookup the sub for an action
From: Junio C Hamano @ 2006-07-31 22:39 UTC (permalink / raw)
  To: Matthias Lederhofer; +Cc: git
In-Reply-To: <E1G7faj-0006W8-17@moooo.ath.cx>

Matthias Lederhofer <matled@gmx.net> writes:

> Signed-off-by: Matthias Lederhofer <matled@gmx.net>

Yeah, finally.  I like this.

^ permalink raw reply

* Re: [PATCH 21] gitweb: use a hash to lookup the sub for an action
From: Jakub Narebski @ 2006-07-31 22:55 UTC (permalink / raw)
  To: git
In-Reply-To: <E1G7faj-0006W8-17@moooo.ath.cx>

Matthias Lederhofer wrote:

> Signed-off-by: Matthias Lederhofer <matled@gmx.net>

Acked-by: Jakub Narebski <jnareb@gmail.com>

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply

* Re: Diff format in packs
From: Jon Smirl @ 2006-07-31 23:08 UTC (permalink / raw)
  To: Shawn Pearce; +Cc: Jakub Narebski, git
In-Reply-To: <20060731223221.GB24888@spearce.org>

On 7/31/06, Shawn Pearce <spearce@spearce.org> wrote:
> It should be reasonably simple to extract each revision from a
> single ,v file into its full undeltafied form, compute its SHA1,
> compress it with zlib, and append it into a pack file.  Do that
> for every file and toss the SHA1 values, file names and revision
> numbers off into a table somewhere.

cvs2svn has put everything needed into a nice db4 database that I can
generate the trees from once I get the revisions into git. I'll modify
cvs2svn to record the SHA1 for the deltas when they are originally
scanned. The change set algorithm used by cvs2svn is the only one of
the bunch that can process moz cvs without errors or losing check-ins.
It takes 3.5hrs to generate the changeset db. There are over 1M deltas
to sort and 250K commits.

> So I think I'm suggesting you find a way to generate the base objects
> yourself right into a pack file, rather than using the higher level
> GIT executables to do it.  You may be able to reuse some of the
> code in GIT but I know its writer code is organized for writing
> loose objects, not for appending new objects into a new pack file,
> so some surgery would probably be required.

This makes sense, just put the objects into the pack and forget about
deltas for now. I can add deltas in the next rewrite or just use
git-repack. Since cvs2svn is in Python I need to figure out how to
write a pack file from that environment. At least Python has sha1 and
zlib support built-in.

What is more important is that I get a working incremental update
functioning. I'm hoping that I can rely on cvsps for that. Cutting
everyone over at once is unlikely to happen.

-- 
Jon Smirl
jonsmirl@gmail.com

^ permalink raw reply

* Fresh stuff Impress your girl with prolonged hardness, plentiful explosions and increased duration
From: Lester @ 2006-07-31 23:09 UTC (permalink / raw)
  To: git

Dear valued customer.

 Rock hard manhood, multiple explosions and several times more semen volumeRock hard manhood, multiple explosions and several times more semen volume


Masculine performance has never been so easy to increase with these products


 See our offer: http://www.audionjn.com


Lester Smallwood

Distance lends enchantment to the view It is possible to give without loving but it is impossible to love without giving Perfection is inperfect Chaste makes waste.

Good and quickly seldom meet  It is nice to be important but it is more important to be nice

^ permalink raw reply

* Re: Fix up some fallout from "setup_git_directory()" cleanups
From: Johannes Schindelin @ 2006-07-31 23:19 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0607311508060.4168@g5.osdl.org>

Hi,

On Mon, 31 Jul 2006, Linus Torvalds wrote:

> "-Wshadow" _would_ be useful, if it had been designed right. But that 
> definitely implies _not_ warning about name clashes that are also 
> obvious type clashes.

Wouldn't this just be a _perfect_ task for 'sparse'?

Ciao,
Dscho

^ permalink raw reply

* Re: Diff format in packs
From: Martin Langhoff @ 2006-08-01  0:47 UTC (permalink / raw)
  To: Jon Smirl; +Cc: Jakub Narebski, git
In-Reply-To: <9e4733910607311420n8537b76lbde4d60062195403@mail.gmail.com>

Jon,

just get all the file versions out of the ,v file and into the GIT
repo, then do find .git/objects/ -type f | git-pack-objects. You don't
have to even think of generating the packfile yourself.

On 8/1/06, Jon Smirl <jonsmirl@gmail.com> wrote:
> I am working on combining cvs2svn, parsecvs and cvsps into something
> that can handle Mozilla CVS.

If you publish your WIP somewhere, I might be able to jump in and help
a bit. I've seen your "challenge" email earlier, but haven't been able
to get started yet -- lots of work on other foss fronts.

cheers,


martin

^ permalink raw reply

* [PATCH 22]
From: Jakub Narebski @ 2006-08-01  0:59 UTC (permalink / raw)
  To: git
In-Reply-To: <200607292239.11034.jnareb@gmail.com>

>From d69d3357f134bb5548f18fafff7664499adc1fcd Mon Sep 17 00:00:00 2001
From: Jakub Narebski <jnareb@gmail.com>
Date: Tue, 1 Aug 2006 02:56:51 +0200
Subject: [PATCH] gitweb: Refactoring git_project_list

Slightly reworking git_project_list, including moving setting $order,
as it is used only in this action. Mostly reindent.

Signed-off-by: Jakub Narebski <jnareb@gmail.com>
---
After Matthias Lederhofer <matled@gmx.net> patch,
"[PATCH] gitweb: use a hash to lookup the sub for an action"

 gitweb/gitweb.cgi |   57 +++++++++++++++++++++++++++++++++--------------------
 1 files changed, 35 insertions(+), 22 deletions(-)

diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi
index 75390c8..27c36ef 100755
--- a/gitweb/gitweb.cgi
+++ b/gitweb/gitweb.cgi
@@ -80,14 +80,6 @@ if (defined $action) {
 	}
 }
 
-our $order = $cgi->param('o');
-if (defined $order) {
-	if ($order =~ m/[^0-9a-zA-Z_]/) {
-		undef $order;
-		die_error(undef, "Invalid order parameter.");
-	}
-}
-
 our $project = ($cgi->param('p') || $ENV{'PATH_INFO'});
 if (defined $project) {
 	$project =~ s|^/||; $project =~ s|/$||;
@@ -1303,10 +1295,15 @@ sub git_logo {
 }
 
 sub git_project_list {
+	my $order = $cgi->param('o');
+	if (defined $order && $order !~ m/project|descr|owner|age/) {
+		die_error(undef, "Invalid order parameter '$order'.");
+	}
+
 	my @list = git_read_projects();
 	my @projects;
 	if (!@list) {
-		die_error(undef, "No project found.");
+		die_error(undef, "No projects found.");
 	}
 	foreach my $pr (@list) {
 		my $head = git_read_head($pr->{'path'});
@@ -1328,6 +1325,7 @@ sub git_project_list {
 		}
 		push @projects, $pr;
 	}
+
 	git_header_html();
 	if (-f $home_text) {
 		print "<div class=\"index_include\">\n";
@@ -1338,29 +1336,42 @@ sub git_project_list {
 	}
 	print "<table class=\"project_list\">\n" .
 	      "<tr>\n";
-	if (!defined($order) || (defined($order) && ($order eq "project"))) {
+	$order ||= "project";
+	if ($order eq "project") {
 		@projects = sort {$a->{'path'} cmp $b->{'path'}} @projects;
 		print "<th>Project</th>\n";
 	} else {
-		print "<th>" . $cgi->a({-class => "header", -href => "$my_uri?" . esc_param("o=project")}, "Project") . "</th>\n";
+		print "<th>" .
+		      $cgi->a({-href => "$my_uri?" . esc_param("o=project"),
+		               -class => "header"}, "Project") .
+		      "</th>\n";
 	}
-	if (defined($order) && ($order eq "descr")) {
+	if ($order eq "descr") {
 		@projects = sort {$a->{'descr'} cmp $b->{'descr'}} @projects;
 		print "<th>Description</th>\n";
 	} else {
-		print "<th>" . $cgi->a({-class => "header", -href => "$my_uri?" . esc_param("o=descr")}, "Description") . "</th>\n";
+		print "<th>" .
+		      $cgi->a({-href => "$my_uri?" . esc_param("o=descr"),
+		               -class => "header"}, "Description") .
+		      "</th>\n";
 	}
-	if (defined($order) && ($order eq "owner")) {
+	if ($order eq "owner") {
 		@projects = sort {$a->{'owner'} cmp $b->{'owner'}} @projects;
 		print "<th>Owner</th>\n";
 	} else {
-		print "<th>" . $cgi->a({-class => "header", -href => "$my_uri?" . esc_param("o=owner")}, "Owner") . "</th>\n";
+		print "<th>" .
+		      $cgi->a({-href => "$my_uri?" . esc_param("o=owner"),
+		               -class => "header"}, "Owner") .
+		      "</th>\n";
 	}
-	if (defined($order) && ($order eq "age")) {
+	if ($order eq "age") {
 		@projects = sort {$a->{'commit'}{'age'} <=> $b->{'commit'}{'age'}} @projects;
 		print "<th>Last Change</th>\n";
 	} else {
-		print "<th>" . $cgi->a({-class => "header", -href => "$my_uri?" . esc_param("o=age")}, "Last Change") . "</th>\n";
+		print "<th>" .
+		      $cgi->a({-href => "$my_uri?" . esc_param("o=age"),
+		               -class => "header"}, "Last Change") .
+		      "</th>\n";
 	}
 	print "<th></th>\n" .
 	      "</tr>\n";
@@ -1372,14 +1383,16 @@ sub git_project_list {
 			print "<tr class=\"light\">\n";
 		}
 		$alternate ^= 1;
-		print "<td>" . $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=summary"), -class => "list"}, esc_html($pr->{'path'})) . "</td>\n" .
+		print "<td>" . $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=summary"),
+		                        -class => "list"}, esc_html($pr->{'path'})) . "</td>\n" .
 		      "<td>" . esc_html($pr->{'descr'}) . "</td>\n" .
 		      "<td><i>" . chop_str($pr->{'owner'}, 15) . "</i></td>\n";
-		print "<td class=\"". age_class($pr->{'commit'}{'age'}) . "\">" . $pr->{'commit'}{'age_string'} . "</td>\n" .
+		print "<td class=\"". age_class($pr->{'commit'}{'age'}) . "\">" .
+		      $pr->{'commit'}{'age_string'} . "</td>\n" .
 		      "<td class=\"link\">" .
-		      $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=summary")}, "summary") .
-		      " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=shortlog")}, "shortlog") .
-		      " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=log")}, "log") .
+		      $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=summary")}, "summary")   . " | " .
+		      $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=shortlog")}, "shortlog") . " | " .
+		      $cgi->a({-href => "$my_uri?" . esc_param("p=$pr->{'path'};a=log")}, "log") .
 		      "</td>\n" .
 		      "</tr>\n";
 	}
-- 
1.4.1.1

^ permalink raw reply related

* Re: Diff format in packs
From: Martin Langhoff @ 2006-08-01  1:03 UTC (permalink / raw)
  To: Jon Smirl; +Cc: Jakub Narebski, git
In-Reply-To: <46a038f90607311747j947c786s6af2fe637dbde89d@mail.gmail.com>

On 8/1/06, Martin Langhoff <martin.langhoff@gmail.com> wrote:
> just get all the file versions out of the ,v file and into the GIT
> repo, then do find .git/objects/ -type f | git-pack-objects. You don't
> have to even think of generating the packfile yourself.

Well, that's a bit of a lie, using bare find won't quite work, but if
you look up the "Repacking many disconnected blobs" thread, there's a
good discussion of packing objects that are not related to trees yet.

martin

^ permalink raw reply

* Re: Diff format in packs
From: Jon Smirl @ 2006-08-01  1:13 UTC (permalink / raw)
  To: Martin Langhoff; +Cc: Jakub Narebski, git
In-Reply-To: <46a038f90607311747j947c786s6af2fe637dbde89d@mail.gmail.com>

On 7/31/06, Martin Langhoff <martin.langhoff@gmail.com> wrote:
> Jon,
>
> just get all the file versions out of the ,v file and into the GIT
> repo, then do find .git/objects/ -type f | git-pack-objects. You don't
> have to even think of generating the packfile yourself.

Moz CVS expands into over 1M files and 12GB in size. I keep getting
concerned about algorithms that take days to complete and need 4GB to
run.

> On 8/1/06, Jon Smirl <jonsmirl@gmail.com> wrote:
> > I am working on combining cvs2svn, parsecvs and cvsps into something
> > that can handle Mozilla CVS.
>
> If you publish your WIP somewhere, I might be able to jump in and help
> a bit. I've seen your "challenge" email earlier, but haven't been able
> to get started yet -- lots of work on other foss fronts.

I haven't got anything useful yet, I keep switching in and out of
working on this. I am still trying to work out a viable transition
strategy that I can attempt to sell the Mozilla developers on. So far
I don't have one.

The requirements I have so far:
1) the conversion needs to be reproducible so that Moz staff can do it
internally without a lot of hassle. They need to verify that nothing
has been lost.
2) It shouldn't need a monster machine to run it and it can't take
days to finish
3) It has to have incremental support so that it can be run in
parallel with CVS with commits still going to CVS.
4) nothing can be lost out of existing CVS
5) a bonus feature would be a partial repository to avoid the initial
700MB git download.

cvsps meets these requirements except for not losing anything out of
the existing CVS. cvsps is throwing away some items it finds
confusing. So far the only algorithm that appears to successfully
convert all branches into change sets is the algorithm in cvs2svn.
http://cvs2svn.tigris.org/source/browse/cvs2svn/trunk/design-notes.txt?rev=2536&view=markup

I've spent more time looking at parsecvs than cvsps, is it reasonable
to convert cvsps to the algorithm described above? Another strategy
would be to use cvs2svn to build the changeset database and then use
cvsps to simply read the changesets out of it and build the git
repository.

Parsecvs never finishes the conversion it always hits an error or GPF
after 4-5 hours, probably a wild pointer somewhere.

-- 
Jon Smirl
jonsmirl@gmail.com

^ permalink raw reply

* Why I love GIT but use Subversion (was: GIT user survey)
From: Jörg W Mittag @ 2006-08-01  1:45 UTC (permalink / raw)
  To: git
In-Reply-To: <4d8e3fd30607300248m36b4038dv1fcd1f3716503905@mail.gmail.com>

Paolo Ciarrocchi wrote:
> On 7/23/06, Paolo Ciarrocchi <paolo.ciarrocchi@gmail.com> wrote:
>> We would like to ask you a few questions about your use of the GIT
>> version control system. This survey is mainly to understand who is
>> using GIT, how and why.
> Thanks a lot to all the people that already filled the questionnaire.
> We received 89 full filled questionnaires but we can do better, if you
> didn't fill it please do it before the 6th of August.

Okay, I thought a bit about filling out that survey, but I couldn't
because it didn't really fit my needs.  After all, it's a Git *user*
survey and I'm only a *wannabe* user.

So, why am I only a wannabe Git user (and a frustrated Subversion
user) even though I like Git very much?  Well, there's a couple of
reasons (beware: this rant should have really been a blog post, but I
don't have a blog ...; also, being a rant, this post may contain
oversimplification, overgeneralization and overexaggeration.  Please,
don't feel offended and also keep in mind that I'm not a native
speaker.).

The most important reason why I'm not using Git is probably that I'm
the wrong kind of user: Git is a source code(1) management system for
Linux(2) developers(3) and I am

  (1) not managing source code, 
  (2) not using Linux and 
  (3) not a developer.
  
Please note that there's nothing actually wrong with that---you can't
drive screws with a hammer and you can't make coffee with a
screwdriver but that doesn't mean that the hammer or the screwdriver
are buggy, it just means you have either the wrong problem or the
wrong tool.

So, I don't really know whether the fact that Git doesn't support my
operating environment and my workflow is (a) a problem with Git being
too specialized or (b) a problem with me choosing the wrong tool.
This is probably actually the most important question I have, because
if the answer is (a) I just need to wait some more until Git matures,
but if the answer is (b) I need to forget about Git and start looking
for another tool.

In my opinion, version control needs to integrate and really blend
into the operating environment and the workflow people use, because
otherwise, if it *doesn't* integrate but forces them to change their
operating environment, their workflow or their habits, people will get
lazy.  I know I would.  And being lazy about version control is even
worse than not having any version control at all, just as with backups
it gives you a false sense of security.

In my case the operating environment is the Windows Explorer or
Eclipse and my workflow is basically dragging and dropping files with
the mouse.  I can do just that with TortoiseSVN and Subclipse without
having to change the way I normally work.  With Git I would constantly
need to switch back and forth between Explorer or Eclipse and Cygwin.
That is, if I actually get Git compiled and up and running *at all*.
(Is there any unwritten rule in Git development that says that new
features are only accepted if they add a new dependency on a new
programming language?  Currently Git is implemented in C, POSIX sh,
Perl, Python, Tcl/Tk and C++ (if you include QGit) and I've already
seen some Ruby code posted to the mailing list.)

Don't get me wrong: Git is very nice.  Its similarity to a Unix
filesystem and the similarity of its UI to popular Unix command line
utilities means that it actually integrates perfectly with the Unix
shell, which also means that it integrates perfectly with the workflow
of people who mainly work in a Unix shell.  I'm sometimes using Git in
Linux where I mainly work from the command line and it's absolutely
amazing!  You have everything you would expect from your regular
environment: cat, diff, ls, tar, grep, mv, rm and even fsck!

But that's not the only operating environment, and it's certainly not
the one most widely used.  In order to be universally usable, Git
needs to also integrate with the Windows Explorer, MacOS Finder,
Konqueror, Nautilus, Eclipse and Visual Studio (among others).  It
needs to integrate with project management tools like Trac or Collaboa
and in order to do that it probably needs complete high-quality native
language bindings for Java, Perl, Python, Ruby, PHP, ...

Okay, let's answer two questions from the survey:

| Q20. What would you most like to see improved about GIT? (features,
|        bugs, plugins, documentation, ...)

The most pressing need for me would be a native Windows port.  Where
"native" means:

 - an installer package, 
 - integration with the Windows Explorer, 
 - handling of different line-ending encodings and 
 - addressing the fact that things like SSH clients, diff, patch, 
     merge, Perl, Python, Tcl/Tk, Bash and so on are usually not part 
     of a standard Windows installation and are also notoriously 
     difficult to install.

Number 2 would probably be providing the same level of integration for
Eclipse.

| Q21. If you want to see GIT more widely used, what do you think we
|        could do to make this happen?

What I think is most lacking is the ecosystem *around* Git, which is
actually not very surprising, considering that Git is still fairly
young compared to e.g. CVS and Subversion.  With "ecosystem" I mean
things like public repository hosting (currently it's mostly CVS
and/or Subversion and some Arch), integration in IDEs (e.g. Eclipse,
Visual Studio), project management software (e.g. Trac, Collaboa) and
so on.

The general theme is probably: make Git more seamless for more types
of users on more operating systems.

I currently use Subversion.  I hate Subversion.  I constanly hit the
limitations of the centralized model, and I hit them *very hard* and
*very often*.  I would *love* to migrate away as soon as possible.
There's only two reasons why I use Subversion: because I can install
it with three mouse clicks and because I can use it with three mouse
clicks.

Please, make those reasons go away.

Thank you for bearing with me through this long rant.

jwm

PS: I am well aware of the fact that Git is free software and that I
could fix all those issues myself.  However, the truth is, I can't.
I'm stupid.  I'm not a programmer.  So, please don't take this as a
demand or a request, merely a humble suggestion by a humble wannabe
user, whom you are free to ignore.

^ permalink raw reply

* Perhaps an obvious cut and paste error.
From: Junio C Hamano @ 2006-08-01  2:12 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <200608010259.13721.jnareb@gmail.com>

diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi
index 4e79390..a4a46d9 100755
--- a/gitweb/gitweb.cgi
+++ b/gitweb/gitweb.cgi
@@ -1441,7 +1434,7 @@ sub git_summary {
 	my $headlist = git_read_refs("refs/heads");
 	if (defined @$headlist) {
 		git_header_div('heads');
-		git_heads_body($taglist, $head, 0, 15,
+		git_heads_body($headlist, $head, 0, 15,
 		               $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=heads")}, "..."));
 	}
 

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox