Git development
 help / color / mirror / Atom feed
* [PATCH] [RFC] Introduce Git.pm
From: Petr Baudis @ 2006-06-22  0:35 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

This patch introduces a very basic and barebone Git.pm module
with a sketch of how the generic interface would look like;
most functions are missing, but this should give some good base.
I will expand it in the next days.

Most desirable now is proper error reporting, generic_in() for feeding
input to Git commands and the repository() constructor doing some poking
with git-rev-parse to get the git directory and subdirectory prefix.
Those three are basically the prerequisities for converting git-mv.

Currently Git.pm just wraps up exec()s of Git commands, but even that
is not trivial to get right and various Git perl scripts do it in
various inconsistent ways. And things will get much more interesting
when we get to XS-izing libgit.

This adds the Git.pm, integrates it to the build system and as an example
converts the git-fmt-merge-msg.perl script to it (the result is not very
impressive since its advantage is not quite apparent in this one, but I
just picked up the simplest Git user around).

This is mostly to show up what I have so far and gather some comments
on the general shapes of the interface; I guess in the current shape
of the API it's suitable for pu at best, but that's not my call.

My current working state is available all the time at

	http://pasky.or.cz/~xpasky/git-perl/Git.pm

and an irregularily updated API documentation is at

	http://pasky.or.cz/~xpasky/git-perl/Git.html

Signed-off-by: Petr Baudis <pasky@suse.cz>
---

 Makefile               |   13 ++
 git-fmt-merge-msg.perl |    9 +-
 perl/Git.pm            |  284 ++++++++++++++++++++++++++++++++++++++++++++++++
 perl/Makefile.PL       |   14 ++
 4 files changed, 314 insertions(+), 6 deletions(-)

diff --git a/Makefile b/Makefile
index 0887945..59eca6d 100644
--- a/Makefile
+++ b/Makefile
@@ -479,7 +479,8 @@ ### Build rules
 
 all: $(ALL_PROGRAMS) $(BUILT_INS) git$X gitk
 
-all:
+all: perl/Makefile
+	$(MAKE) -C perl
 	$(MAKE) -C templates
 
 strip: $(PROGRAMS) git$X
@@ -511,7 +512,7 @@ common-cmds.h: Documentation/git-*.txt
 
 $(patsubst %.perl,%,$(SCRIPT_PERL)) : % : %.perl
 	rm -f $@ $@+
-	sed -e '1s|#!.*perl|#!$(PERL_PATH_SQ)|' \
+	sed -e '1s|#!.*perl\(.*\)|#!$(PERL_PATH_SQ)\1 -I'"$$(make -s -C perl instlibdir)"'|' \
 	    -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
 	    $@.perl >$@+
 	chmod +x $@+
@@ -599,6 +600,9 @@ XDIFF_OBJS=xdiff/xdiffi.o xdiff/xprepare
 	rm -f $@ && $(AR) rcs $@ $(XDIFF_OBJS)
 
 
+perl/Makefile:	perl/Git.pm perl/Makefile.PL
+	(cd perl && $(PERL_PATH) Makefile.PL PREFIX="$(prefix)")
+
 doc:
 	$(MAKE) -C Documentation all
 
@@ -618,6 +622,7 @@ GIT-CFLAGS: .FORCE-GIT-CFLAGS
 	@FLAGS='$(TRACK_CFLAGS)'; \
 	    if test x"$$FLAGS" != x"`cat GIT-CFLAGS 2>/dev/null`" ; then \
 		echo 1>&2 "    * new build flags or prefix"; \
+		echo 1>&2 "    * $$FLAGS != `cat GIT-CFLAGS 2>/dev/null`"; \
 		echo "$$FLAGS" >GIT-CFLAGS; \
             fi
 
@@ -654,6 +659,7 @@ install: all
 	$(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(gitexecdir_SQ)'
 	$(INSTALL) git$X gitk '$(DESTDIR_SQ)$(bindir_SQ)'
 	$(MAKE) -C templates install
+	$(MAKE) -C perl install
 	$(INSTALL) -d -m755 '$(DESTDIR_SQ)$(GIT_PYTHON_DIR_SQ)'
 	$(INSTALL) $(PYMODULES) '$(DESTDIR_SQ)$(GIT_PYTHON_DIR_SQ)'
 	if test 'z$(bindir_SQ)' != 'z$(gitexecdir_SQ)'; \
@@ -721,7 +727,8 @@ clean:
 	rm -f $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz
 	rm -f $(htmldocs).tar.gz $(manpages).tar.gz
 	$(MAKE) -C Documentation/ clean
-	$(MAKE) -C templates clean
+	[ ! -e perl/Makefile ] || $(MAKE) -C perl/ clean
+	$(MAKE) -C templates/ clean
 	$(MAKE) -C t/ clean
 	rm -f GIT-VERSION-FILE GIT-CFLAGS
 
diff --git a/git-fmt-merge-msg.perl b/git-fmt-merge-msg.perl
index 5986e54..a2da46e 100755
--- a/git-fmt-merge-msg.perl
+++ b/git-fmt-merge-msg.perl
@@ -6,6 +6,9 @@ # Read .git/FETCH_HEAD and make a human 
 # by grouping branches and tags together to form a single line.
 
 use strict;
+use Git;
+
+my $repo = Git->repository();
 
 my @src;
 my %src;
@@ -28,12 +31,12 @@ sub andjoin {
 }
 
 sub repoconfig {
-	my ($val) = qx{git-repo-config --get merge.summary};
+	my ($val) = $repo->generic_oneline('repo-config', '--get', 'merge.summary');
 	return $val;
 }
 
 sub current_branch {
-	my ($bra) = qx{git-symbolic-ref HEAD};
+	my ($bra) = $repo->generic_oneline('symbolic-ref', 'HEAD');
 	chomp($bra);
 	$bra =~ s|^refs/heads/||;
 	if ($bra ne 'master') {
@@ -47,7 +50,7 @@ sub current_branch {
 sub shortlog {
 	my ($tip) = @_;
 	my @result;
-	foreach ( qx{git-log --no-merges --topo-order --pretty=oneline $tip ^HEAD} ) {
+	foreach ($repo->generic('log', '--no-merges', '--topo-order', '--pretty=oneline', $tip, '^HEAD')) {
 		s/^[0-9a-f]{40}\s+//;
 		push @result, $_;
 	}
diff --git a/perl/Git.pm b/perl/Git.pm
new file mode 100644
index 0000000..2f968c5
--- /dev/null
+++ b/perl/Git.pm
@@ -0,0 +1,284 @@
+=head1 NAME
+
+Git - Perl interface to the Git version control system
+
+=cut
+
+
+package Git;
+
+use strict;
+
+use vars qw ($VERSION @ISA @EXPORT @EXPORT_OK);
+
+# Totally unstable API.
+$VERSION = "0.0.1";
+
+
+=head1 SYNOPSIS
+
+  use Git;
+
+  my $version = Git::generic_oneval('version');
+
+  Git::generic_vocal('update-server-info');
+
+  my $repo = Git->repository (Directory => '/srv/git/cogito.git');
+
+
+  my @revs = $repo->generic('rev-list', '--since=last monday', '--all');
+
+  my $fh = $repo->generic('rev-list', '--since=last monday', '--all');
+  my $lastrev = <$fh>; chomp $lastrev;
+  close $fh;
+
+  my $lastrev = $repo->generic_oneval('rev-list', '--all');
+
+=cut
+
+
+require Exporter;
+
+@ISA = qw(Exporter);
+
+@EXPORT = qw();
+
+# Methods which can be called as standalone functions as well:
+@EXPORT_OK = qw(generic generic_oneval generic_vocal);
+
+
+=head1 DESCRIPTION
+
+This module provides Perl scripts easy way to interface the Git version control
+system. The modules have an easy and well-tested way to call arbitrary Git
+commands; in the future, the interface will also provide specialized methods
+for doing easily operations which are not totally trivial to do over the generic
+interface.
+
+While some commands can be executed outside of any context (e.g. 'version'
+or 'init-db'), most operations require a repository context, which in practice
+means getting an instance of the Git object using the repository() constructor.
+(In the future, we will also get a new_repository() constructor.) All commands
+called as methods of the object are then executed in the context of the
+repository.
+
+TODO: In the future, we might also do
+
+	my $subdir = $repo->subdir('Documentation');
+	# Gets called in the subdirectory context:
+	$subdir->generic('status');
+
+	my $remoterepo = $repo->remote_repository (name => 'cogito', branch => 'master');
+	$remoterepo ||= Git->remote_repository ('http://git.or.cz/cogito.git/');
+	my @refs = $remoterepo->refs();
+
+So far, all functions just die if anything goes wrong. If you don't want that,
+make appropriate provisions to catch the possible deaths. Better error recovery
+mechanisms will be provided in the future.
+
+Currently, the module merely wraps calls to external Git tools. In the future,
+it will provide a much faster way to interact with Git by linking directly
+to libgit. This should be completely opaque to the user, though (performance
+increate nonwithstanding).
+
+=cut
+
+
+use IPC::Open3;
+
+
+=head1 CONSTRUCTORS
+
+=over 4
+
+=item repository ( OPTIONS )
+
+=item repository ( DIRECTORY )
+
+=item repository ()
+
+Construct a new repository object.
+C<OPTIONS> are passed in a hash like fashion, using key and value pairs.
+Possible options are:
+
+B<Repository> - Path to the Git repository.
+
+B<WorkingCopy> - Path to the associated working copy; not strictly required
+as many commands will happily crunch on a bare repository.
+
+B<Directory> - Path to the Git working directory in its usual setup. This
+is just for convenient setting of both C<Repository> and C<WorkingCopy>
+at once: If the directory as a C<.git> subdirectory, C<Repository> is pointed
+to the subdirectory and the directory is assumed to be the working copy.
+If the directory does not have the subdirectory, C<WorkingCopy> is left
+undefined and C<Repository> is pointed to the directory itself.
+
+You should not use both C<Directory> and either of C<Repository> and
+C<WorkingCopy> - the results of that are undefined.
+
+Alternatively, a directory path may be passed as a single scalar argument
+to the constructor; it is equivalent to setting only the C<Directory> option
+field.
+
+Calling the constructor with no options whatsoever is equivalent to
+calling it with C<< Directory => '.' >>.
+
+=cut
+
+sub repository {
+	my $class = shift;
+	my @args = @_;
+	my %opts = ();
+	my $self;
+
+	if (defined $args[0]) {
+		if ($#args % 2 != 1) {
+			# Not a hash.
+			$#args == 0 or die "Git::repository(): bad usage";
+			%opts = (Directory => $args[0]);
+		} else {
+			%opts = @args;
+		}
+
+		if ($opts{Directory}) {
+			-d $opts{Directory} or die "Git::repository($opts{Directory}): $!";
+			if (-d $opts{Directory}."/.git") {
+				# TODO: Might make this more clever
+				$opts{WorkingCopy} = $opts{Directory};
+				$opts{Repository} = $opts{Directory}."/.git";
+			} else {
+				$opts{Repository} = $opts{Directory};
+			}
+			delete $opts{Directory};
+		}
+	}
+
+	$self = { opts => \%opts };
+	bless $self, $class;
+}
+
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item generic ( COMMAND [, ARGUMENTS... ] )
+
+Execute the given Git C<COMMAND> (specify it without the 'git-'
+prefix), optionally with the specified extra C<ARGUMENTS>. The method can be
+called without any instance or on a specified Git repository.
+
+In scalar context, it returns a filehandle containing the command output.
+
+In array context, it returns an array containing lines printed to the
+command's stdout.
+
+In both cases, the command's stdin and stderr are the same as the caller's.
+
+=cut
+
+sub generic {
+	my ($self, $cmd, @args) = _maybe_self(@_);
+
+	$cmd =~ /^[a-z0-9A-Z_-]+$/ or die "bad command: $cmd";
+
+	my $pid = open(my $fh, "-|");
+	if ($pid < 0) {
+		die "generic($cmd, @args) open: $!";
+	} elsif ($pid == 0) {
+		_do_exec($self, $cmd, @args);
+	}
+
+	return $fh unless wantarray;
+
+	my @lines = <$fh>;
+	close $fh;
+	chomp @lines;
+	return @lines;
+}
+
+=item generic_oneline ( COMMAND [, ARGUMENTS... ] )
+
+Execute the given C<COMMAND> in the same way as generic()
+does but always return a scalar string containing the first line
+of the command's standard output.
+
+=cut
+
+sub generic_oneline {
+	my $fh = generic(@_);
+	my $line = <$fh>;
+	close $fh;
+	chomp $line;
+	return $line;
+}
+
+=item generic_vocal ( COMMAND [, ARGUMENTS... ] )
+
+Execute the given C<COMMAND> in the same way as generic() does but does not
+capture the command output - the standard output is not redirected and goes
+to the standard output of the caller application.
+
+While the method is called generic_vocal(), you might want to as well use
+it for the most silent Git commands which you know will never pollute your
+stdout but you want to avoid the overhead of the pipe setup when calling them.
+
+The function returns only after the command has finished running.
+
+=cut
+
+sub generic_vocal {
+	my ($self, $cmd, @args) = _maybe_self(@_);
+
+	$cmd =~ /^[a-z0-9A-Z_-]+$/ or die "bad command: $cmd";
+
+	my $pid = fork;
+	if ($pid < 0) {
+		die "generic_vocal($cmd, @args) fork: $!";
+	} elsif ($pid == 0) {
+		_do_exec($self, $cmd, @args);
+	}
+	waitpid($pid, 0);
+}
+
+
+=back
+
+=head1 TODO
+
+This is still fairly crude. Repository objects not yet supported.
+We need some good way to report errors back except just dying.
+
+=head1 COPYRIGHT
+
+Copyright 2006 by Petr Baudis E<lt>pasky@suse.czE<gt>.
+
+This module is free software; it may be used, copied, modified
+and distributed under the terms of the GNU General Public Licence,
+either version 2, or (at your option) any later version.
+
+=cut
+
+
+# Takes raw method argument list and returns ($obj, @args) in case
+# the method was called upon an instance and (undef, @args) if
+# it was called directly.
+sub _maybe_self {
+	# This breaks inheritance. Oh well.
+	ref $_[0] eq 'Git' ? @_ : (undef, @_);
+}
+
+# When already in the subprocess, set up the appropriate state
+# for the given repository and execute the git command.
+sub _do_exec {
+	my ($self, @args) = @_;
+	if ($self) {
+		$self->{opts}->{Repository} and $ENV{'GIT_DIR'} = $self->{opts}->{Repository};
+		$self->{opts}->{WorkingCopy} and chdir($self->{opts}->{WorkingCopy});
+	}
+	exec ('git', @args) or die "Git exec: $!";
+}
+
+1; # Famous final words
diff --git a/perl/Makefile.PL b/perl/Makefile.PL
new file mode 100644
index 0000000..703ea98
--- /dev/null
+++ b/perl/Makefile.PL
@@ -0,0 +1,14 @@
+use ExtUtils::MakeMaker;
+
+sub MY::postamble {
+	return <<'MAKE_FRAG';
+instlibdir:
+	@echo $(INSTALLSITELIB)
+
+MAKE_FRAG
+}
+
+WriteMakefile(
+	NAME            => 'Git',
+	VERSION_FROM    => 'Git.pm'
+);

^ permalink raw reply related

* Re: gitk lower pane (commit and files view) scrollbar extends past gitk window
From: Edgar Toernig @ 2006-06-22  0:35 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <e7ber7$qh9$1@sea.gmane.org>

Jakub Narebski wrote:
>
> In gitk from the current 'next' branch, post git version 1.4.0 
> (blob ba4644f) scrollbar for lower pane, i.e. for commitdiff and files
> (Comments) views extends past the bottom of the gitk window. Therefore 
> I cannnot see lower part of commit diff if it is larger than window height.

Yes, and the search field at the bottom is invisible too.  Removing
line 431:

        .ctop conf -width $geometry(width) -height $geometry(height)

seems to fix it and the window still gets the right size.

Ciao, ET.

^ permalink raw reply

* Re: [PATCH 4/4] upload-pack/fetch-pack: support side-band communication
From: Junio C Hamano @ 2006-06-22  0:17 UTC (permalink / raw)
  To: git; +Cc: Jon Loeliger
In-Reply-To: <7vsllyzs9w.fsf@assigned-by-dhcp.cox.net>

Junio C Hamano <junkio@cox.net> writes:

> This implements a protocol extension between fetch-pack and
> upload-pack to allow stderr stream from upload-pack (primarily
> used for the progress bar display) to be passed back.
>
> Signed-off-by: Junio C Hamano <junkio@cox.net>
> ---
>
>  * With this, fetching and cloning over git+ssh:// and git://
>    does not discard the progress bar and error messages that
>    upload-pack emits on its standard output.  They are sent to
>    the downloader and shown to the user.
>
>    Somehow this does not work when connecting to git daemon that
>    runs under inetd.  Fixes appreciated.

This seems to fix it.

-- >8 --
Subject: [PATCH] daemon: send stderr to /dev/null instead of closing.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---
 daemon.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/daemon.c b/daemon.c
index bdfe80d..0747ce2 100644
--- a/daemon.c
+++ b/daemon.c
@@ -757,7 +757,7 @@ int main(int argc, char **argv)
 		struct sockaddr *peer = (struct sockaddr *)&ss;
 		socklen_t slen = sizeof(ss);
 
-		fclose(stderr); //FIXME: workaround
+		freopen("/dev/null", "w", stderr);
 
 		if (getpeername(0, peer, &slen))
 			peer = NULL;
-- 
1.4.0.g7883

^ permalink raw reply related

* Re: [PATCH] gitweb: Add title attribute with full first line of tag comment if it is needed
From: Junio C Hamano @ 2006-06-21 23:10 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <11509297422173-git-send-email-jnareb@gmail.com>

Jakub Narebski <jnareb@gmail.com> writes:

> For commits in oneline view (summary, shortlog, history) commit title
> (first line of commit message) is link to commit itself. If commit title
> (commit description) is shortened in output, hyperlink has title attribute
> with full title.

There are pure fixes and this "-title" enhancement intermixed.
Can we have fixes-only first?

> diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi
> index e044c61..8f8ae4a 100755
> --- a/gitweb/gitweb.cgi
> +++ b/gitweb/gitweb.cgi
> @@ -326,7 +326,7 @@ EOF
>  		} elsif (defined $hash) {
>  			$search_hash = $hash;
>  		} else {
> -			$search_hash  = "HEAD";
> +			$search_hash = "HEAD";
>  		}
>  		$cgi->param("a", "search");
>  		$cgi->param("h", $search_hash);

Is a fix.

> @@ -1107,7 +1107,8 @@ sub git_summary {
>  		foreach my $entry (@$taglist) {
>  			my %tag = %$entry;
>  			my $comment_lines = $tag{'comment'};
> -			my $comment = shift @$comment_lines;
> +			my $comment_long = shift @$comment_lines;
> +			my $comment = $comment_long;
>  			if (defined($comment)) {
>  				$comment = chop_str($comment, 30, 5);
>  			}

Is an enhancement.

> @@ -1119,13 +1120,17 @@ sub git_summary {
>  			$alternate ^= 1;
>  			if ($i-- > 0) {
>  				print "<td><i>$tag{'age'}</i></td>\n" .
> -				      "<td>" .
> +				      "<td>";
>  				      $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$tag{'reftype'};h=$tag{'refid'}"), -class => "list"},
>  				      "<b>" . esc_html($tag{'name'}) . "</b>") .
>  				      "</td>\n" .
>  				      "<td>";

Is a fix.  How could we have missed this?

>  				if (defined($comment)) {
> -				      print $cgi->a({-class => "list", -href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}")}, $comment);
> +					if (length($comment) < length($comment_long)) {
> +						print $cgi->a({-class => "list", -href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}"), -title => "$comment_long"}, $comment);
> +					} else {
> +						print $cgi->a({-class => "list", -href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}")}, $comment);
> +					}
>  				}
>  				print "</td>\n" .
>  				      "<td class=\"link\">";

Is an enhancement -- I suspect it is not worth to switch
depending on the length of $comment_long.  Does it clutter the
output too much if you did -title to everybody?

> @@ -1346,7 +1351,8 @@ sub git_tags {
>  		foreach my $entry (@$taglist) {
>  			my %tag = %$entry;
>  			my $comment_lines = $tag{'comment'};
> -			my $comment = shift @$comment_lines;
> +			my $comment_long = shift @$comment_lines;
> +			my $comment = $comment_long;
>  			if (defined($comment)) {
>  				$comment = chop_str($comment, 30, 5);
>  			}

Is an enhancement.  I think the matching hunk to fix the same
"$cgi->a() output concatenated as print argument" problem is
missing here.  And the next hunk the same comment as the one for
git_summary applies.

And as you say, git_summary and git_tags do look similar.  Maybe
we would want to refactor them first to clean things up before
piling up more features?

^ permalink raw reply

* [PATCH] gitweb: Add title attribute with full first line of tag comment if it is needed
From: Jakub Narebski @ 2006-06-21 22:42 UTC (permalink / raw)
  To: git; +Cc: Jakub Narebski

For commits in oneline view (summary, shortlog, history) commit title
(first line of commit message) is link to commit itself. If commit title
(commit description) is shortened in output, hyperlink has title attribute
with full title.

This commit does the same also for tags. It is much more rare to have long
tag description, though.

Misfeature: sometimes tag link has title attribute even if tag description
doesn't seem to be shortened.

Needs refactoring (twice done almost exactly the same, four times similar
code is used).

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

---

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

e41a09e140c1ecd933ae90e7b55660d67f33dc1b
diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi
index e044c61..8f8ae4a 100755
--- a/gitweb/gitweb.cgi
+++ b/gitweb/gitweb.cgi
@@ -326,7 +326,7 @@ EOF
 		} elsif (defined $hash) {
 			$search_hash = $hash;
 		} else {
-			$search_hash  = "HEAD";
+			$search_hash = "HEAD";
 		}
 		$cgi->param("a", "search");
 		$cgi->param("h", $search_hash);
@@ -1107,7 +1107,8 @@ sub git_summary {
 		foreach my $entry (@$taglist) {
 			my %tag = %$entry;
 			my $comment_lines = $tag{'comment'};
-			my $comment = shift @$comment_lines;
+			my $comment_long = shift @$comment_lines;
+			my $comment = $comment_long;
 			if (defined($comment)) {
 				$comment = chop_str($comment, 30, 5);
 			}
@@ -1119,13 +1120,17 @@ sub git_summary {
 			$alternate ^= 1;
 			if ($i-- > 0) {
 				print "<td><i>$tag{'age'}</i></td>\n" .
-				      "<td>" .
+				      "<td>";
 				      $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=$tag{'reftype'};h=$tag{'refid'}"), -class => "list"},
 				      "<b>" . esc_html($tag{'name'}) . "</b>") .
 				      "</td>\n" .
 				      "<td>";
 				if (defined($comment)) {
-				      print $cgi->a({-class => "list", -href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}")}, $comment);
+					if (length($comment) < length($comment_long)) {
+						print $cgi->a({-class => "list", -href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}"), -title => "$comment_long"}, $comment);
+					} else {
+						print $cgi->a({-class => "list", -href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}")}, $comment);
+					}
 				}
 				print "</td>\n" .
 				      "<td class=\"link\">";
@@ -1346,7 +1351,8 @@ sub git_tags {
 		foreach my $entry (@$taglist) {
 			my %tag = %$entry;
 			my $comment_lines = $tag{'comment'};
-			my $comment = shift @$comment_lines;
+			my $comment_long = shift @$comment_lines;
+			my $comment = $comment_long;
 			if (defined($comment)) {
 				$comment = chop_str($comment, 30, 5);
 			}
@@ -1363,7 +1369,11 @@ sub git_tags {
 			      "</td>\n" .
 			      "<td>";
 			if (defined($comment)) {
-			      print $cgi->a({-class => "list", -href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}")}, $comment);
+				if (length($comment) < length($comment_long)) {
+					print $cgi->a({-class => "list", -href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}"), -title => "$comment_long"}, $comment);
+				} else {
+					print $cgi->a({-class => "list", -href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}")}, $comment);
+				}
 			}
 			print "</td>\n" .
 			      "<td class=\"link\">";
-- 
1.3.0

^ permalink raw reply related

* Re: [PATCH] Check and document the options to prevent mistakes.
From: Junio C Hamano @ 2006-06-21 20:53 UTC (permalink / raw)
  To: Eric W. Biederman; +Cc: git
In-Reply-To: <m164iu8x78.fsf@ebiederm.dsl.xmission.com>

ebiederm@xmission.com (Eric W. Biederman) writes:

> +# Verify the user input
> +
> +foreach my $entry (@to) {
> +	die "Comma in --to entry: $entry'\n" unless $entry !~ m/,/;
> +}
> +

Perhaps, avoiding double negation would be easier on the eyes.

        die ... if $entry =~ /,/

Does it grok '"Biederman, Eric W." <eb@xm.com>' some people seem
to do properly, or do we care (I personally don't)?

^ permalink raw reply

* Re: [RFC] gitweb wishlist and TODO list
From: Josef Weidendorfer @ 2006-06-21 20:35 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <200606211838.50864.jnareb@gmail.com>

On Wednesday 21 June 2006 18:38, you wrote:
> Josef Weidendorfer wrote:
> > Let's see. A think a mixture between current history and log...
> > Currently, it looks like this
> > 
> >  http://git.kernel.org/git/?p=git/git.git;a=history;f=Documentation
> > 
> > gives you the history of subdirectory Documentation/ of git
> > (unfortunately only reachable via changing the URL...).
> > 
> > And it could look as attached (I did a little copy/paste of
> > HTML). I only modified 2 commits of the list...
> 
> It probably didn't get to mailing list (at least to archives) due 
> to having attachement.

Yes; the mailing list regarded as spam because of the attachment.

> I thought you wanted to enhance tree view,

That wasn't me ;-)

> e.g. adding to the view like in 
> 
>   http://git.kernel.org/git/?p=git/git.git;a=tree;f=Documentation
> 
> columns 'Changed by' or 'Author', 'Age' or 'Last changed', 'Commit' 
> (i.e. abbreviated sha1 id of a commit), and perhaps shortened commit
> message (short description of changes, a la shortlog but shorther).

Yes, sometimes this could be interesting. However, as said above,
I find myself often looking for date sorting with such views.

> In other words 'blame'/'annotate' for directory. Which would need new git
> command I think.

Hmmm... wouldn't "git-log --summary", and building up a map from files names
to commits be enough? You would probably need to parse the full history before
sending any output, so it is potentially heavy. 

> Adding filtered list of files modified by commit in log and history views 
> should be fairly easy...

Yes. If I get some time, I'll send a patch.

Josef

^ permalink raw reply

* Re: Odd behavior with git and cairo-devel repo
From: Junio C Hamano @ 2006-06-21 19:43 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Andre Noll, Art Haas, git
In-Reply-To: <Pine.LNX.4.64.0606211054500.5498@g5.osdl.org>

Linus Torvalds <torvalds@osdl.org> writes:

> Ouch. 

Ouch indeed ;-).

> Actually, the alternate patch is the one I had intended to do but for some 
> reasons didn't.
>
> This one also removes two more lines than it adds, but it's obviously a 
> bigger patch.

I'll take this, since I think keeping the hash population
(collision maintenance) code in one place like your version does
seems cleaner for me to read three months down the road.

Again, thanks Andre, Art and Linus.

^ permalink raw reply

* Re: Odd behavior with git and cairo-devel repo
From: Linus Torvalds @ 2006-06-21 18:01 UTC (permalink / raw)
  To: Andre Noll; +Cc: Art Haas, Junio C Hamano, git
In-Reply-To: <20060621174632.GP11245@skl-net.de>



On Wed, 21 Jun 2006, Andre Noll wrote:
>
> Fix grow_refs_hash()

Ouch. 

Actually, the alternate patch is the one I had intended to do but for some 
reasons didn't.

This one also removes two more lines than it adds, but it's obviously a 
bigger patch.

Junio, depending on which one you prefer, add the appropriate

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

(for Andre's one) or

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

if you take this one.

		Linus
---
 object-refs.c |   30 ++++++++++++++----------------
 1 files changed, 14 insertions(+), 16 deletions(-)

diff --git a/object-refs.c b/object-refs.c
index a7d49c6..b1b8065 100644
--- a/object-refs.c
+++ b/object-refs.c
@@ -12,6 +12,18 @@ static unsigned int hash_obj(struct obje
 	return hash % n;
 }
 
+static void insert_ref_hash(struct object_refs *ref, struct object_refs **hash, unsigned int size)
+{
+	int j = hash_obj(ref->base, size);
+
+	while (hash[j]) {
+		j++;
+		if (j >= size)
+			j = 0;
+	}
+	hash[j] = ref;
+}
+
 static void grow_refs_hash(void)
 {
 	int i;
@@ -20,30 +32,16 @@ static void grow_refs_hash(void)
 
 	new_hash = calloc(new_hash_size, sizeof(struct object_refs *));
 	for (i = 0; i < refs_hash_size; i++) {
-		int j;
 		struct object_refs *ref = refs_hash[i];
 		if (!ref)
 			continue;
-		j = hash_obj(ref->base, new_hash_size);
-		new_hash[j] = ref;
+		insert_ref_hash(ref, new_hash, new_hash_size);
 	}
 	free(refs_hash);
 	refs_hash = new_hash;
 	refs_hash_size = new_hash_size;
 }
 
-static void insert_ref_hash(struct object_refs *ref)
-{
-	int j = hash_obj(ref->base, refs_hash_size);
-
-	while (refs_hash[j]) {
-		j++;
-		if (j >= refs_hash_size)
-			j = 0;
-	}
-	refs_hash[j] = ref;
-}
-
 static void add_object_refs(struct object *obj, struct object_refs *ref)
 {
 	int nr = nr_object_refs + 1;
@@ -51,7 +49,7 @@ static void add_object_refs(struct objec
 	if (nr > refs_hash_size * 2 / 3)
 		grow_refs_hash();
 	ref->base = obj;
-	insert_ref_hash(ref);
+	insert_ref_hash(ref, refs_hash, refs_hash_size);
 	nr_object_refs = nr;
 }
 

^ permalink raw reply related

* Re: Odd behavior with git and cairo-devel repo
From: Andre Noll @ 2006-06-21 17:46 UTC (permalink / raw)
  To: Art Haas; +Cc: Junio C Hamano, git, Linus Torvalds
In-Reply-To: <20060621120618.GR2820@artsapartment.org>

On 07:06, Art Haas wrote:
> I see this patch has made it into git now, and it fixes the problem
> described above. Thanks!
> 
> However, I'm still seeing the problem where 'git prune' leaves the
> repo in an invalid state. In the case above, running 'git prune' on a
> freshly checked-out repo works without problems; when the repo has a
> number of unpacked objects, however, things go bad. On the FC4 machine
> I have, I updated my git repo, rebuilt, and installed the build with
> the patch above, then updated my cairo repo. The 'git pull' retrieved
> a handful of objects, and 'git fsck-objects' ran without problem.
> Then 'git prune' was run, seemingly without problem, and when I tried
> 'git repack -a -d' things went boom. A subsequent 'git fsck-object'
> run indicated the repo was missing tree and commit objects.
> 
> Is anyone else seeing a similar problem with 'git prune'?

Yeah. This is due to a thinko in grow_refs_hash() which was introduced in

	commit 3e4339e6f96e8c4f38a9c6607b98d3e96a2ed783
	Author: Linus Torvalds <torvalds@osdl.org>
	Date:   Sun Jun 18 11:45:02 2006 -0700

	    Remove "refs" field from "struct object"

Fix below.
---
Fix grow_refs_hash()

As the hash values depend on the hash size, they have to be
recalulated when growing the hash. It's possible (though unlikely)
that there are duplicates even with the new, larger hash size, so
make grow_refs_hash() check for duplicates.

Signed-off-by: Andre Noll <maan@systemlinux.org>
---
diff --git a/object-refs.c b/object-refs.c
index 8afa227..fa1d3c1 100644
--- a/object-refs.c
+++ b/object-refs.c
@@ -25,6 +25,8 @@ static void grow_refs_hash(void)
 		if (!ref)
 			continue;
 		j = hash_obj(ref->base, new_hash_size);
+		while (new_hash[j])
+			j = (j + 1) % new_hash_size;
 		new_hash[j] = ref;
 	}
 	free(refs_hash);
-- 
The only person who always got his work done by Friday was Robinson Crusoe

^ permalink raw reply related

* Re: [RFC] gitweb wishlist and TODO list
From: Jakub Narebski @ 2006-06-21 17:36 UTC (permalink / raw)
  To: git
In-Reply-To: <20060621164503.GA1285@h4x0r5.com>

Ryan Anderson wrote:

> On Wed, Jun 21, 2006 at 03:05:35PM +0200, Dennis Stosberg wrote:
>> (2) Setting %ENV has no effect on spawned processes under mod_perl,
>>     so the git commands would never find the project directories.
>>     My first thought was to set $GIT_DIR on the commands' command
>>     lines like in open($fh, '$GIT_DIR=blah git-rev-list ...') but it
>>     would lead to an extra shell being spawned on every invocation
>>     of a git command.
> 
> I haven't looked at gitweb much, but why can't you solve this by doing
> manual pipe,fork,exec combinations?  That should give you complete
> control over the environment, right?

In gitweb.cgi we now use magic open "-|" invocation, e.g.:

        open my $fd, "-|", "$gitbin/git-cat-file -t $hash" or return;

in git-rerere we still fork magically, but exec explicitely

        my $pid = open($in, '-|');
        die "$!" unless defined $pid;
        if (!$pid) {
                exec(qw(git ls-files -z -u)) or die "$!: ls-files";
        }

The same is done in git-annotate (via open_pipe sub which takes care of
ActiveState Perl implementation); git-archimport, git-cvsexportcommit 
(via safe_pipe_capture); git-send-email (without encapsulating in 
a subroutine; it also uses backticks)  

git-svn uses fork + redirecting output + exec and waitpid for quiet_run
subroutine and system call.

git-cvsimport uses system call, backticks, straight pipe open, i.e. using
"git-command |", and magic open "-|" like gitweb.cgi. git-cvsserver has
safe_pipe_capture, but sometimes uses backticks. git-fmt-merge-message uses
backticks only. git-mv uses backticks and pipe. git-svnimport uses system
call and pipe.

What a mess. We really need Git.pm module...


And to answer your question, AFAICT exec cannot modify environment, not like
execve (or execle wrapper). POE (POE::Wheel::Run) or IPC::Run modules
perhaps...

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply

* Re: [RFC] gitweb wishlist and TODO list
From: Ryan Anderson @ 2006-06-21 16:45 UTC (permalink / raw)
  To: Dennis Stosberg; +Cc: Martin Langhoff, Jakub Narebski, git
In-Reply-To: <20060621130535.G2b34d382@leonov.stosberg.net>

On Wed, Jun 21, 2006 at 03:05:35PM +0200, Dennis Stosberg wrote:
> (2) Setting %ENV has no effect on spawned processes under mod_perl,
>     so the git commands would never find the project directories.
>     My first thought was to set $GIT_DIR on the commands' command
>     lines like in open($fh, '$GIT_DIR=blah git-rev-list ...') but it
>     would lead to an extra shell being spawned on every invocation
>     of a git command.


I haven't looked at gitweb much, but why can't you solve this by doing
manual pipe,fork,exec combinations?  That should give you complete
control over the environment, right?

(IIRC, the last time I played with mod_perl and spawning processes, I
recall it doing something very confusing with the pipes I had open.)


-- 

Ryan Anderson
  sometimes Pug Majere

^ permalink raw reply

* Re: [RFC] gitweb wishlist and TODO list
From: Jakub Narebski @ 2006-06-21 16:38 UTC (permalink / raw)
  To: Josef Weidendorfer; +Cc: git
In-Reply-To: <200606211802.41071.Josef.Weidendorfer@gmx.de>

Josef Weidendorfer wrote:
> On Wednesday 21 June 2006 15:53, Jakub Narebski wrote:
>>> Yup, but when you are interested in the history of changes to files in
>>> a given directory, you also want to see the name of the changed files on
>>> the same page, and not have to click on every commit to get the file
>>> names. Besides, the "commit" view shows all changed files, and not only 
>>> the ones which are in the directory.
>> 
>> Could you please create a mockup how you imagine the page to look like
>> (in ascii-art)? At least list the columns...
> 
> Let's see. A think a mixture between current history and log...
> Currently, it looks like this
> 
>  http://git.kernel.org/git/?p=git/git.git;a=history;f=Documentation
> 
> gives you the history of subdirectory Documentation/ of git
> (unfortunately only reachable via changing the URL...).
> 
> And it could look as attached (I did a little copy/paste of
> HTML). I only modified 2 commits of the list...

It probably didn't get to mailing list (at least to archives) due 
to having attachement.

I thought you wanted to enhance tree view, e.g. adding to the view like in

  http://git.kernel.org/git/?p=git/git.git;a=tree;f=Documentation

columns 'Changed by' or 'Author', 'Age' or 'Last changed', 'Commit' 
(i.e. abbreviated sha1 id of a commit), and perhaps shortened commit
message (short description of changes, a la shortlog but shorther).
In other words 'blame'/'annotate' for directory. Which would need new git
command I think.

Adding filtered list of files modified by commit in log and history views 
should be fairly easy...
-- 
Jakub Narebski
Poland

^ permalink raw reply

* Re: packs and trees
From: David Lang @ 2006-06-21 15:32 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Martin Langhoff, Nicolas Pitre, Jon Smirl, git
In-Reply-To: <Pine.LNX.4.64.0606202046290.5498@g5.osdl.org>

there are performance penalties in some cases when you use directory hashing. I 
did some tests last year of lots of small files in a directory tree (X/X/X/XXX 
of 1k files) and I found that turning on directory hashing actually slowed down 
the creation of this tree from a tarball significantly (I also found that in 
this case the ext2 allocation strategy was significantly better then the ext3 
one), so test on your system.

David Lang


  On Tue, 20 Jun 2006, Linus Torvalds wrote:

> Date: Tue, 20 Jun 2006 20:54:01 -0700 (PDT)
> From: Linus Torvalds <torvalds@osdl.org>
> To: Martin Langhoff <martin.langhoff@gmail.com>
> Cc: Nicolas Pitre <nico@cam.org>, Jon Smirl <jonsmirl@gmail.com>,
>     git <git@vger.kernel.org>
> Subject: Re: packs and trees
> 
>
>
> On Wed, 21 Jun 2006, Martin Langhoff wrote:
>>
>> If you are asking about the ext3 performance problems, I think Linus
>> discussed that a while ago, why unpacked repos are slow (in addition
>> to huge), and there were some suggestions of using hashed directory
>> indexes.
>
> Yes. I think most distros still default to nonhashed directories, but for
> any large-directory case you really want to turn on hashing.
>
> I forget the exact details, it's somethng like
>
> 	tune2fs -O dir_index
>
> or something to turn it on (if I remember correctly, that will only affect
> any directories then created after that, but you can effect that by just
> doing a "git repack -a -d" which will remove all old object directories,
> and now subsequent directories will be done with indexing on).
>
> Personally, I just ended up using packs extensively, so I think I'm still
> running without indexing on all my machines ;)
>
> 		Linus
> -
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply

* [PATCH] gitweb: Make use of $PATH_INFO for project parameter
From: Jakub Narebski @ 2006-06-21 15:06 UTC (permalink / raw)
  To: git; +Cc: Jakub Narebski
In-Reply-To: <11509012742493-git-send-email-jnareb@gmail.com>

Allow to have project name in the path part of URL, just after the name of
script. For example instead of gitweb.cgi?p=git.git you can write
gitweb.cgi/git.git or gitweb.cgi/git.git/

Not used in URLs inside gitweb; it means that the above alternate syntax
must be generated by hand, at least for now.

Side effect: project name parameter is now stripped of leading and
trailing slash before validation.

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

---
This is final, correct version of the patch.

 gitweb/gitweb.cgi |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

b9df055ae8d3aafe03744537026823dbaf7342ba
diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi
index e044c61..e2108de 100755
--- a/gitweb/gitweb.cgi
+++ b/gitweb/gitweb.cgi
@@ -86,8 +86,9 @@ if (defined $order) {
 	}
 }
 
-my $project = $cgi->param('p');
+my $project = ($cgi->param('p') || $ENV{'PATH_INFO'});
 if (defined $project) {
+	$project =~ s|^/||; $project =~ s|/$||;
 	$project = validate_input($project);
 	if (!defined($project)) {
 		die_error(undef, "Invalid project parameter.");
-- 
1.3.0

^ permalink raw reply related

* [PATCH (amend)] gitweb: Make use of $PATH_INFO for project parameter
From: Jakub Narebski @ 2006-06-21 15:03 UTC (permalink / raw)
  To: git; +Cc: Jakub Narebski
In-Reply-To: <11509012742493-git-send-email-jnareb@gmail.com>

Allow to have project name in the path part of URL, just after the name of
script. For example instead of gitweb.cgi?p=git.git you can write
gitweb.cgi/git.git or gitweb.cgi/git.git/

Not used in URLs inside gitweb; it means that the above alternate syntax
must be generated by hand, at least for now.

Side effect: project name parameter is now stripped of leading and
trailing slash before validation.

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

---

 gitweb/gitweb.cgi |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

63ffc79283d23aeedbdc259e3b069f1e97498e09
diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi
index e044c61..91698df 100755
--- a/gitweb/gitweb.cgi
+++ b/gitweb/gitweb.cgi
@@ -86,7 +86,8 @@ if (defined $order) {
 	}
 }
 
-my $project = $cgi->param('p');
+my $project = ($cgi->param('p') || $ENV{'PATH_INFO'});
+$project =~ s|^/||; $project =~ s|/$||;
 if (defined $project) {
 	$project = validate_input($project);
 	if (!defined($project)) {
-- 
1.3.0

^ permalink raw reply related

* Re: [RFC] gitweb wishlist and TODO list
From: Jakub Narebski @ 2006-06-21 14:52 UTC (permalink / raw)
  To: git
In-Reply-To: <20060620175505.GR2609@pasky.or.cz>

Petr Baudis wrote:

> Nope, you get the stuff in $PATH_INFO. And having at least just the
> project name in the path part would be quite nice, it's my common gripe
> with cvsweb as I frequently get to mangle with the query part manually
> (can be much faster than clicking around) and I have to carefully evade
> the project name part, which is something I would really expect to be in
> the "static" part of the URL.

What about the patch I just sent:  "[PATCH] gitweb: Make use of $PATH_INFO
for project parameter" (<11509012742493-git-send-email-jnareb@gmail.com>)?

It doesn't as of yet make use of that.

I wonder if this solution would work for mod_perl, or one would need some
Apache-specific package...

P.S. I meant to sent the patch as reply to this mail. Oops.
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply

* [PATCH] gitweb: Make use of $PATH_INFO for project parameter
From: Jakub Narebski @ 2006-06-21 14:47 UTC (permalink / raw)
  To: git; +Cc: Jakub Narebski

Allow to have project name in the path part of URL, just after the name of
script. For example instead of gitweb.cgi?p=git.git you can write
gitweb.cgi/git.git or gitweb.cgi/git.git/

Not used in URLs inside gitweb; it means that the above alternate syntax
must be generated by hand, at least for now.

Side effect: project name parameter is now stripped of leading and
trailing slash before validation.

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

---

 gitweb/gitweb.cgi |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

51faac72f83777ced3d9d3544cc6d47431d1b8ee
diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi
index e044c61..91698df 100755
--- a/gitweb/gitweb.cgi
+++ b/gitweb/gitweb.cgi
@@ -86,7 +86,8 @@ if (defined $order) {
 	}
 }
 
-my $project = $cgi->param('p');
+my $project = ($cgi->param('p') || $ENV{'PATH_INFO'});
+$project =~ s|^/||; $project =~ s|/$||;
 if (defined $project) {
 	$project = validate_input($project);
 	if (!defined($project)) {
-- 
1.3.0

^ permalink raw reply related

* Re: [RFC] gitweb wishlist and TODO list
From: Jakub Narebski @ 2006-06-21 13:53 UTC (permalink / raw)
  To: git
In-Reply-To: <200606211157.23809.Josef.Weidendorfer@gmx.de>

Josef Weidendorfer wrote:

> On Wednesday 21 June 2006 11:15, Jakub Narebski wrote:
>> Josef Weidendorfer wrote:
>> 
>>> It would be nice to have a list of the files in the directory
>>> touched by the given commits.
>> 
>> 'commit' view gives at the bottom list of all files affected by given
>> commit.
> 
> Yup, but when you are interested in the history of changes to files in
> a given directory, you also want to see the name of the changed files on
> the same page, and not have to click on every commit to get the file
> names. Besides, the "commit" view shows all changed files, and not only 
> the ones which are in the directory.

Could you please create a mockup how you imagine the page to look like
(in ascii-art)? At least list the columns...

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply

* Re: [PATCH 3/3] gitweb: Use --git-dir parameter instead of setting $ENV{'GIT_DIR'}
From: Jakub Narebski @ 2006-06-21 13:42 UTC (permalink / raw)
  To: git
In-Reply-To: <20060621163302.47271f89.tihirvon@gmail.com>

Timo Hirvonen wrote:

> Dennis Stosberg <dennis@stosberg.net> wrote:
> 
>> -    open my $fd, "-|", "$gitbin/git-cat-file -t $hash" or return;
>> +    open my $fd, "-|", "$gitbin/git --git-dir=$git_dir cat-file -t $hash" or return;
> 
> How about adding a function to simplify calling the git commands?
> 
> Something like git("cat-file -t $hash") which would return
> "$gitbin/git --git-dir=$git_dir cat-file -t $hash" string.

Or rather add a function(s) to call git commands, either returning git command
output, or filehandle to read from, e.g.

  my $fd = git_open("cat-file", "-t $hash") or return; 

i.e. each parameter separately, just in case.

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply

* Re: [PATCH 3/3] gitweb: Use --git-dir parameter instead of setting $ENV{'GIT_DIR'}
From: Timo Hirvonen @ 2006-06-21 13:33 UTC (permalink / raw)
  To: Dennis Stosberg; +Cc: martin.langhoff, jnareb, git
In-Reply-To: <20060621130930.G421234bb@leonov.stosberg.net>

Dennis Stosberg <dennis@stosberg.net> wrote:

> -	open my $fd, "-|", "$gitbin/git-cat-file -t $hash" or return;
> +	open my $fd, "-|", "$gitbin/git --git-dir=$git_dir cat-file -t $hash" or return;

How about adding a function to simplify calling the git commands?

Something like git("cat-file -t $hash") which would return
"$gitbin/git --git-dir=$git_dir cat-file -t $hash" string.

I'm not Perl programmer so I don't know what would be the best way to
do this.

-- 
http://onion.dynserv.net/~timo/

^ permalink raw reply

* Re: [RFC] gitweb wishlist and TODO list
From: Jakub Narebski @ 2006-06-21 13:30 UTC (permalink / raw)
  To: git
In-Reply-To: <20060621130535.G2b34d382@leonov.stosberg.net>

Dennis Stosberg wrote:

> (2) Setting %ENV has no effect on spawned processes under mod_perl,
>     so the git commands would never find the project directories.
>     My first thought was to set $GIT_DIR on the commands' command
>     lines like in open($fh, '$GIT_DIR=blah git-rev-list ...') but it
>     would lead to an extra shell being spawned on every invocation
>     of a git command.
> 
>     So I added the possibility to set/override the path to the
>     repository with a command line parameter.  For simplicity I
>     handled that parameter in git.c.  The drawbacks are that it has
>     to be given before the command name and that it won't work when
>     commands are invoked as "git-command".

So now you have extra git redirector being spawned, instead of extra shell
being spawned. I wonder if using 'env' wouldn't be simplier, and how
portable 'env' is.

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply

* [PATCH] Check and document the options to prevent mistakes.
From: Eric W. Biederman @ 2006-06-21 13:17 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git


When multiple recipients are given to git-send-email on the same
--cc line the code does not properly handle it.

Full and proper parsing of the email addresses so I can detect
which commas mean a new email address is more than I care to implement.

In particular this email address: "bibo,mao" <bibo.mao@intel.com>
must not be treated as two email addresses.

So this patch simply treats all commas in recipient lists as
an error and fails if one is given.

At the same time it documents that git-send-email wants multiple
instances of --cc specified on the command line if you want to
cc multiple recipients.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>

---

 Documentation/git-send-email.txt |    9 +++++++++
 git-send-email.perl              |   14 ++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt
index ad1b9cf..481b3f5 100644
--- a/Documentation/git-send-email.txt
+++ b/Documentation/git-send-email.txt
@@ -24,9 +24,16 @@ OPTIONS
 -------
 The options available are:
 
+--bcc::
+	Specify a "Bcc:" value for each email.
+
+	The --bcc option must be repeated for each user you want on the bcc list.
+
 --cc::
 	Specify a starting "Cc:" value for each email.
 
+	The --cc option must be repeated for each user you want on the cc list.
+
 --chain-reply-to, --no-chain-reply-to::
 	If this is set, each email will be sent as a reply to the previous
 	email sent.  If disabled with "--no-chain-reply-to", all emails after
@@ -76,6 +83,8 @@ The options available are:
 	Generally, this will be the upstream maintainer of the
 	project involved.
 
+	The --to option must be repeated for each user you want on the to list.
+
 
 Author
 ------
diff --git a/git-send-email.perl b/git-send-email.perl
index 7b1cca7..c5d9e73 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -65,6 +65,20 @@ my $rc = GetOptions("from=s" => \$from,
 		    "no-signed-off-cc|no-signed-off-by-cc" => \$no_signed_off_cc,
 	 );
 
+# Verify the user input
+
+foreach my $entry (@to) {
+	die "Comma in --to entry: $entry'\n" unless $entry !~ m/,/;
+}
+
+foreach my $entry (@initial_cc) {
+	die "Comma in --cc entry: $entry'\n" unless $entry !~ m/,/;
+}
+
+foreach my $entry (@bcclist) {
+	die "Comma in --bcclist entry: $entry'\n" unless $entry !~ m/,/;
+}
+
 # Now, let's fill any that aren't set in with defaults:
 
 sub gitvar {

^ permalink raw reply related

* [PATCH 3/3] gitweb: Use --git-dir parameter instead of setting $ENV{'GIT_DIR'}
From: Dennis Stosberg @ 2006-06-21 13:09 UTC (permalink / raw)
  To: Martin Langhoff; +Cc: Jakub Narebski, git
In-Reply-To: <20060621130535.G2b34d382@leonov.stosberg.net>

---
 gitweb/gitweb.cgi |   67 +++++++++++++++++++++++++++--------------------------
 1 files changed, 34 insertions(+), 33 deletions(-)

diff --git a/gitweb/gitweb.cgi b/gitweb/gitweb.cgi
index 8f19fdb..57ac3a3 100755
--- a/gitweb/gitweb.cgi
+++ b/gitweb/gitweb.cgi
@@ -61,6 +61,9 @@ # file to use for guessing MIME types be
 # (relative to the current git repository)
 our $mimetypes_file = undef;
 
+# path to the project's repository
+our $git_dir = undef;
+
 # input validation and dispatch
 our $action = $cgi->param('a');
 if (defined $action) {
@@ -101,7 +104,7 @@ if (defined $project) {
 	}
 	$rss_link = "<link rel=\"alternate\" title=\"" . esc_param($project) . " log\" href=\"" .
 		    "$my_uri?" . esc_param("p=$project;a=rss") . "\" type=\"application/rss+xml\"/>";
-	$ENV{'GIT_DIR'} = "$projectroot/$project";
+	$git_dir = "$projectroot/$project";
 } else {
 	git_project_list();
 	exit;
@@ -372,7 +375,7 @@ sub die_error {
 sub git_get_type {
 	my $hash = shift;
 
-	open my $fd, "-|", "$gitbin/git-cat-file -t $hash" or return;
+	open my $fd, "-|", "$gitbin/git --git-dir=$git_dir cat-file -t $hash" or return;
 	my $type = <$fd>;
 	close $fd or return;
 	chomp $type;
@@ -381,19 +384,15 @@ sub git_get_type {
 
 sub git_read_head {
 	my $project = shift;
-	my $oENV = $ENV{'GIT_DIR'};
 	my $retval = undef;
-	$ENV{'GIT_DIR'} = "$projectroot/$project";
-	if (open my $fd, "-|", "$gitbin/git-rev-parse", "--verify", "HEAD") {
+
+	if (open my $fd, "-|", "$gitbin/git", "--git-dir=$projectroot/$project", "rev-parse", "--verify", "HEAD") {
 		my $head = <$fd>;
 		close $fd;
 		if (defined $head && $head =~ /^([0-9a-fA-F]{40})$/) {
 			$retval = $1;
 		}
 	}
-	if (defined $oENV) {
-		$ENV{'GIT_DIR'} = $oENV;
-	}
 	return $retval;
 }
 
@@ -424,7 +423,7 @@ sub git_read_tag {
 	my %tag;
 	my @comment;
 
-	open my $fd, "-|", "$gitbin/git-cat-file tag $tag_id" or return;
+	open my $fd, "-|", "$gitbin/git --git-dir=$git_dir cat-file tag $tag_id" or return;
 	$tag{'id'} = $tag_id;
 	while (my $line = <$fd>) {
 		chomp $line;
@@ -496,7 +495,7 @@ sub git_read_commit {
 		@commit_lines = @$commit_text;
 	} else {
 		$/ = "\0";
-		open my $fd, "-|", "$gitbin/git-rev-list --header --parents --max-count=1 $commit_id" or return;
+		open my $fd, "-|", "$gitbin/git  --git-dir=$git_dir rev-list --header --parents --max-count=1 $commit_id" or return;
 		@commit_lines = split '\n', <$fd>;
 		close $fd or return;
 		$/ = "\n";
@@ -594,7 +593,7 @@ sub git_diff_print {
 	if (defined $from) {
 		$from_tmp = "$git_temp/gitweb_" . $$ . "_from";
 		open my $fd2, "> $from_tmp";
-		open my $fd, "-|", "$gitbin/git-cat-file blob $from";
+		open my $fd, "-|", "$gitbin/git --git-dir=$git_dir cat-file blob $from";
 		my @file = <$fd>;
 		print $fd2 @file;
 		close $fd2;
@@ -605,7 +604,7 @@ sub git_diff_print {
 	if (defined $to) {
 		$to_tmp = "$git_temp/gitweb_" . $$ . "_to";
 		open my $fd2, "> $to_tmp";
-		open my $fd, "-|", "$gitbin/git-cat-file blob $to";
+		open my $fd, "-|", "$gitbin/git --git-dir=$git_dir cat-file blob $to";
 		my @file = <$fd>;
 		print $fd2 @file;
 		close $fd2;
@@ -844,10 +843,12 @@ sub git_project_list {
 	}
 	foreach my $pr (@list) {
 		my $head = git_read_head($pr->{'path'});
+		print STDERR $head;
+
 		if (!defined $head) {
 			next;
 		}
-		$ENV{'GIT_DIR'} = "$projectroot/$pr->{'path'}";
+		$git_dir = "$projectroot/$pr->{'path'}";
 		my %co = git_read_commit($head);
 		if (!%co) {
 			next;
@@ -1046,7 +1047,7 @@ sub git_summary {
 	      "<tr><td>owner</td><td>$owner</td></tr>\n" .
 	      "<tr><td>last change</td><td>$cd{'rfc2822'}</td></tr>\n" .
 	      "</table>\n";
-	open my $fd, "-|", "$gitbin/git-rev-list --max-count=17 " . git_read_head($project) or die_error(undef, "Open failed.");
+	open my $fd, "-|", "$gitbin/git --git-dir=$git_dir rev-list --max-count=17 " . git_read_head($project) or die_error(undef, "Open failed.");
 	my (@revlist) = map { chomp; $_ } <$fd>;
 	close $fd;
 	print "<div>\n" .
@@ -1224,7 +1225,7 @@ sub git_tag {
 
 sub git_blame {
 	my $fd;
-	die_error('403 Permission denied', "Permission denied.") if (!git_get_project_config_bool ('blame'));
+	#die_error('403 Permission denied', "Permission denied.") if (!git_get_project_config_bool ('blame'));
 	die_error('404 Not Found', "What file will it be, master?") if (!$file_name);
 	$hash_base ||= git_read_head($project);
 	die_error(undef, "Reading commit failed.") unless ($hash_base);
@@ -1234,7 +1235,7 @@ sub git_blame {
 		$hash = git_get_hash_by_path($hash_base, $file_name, "blob")
 			or die_error(undef, "Error lookup file.");
 	}
-	open ($fd, "-|", "$gitbin/git-annotate", '-l', '-t', '-r', $file_name, $hash_base)
+	open ($fd, "-|", "$gitbin/git", "--git-dir=$git_dir", "annotate", '-l', '-t', '-r', $file_name, $hash_base)
 		or die_error(undef, "Open failed.");
 	git_header_html();
 	print "<div class=\"page_nav\">\n" .
@@ -1429,7 +1430,7 @@ sub git_get_hash_by_path {
 	my $tree = $base;
 	my @parts = split '/', $path;
 	while (my $part = shift @parts) {
-		open my $fd, "-|", "$gitbin/git-ls-tree $tree" or die_error(undef, "Open git-ls-tree failed.");
+		open my $fd, "-|", "$gitbin/git --git-dir=$git_dir ls-tree $tree" or die_error(undef, "Open git-ls-tree failed.");
 		my (@entries) = map { chomp; $_ } <$fd>;
 		close $fd or return undef;
 		foreach my $line (@entries) {
@@ -1457,8 +1458,8 @@ sub git_blob {
 		my $base = $hash_base || git_read_head($project);
 		$hash = git_get_hash_by_path($base, $file_name, "blob") || die_error(undef, "Error lookup file.");
 	}
-	my $have_blame = git_get_project_config_bool ('blame');
-	open my $fd, "-|", "$gitbin/git-cat-file blob $hash" or die_error(undef, "Open failed.");
+	my $have_blame = 1; #git_get_project_config_bool ('blame');
+	open my $fd, "-|", "$gitbin/git --git-dir=$git_dir cat-file blob $hash" or die_error(undef, "Open failed.");
 	git_header_html();
 	if (defined $hash_base && (my %co = git_read_commit($hash_base))) {
 		print "<div class=\"page_nav\">\n" .
@@ -1570,7 +1571,7 @@ sub git_blob_plain_mimetype {
 }
 
 sub git_blob_plain {
-	open my $fd, "-|", "$gitbin/git-cat-file blob $hash" or return;
+	open my $fd, "-|", "$gitbin/git --git-dir=$git_dir cat-file blob $hash" or return;
 	my $type = git_blob_plain_mimetype($fd, $file_name);
 
 	# save as filename, even when no $file_name is given
@@ -1602,7 +1603,7 @@ sub git_tree {
 		}
 	}
 	$/ = "\0";
-	open my $fd, "-|", "$gitbin/git-ls-tree -z $hash" or die_error(undef, "Open git-ls-tree failed.");
+	open my $fd, "-|", "$gitbin/git --git-dir=$git_dir ls-tree -z $hash" or die_error(undef, "Open git-ls-tree failed.");
 	chomp (my (@entries) = <$fd>);
 	close $fd or die_error(undef, "Reading tree failed.");
 	$/ = "\n";
@@ -1683,7 +1684,7 @@ #			      " | " . $cgi->a({-href => "$my
 
 sub git_rss {
 	# http://www.notestips.com/80256B3A007F2692/1/NAMO5P9UPQ
-	open my $fd, "-|", "$gitbin/git-rev-list --max-count=150 " . git_read_head($project) or die_error(undef, "Open failed.");
+	open my $fd, "-|", "$gitbin/git --git-dir=$git_dir rev-list --max-count=150 " . git_read_head($project) or die_error(undef, "Open 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');
@@ -1703,7 +1704,7 @@ sub git_rss {
 			last;
 		}
 		my %cd = date_str($co{'committer_epoch'});
-		open $fd, "-|", "$gitbin/git-diff-tree -r $co{'parent'} $co{'id'}" or next;
+		open $fd, "-|", "$gitbin/git --git-dir=$git_dir diff-tree -r $co{'parent'} $co{'id'}" or next;
 		my @difftree = map { chomp; $_ } <$fd>;
 		close $fd or next;
 		print "<item>\n" .
@@ -1756,7 +1757,7 @@ sub git_opml {
 		if (!defined $head) {
 			next;
 		}
-		$ENV{'GIT_DIR'} = "$projectroot/$proj{'path'}";
+		$git_dir = "$projectroot/$proj{'path'}";
 		my %co = git_read_commit($head);
 		if (!%co) {
 			next;
@@ -1791,7 +1792,7 @@ sub git_log {
 	      " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$hash;hb=$hash")}, "tree") . "<br/>\n";
 
 	my $limit = sprintf("--max-count=%i", (100 * ($page+1)));
-	open my $fd, "-|", "$gitbin/git-rev-list $limit $hash" or die_error(undef, "Open failed.");
+	open my $fd, "-|", "$gitbin/git --git-dir=$git_dir rev-list $limit $hash" or die_error(undef, "Open failed.");
 	my (@revlist) = map { chomp; $_ } <$fd>;
 	close $fd;
 
@@ -1882,7 +1883,7 @@ sub git_commit {
 		$root = " --root";
 		$parent = "";
 	}
-	open my $fd, "-|", "$gitbin/git-diff-tree -r -M $root $parent $hash" or die_error(undef, "Open failed.");
+	open my $fd, "-|", "$gitbin/git --git-dir=$git_dir diff-tree -r -M $root $parent $hash" or die_error(undef, "Open failed.");
 	@difftree = map { chomp; $_ } <$fd>;
 	close $fd or die_error(undef, "Reading diff-tree failed.");
 
@@ -2124,7 +2125,7 @@ sub git_commitdiff {
 	if (!defined $hash_parent) {
 		$hash_parent = $co{'parent'};
 	}
-	open my $fd, "-|", "$gitbin/git-diff-tree -r $hash_parent $hash" or die_error(undef, "Open failed.");
+	open my $fd, "-|", "$gitbin/git --git-dir=$git_dir diff-tree -r $hash_parent $hash" or die_error(undef, "Open failed.");
 	my (@difftree) = map { chomp; $_ } <$fd>;
 	close $fd or die_error(undef, "Reading diff-tree failed.");
 
@@ -2214,14 +2215,14 @@ sub git_commitdiff {
 
 sub git_commitdiff_plain {
 	mkdir($git_temp, 0700);
-	open my $fd, "-|", "$gitbin/git-diff-tree -r $hash_parent $hash" or die_error(undef, "Open failed.");
+	open my $fd, "-|", "$gitbin/git --git-dir=$git_dir diff-tree -r $hash_parent $hash" or die_error(undef, "Open failed.");
 	my (@difftree) = map { chomp; $_ } <$fd>;
 	close $fd or die_error(undef, "Reading diff-tree failed.");
 
 	# try to figure out the next tag after this commit
 	my $tagname;
 	my $refs = read_info_ref("tags");
-	open $fd, "-|", "$gitbin/git-rev-list HEAD";
+	open $fd, "-|", "$gitbin/git --git-dir=$git_dir rev-list HEAD";
 	chomp (my (@commits) = <$fd>);
 	close $fd;
 	foreach my $commit (@commits) {
@@ -2291,7 +2292,7 @@ sub git_history {
 	      "</div>\n";
 	print "<div class=\"page_path\"><b>/" . esc_html($file_name) . "</b><br/></div>\n";
 
-	open my $fd, "-|", "$gitbin/git-rev-list $hash | $gitbin/git-diff-tree -r --stdin -- \'$file_name\'";
+	open my $fd, "-|", "$gitbin/git --git-dir=$git_dir rev-list $hash | $gitbin/git --git-dir=$git_dir diff-tree -r --stdin -- \'$file_name\'";
 	my $commit;
 	print "<table cellspacing=\"0\">\n";
 	my $alternate = 0;
@@ -2383,7 +2384,7 @@ sub git_search {
 	my $alternate = 0;
 	if ($commit_search) {
 		$/ = "\0";
-		open my $fd, "-|", "$gitbin/git-rev-list --header --parents $hash" or next;
+		open my $fd, "-|", "$gitbin/git --git-dir=$git_dir rev-list --header --parents $hash" or next;
 		while (my $commit_text = <$fd>) {
 			if (!grep m/$searchtext/i, $commit_text) {
 				next;
@@ -2433,7 +2434,7 @@ sub git_search {
 
 	if ($pickaxe_search) {
 		$/ = "\n";
-		open my $fd, "-|", "$gitbin/git-rev-list $hash | $gitbin/git-diff-tree -r --stdin -S\'$searchtext\'";
+		open my $fd, "-|", "$gitbin/git --git-dir=$git_dir rev-list $hash | $gitbin/git --git-dir=$git_dir diff-tree -r --stdin -S\'$searchtext\'";
 		undef %co;
 		my @files;
 		while (my $line = <$fd>) {
@@ -2504,7 +2505,7 @@ sub git_shortlog {
 	      " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$hash;hb=$hash")}, "tree") . "<br/>\n";
 
 	my $limit = sprintf("--max-count=%i", (100 * ($page+1)));
-	open my $fd, "-|", "$gitbin/git-rev-list $limit $hash" or die_error(undef, "Open failed.");
+	open my $fd, "-|", "$gitbin/git --git-dir=$git_dir rev-list $limit $hash" or die_error(undef, "Open failed.");
 	my (@revlist) = map { chomp; $_ } <$fd>;
 	close $fd;
 
-- 
1.4.0

^ permalink raw reply related

* [PATCH 2/3] Add a parameter to specify the repository path
From: Dennis Stosberg @ 2006-06-21 13:08 UTC (permalink / raw)
  To: Martin Langhoff; +Cc: Jakub Narebski, git
In-Reply-To: <20060621130535.G2b34d382@leonov.stosberg.net>

---
 builtin-help.c |    2 +-
 git.c          |    6 ++++++
 2 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/builtin-help.c b/builtin-help.c
index 7470faa..db233eb 100644
--- a/builtin-help.c
+++ b/builtin-help.c
@@ -10,7 +10,7 @@ #include "exec_cmd.h"
 #include "common-cmds.h"
 
 static const char git_usage[] =
-	"Usage: git [--version] [--exec-path[=GIT_EXEC_PATH]] [--help] COMMAND [ ARGS ]";
+	"Usage: git [--version] [--exec-path[=GIT_EXEC_PATH]] [--git-dir=GIT_DIR] [--help] COMMAND [ ARGS ]";
 
 /* most gui terms set COLUMNS (although some don't export it) */
 static int term_columns(void)
diff --git a/git.c b/git.c
index 94e9a4a..d49f626 100644
--- a/git.c
+++ b/git.c
@@ -277,6 +277,12 @@ int main(int argc, const char **argv, ch
 			puts(git_exec_path());
 			exit(0);
 		}
+
+		if (!strncmp(cmd, "git-dir=", 8)) {
+			setenv("GIT_DIR", cmd + 8, 1);
+			continue;
+		}
+
 		cmd_usage(0, NULL, NULL);
 	}
 	argv[0] = cmd;
-- 
1.4.0

^ 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