Git development
 help / color / mirror / Atom feed
* [PATCH] gitweb: Add support for grep searches
From: Petr Baudis @ 2007-05-17  2:31 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

The 'grep' type of search greps the currently selected tree for given
regexp and shows the results in a fancy table with links into blob view.
The number of shown matches is limited to 1000 and the whole feature
can be turned off (grepping linux-2.6.git already makes repo.or.cz a bit
unhappy).

This second revision makes it in documentation explicit that grep accepts
regexps, and makes grep accept extended regexps instead of basic regexps.

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

 gitweb/gitweb.css  |    4 ++
 gitweb/gitweb.perl |  123 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 125 insertions(+), 2 deletions(-)

diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css
index 02623cb..9f0822f 100644
--- a/gitweb/gitweb.css
+++ b/gitweb/gitweb.css
@@ -484,3 +484,7 @@ span.atnight {
 span.match {
 	color: #e00000;
 }
+
+div.binary {
+	font-style: italic;
+}
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 549e027..f37fa0c 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -146,6 +146,19 @@ our %feature = (
 		'override' => 0,
 		'default' => [1]},
 
+	# Enable grep search, which will list the files in currently selected
+	# tree containing the given string. Enabled by default. This can be
+	# potentially CPU-intensive, of course.
+
+	# To enable system wide have in $GITWEB_CONFIG
+	# $feature{'grep'}{'default'} = [1];
+	# To have project specific config enable override in $GITWEB_CONFIG
+	# $feature{'grep'}{'override'} = 1;
+	# and in project config gitweb.grep = 0|1;
+	'grep' => {
+		'override' => 0,
+		'default' => [1]},
+
 	# Enable the pickaxe search, which will list the commits that modified
 	# a given string in a file. This can be practical and quite faster
 	# alternative to 'blame', but still potentially CPU-intensive.
@@ -245,6 +258,18 @@ sub gitweb_have_snapshot {
 	return $have_snapshot;
 }
 
+sub feature_grep {
+	my ($val) = git_get_project_config('grep', '--bool');
+
+	if ($val eq 'true') {
+		return (1);
+	} elsif ($val eq 'false') {
+		return (0);
+	}
+
+	return ($_[0]);
+}
+
 sub feature_pickaxe {
 	my ($val) = git_get_project_config('pickaxe', '--bool');
 
@@ -364,10 +389,17 @@ if (defined $page) {
 	}
 }
 
+our $searchtype = $cgi->param('st');
+if (defined $searchtype) {
+	if ($searchtype =~ m/[^a-z]/) {
+		die_error(undef, "Invalid searchtype parameter");
+	}
+}
+
 our $searchtext = $cgi->param('s');
 our $search_regexp;
 if (defined $searchtext) {
-	if ($searchtext =~ m/[^a-zA-Z0-9_\.\/\-\+\:\@ ]/) {
+	if ($searchtype ne 'grep' and $searchtext =~ m/[^a-zA-Z0-9_\.\/\-\+\:\@ ]/) {
 		die_error(undef, "Invalid search parameter");
 	}
 	if (length($searchtext) < 2) {
@@ -1923,7 +1955,7 @@ EOF
 		      $cgi->hidden(-name => "a") . "\n" .
 		      $cgi->hidden(-name => "h") . "\n" .
 		      $cgi->popup_menu(-name => 'st', -default => 'commit',
-		                       -values => ['commit', 'author', 'committer', 'pickaxe']) .
+		                       -values => ['commit', 'grep', 'author', 'committer', 'pickaxe']) .
 		      $cgi->sup($cgi->a({-href => href(action=>"search_help")}, "?")) .
 		      " search:\n",
 		      $cgi->textfield(-name => "s", -value => $searchtext) . "\n" .
@@ -4615,6 +4647,12 @@ sub git_search {
 			die_error('403 Permission denied', "Permission denied");
 		}
 	}
+	if ($searchtype eq 'grep') {
+		my ($have_grep) = gitweb_check_feature('grep');
+		if (!$have_grep) {
+			die_error('403 Permission denied', "Permission denied");
+		}
+	}
 
 	git_header_html();
 
@@ -4731,6 +4769,73 @@ sub git_search {
 
 		print "</table>\n";
 	}
+
+	if ($searchtype eq 'grep') {
+		git_print_page_nav('','', $hash,$co{'tree'},$hash);
+		git_print_header_div('commit', esc_html($co{'title'}), $hash);
+
+		print "<table cellspacing=\"0\">\n";
+		my $alternate = 1;
+		my $matches = 0;
+		$/ = "\n";
+		open my $fd, "-|", git_cmd(), 'grep', '-n', '-i', '-E', $searchtext, $co{'tree'};
+		my $lastfile = '';
+		while (my $line = <$fd>) {
+			chomp $line;
+			my ($file, $lno, $ltext, $binary);
+			last if ($matches++ > 1000);
+			if ($line =~ /^Binary file (.+) matches$/) {
+				$file = $1;
+				$binary = 1;
+			} else {
+				(undef, $file, $lno, $ltext) = split(/:/, $line, 4);
+			}
+			if ($file ne $lastfile) {
+				$lastfile and print "</td></tr>\n";
+				if ($alternate++) {
+					print "<tr class=\"dark\">\n";
+				} else {
+					print "<tr class=\"light\">\n";
+				}
+				print "<td class=\"list\">".
+					$cgi->a({-href => href(action=>"blob", hash=>$co{'hash'},
+							       file_name=>"$file"),
+						-class => "list"}, esc_path($file));
+				print "</td><td>\n";
+				$lastfile = $file;
+			}
+			if ($binary) {
+				print "<div class=\"binary\">Binary file</div>\n";
+			} else {
+				$ltext = untabify($ltext);
+				if ($ltext =~ m/^(.*)($searchtext)(.*)$/i) {
+					$ltext = esc_html($1, -nbsp=>1);
+					$ltext .= '<span class="match">';
+					$ltext .= esc_html($2, -nbsp=>1);
+					$ltext .= '</span>';
+					$ltext .= esc_html($3, -nbsp=>1);
+				} else {
+					$ltext = esc_html($ltext, -nbsp=>1);
+				}
+				print "<div class=\"pre\">" .
+					$cgi->a({-href => href(action=>"blob", hash=>$co{'hash'},
+							       file_name=>"$file").'#l'.$lno,
+						-class => "linenr"}, sprintf('%4i', $lno))
+					. ' ' .  $ltext . "</div>\n";
+			}
+		}
+		if ($lastfile) {
+			print "</td></tr>\n";
+			if ($matches > 1000) {
+				print "<div class=\"diff nodifferences\">Too many matches, listing trimmed</div>\n";
+			}
+		} else {
+			print "<div class=\"diff nodifferences\">No matches found</div>\n";
+		}
+		close $fd;
+
+		print "</table>\n";
+	}
 	git_footer_html();
 }
 
@@ -4741,6 +4846,20 @@ sub git_search_help {
 <dl>
 <dt><b>commit</b></dt>
 <dd>The commit messages and authorship information will be scanned for the given string.</dd>
+EOT
+	my ($have_grep) = gitweb_check_feature('grep');
+	if ($have_grep) {
+		print <<EOT;
+<dt><b>grep</b></dt>
+<dd>All files in the currently selected tree (HEAD unless you are explicitly browsing
+    a different one) are searched for the given
+<a href="http://en.wikipedia.org/wiki/Regular_expression">regular expression</a>
+(POSIX extended) and the matches are listed. On large
+trees, this search can take a while and put some strain on the server, so please use it with
+some consideration.</dd>
+EOT
+	}
+	print <<EOT;
 <dt><b>author</b></dt>
 <dd>Name and e-mail of the change author and date of birth of the patch will be scanned for the given string.</dd>
 <dt><b>committer</b></dt>

^ permalink raw reply related

* Re: [PATCH] git-gui: Build even if tclsh is not available
From: Petr Baudis @ 2007-05-17  2:36 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: Junio C Hamano, git
In-Reply-To: <20070517021858.GY3141@spearce.org>

On Thu, May 17, 2007 at 04:18:58AM CEST, Shawn O. Pearce wrote:
> I have a couple of problems with the patch as-is.  The first is
> of course that the patch needs to be split into two; one patch for
> the git-gui subdirectory itself and one for git.git.

Hmm, why? It's an atomic change, one part doesn't make sense without the
other.

> My other problem is 
> 
> >  ifeq ($(findstring $(MAKEFLAGS),s),s)
> > @@ -92,7 +92,7 @@ install: all
> >  	$(INSTALL) git-gui '$(DESTDIR_SQ)$(gitexecdir_SQ)'
> >  	$(foreach p,$(GITGUI_BUILT_INS), rm -f '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' && ln '$(DESTDIR_SQ)$(gitexecdir_SQ)/git-gui' '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' ;)
> >  	$(INSTALL) -d -m755 '$(DESTDIR_SQ)$(libdir_SQ)'
> > -	$(INSTALL) -m644 lib/tclIndex '$(DESTDIR_SQ)$(libdir_SQ)'
> > +	[ ! -e lib/tclIndex ] || $(INSTALL) -m644 lib/tclIndex '$(DESTDIR_SQ)$(libdir_SQ)'
> >  	$(foreach p,$(ALL_LIBFILES), $(INSTALL) -m644 $p '$(DESTDIR_SQ)$(libdir_SQ)' ;)
> 
> git-gui won't work if lib/tclIndex is missing or invalid.  So not
> installing it means we should just disable git-gui entirely.

Aha, ouch - I understood that it is only an optimization. :-(

So AIUI, there are several possibilities:

  (i) Makefile will autodecide on whether git-gui will be
built+installed or not

  (ii) ./configure will, people not using configure and building on
servers will be left to tweak config manually

  (iii) ./configure will, git-gui will default to not to be built and
people not using configure and wanting git-gui will be left to tweak
config manually

I suspect that (ii) will be chosen, and even though I don't like it
*personally* I guess it's the most reasonable approach for the general
public. I didn't know that tclIndex is vital for git-gui when I
submitted the patch, the /Makefile comment suggests otherwise.

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
Ever try. Ever fail. No matter. // Try again. Fail again. Fail better.
		-- Samuel Beckett

^ permalink raw reply

* [PATCH] Git.pm: Add remote_refs() git-ls-remote frontend
From: Petr Baudis @ 2007-05-17  2:37 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Should support all the important features, I guess. Too bad that
	git-ls-remote --heads .
	
is subtly different from

	git-ls-remote . refs/heads/

so we have to provide the interface for specifying both.

This patch also converts git-svn.perl to use it.

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

 git-remote.perl |    5 +----
 perl/Git.pm     |   55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/git-remote.perl b/git-remote.perl
index 5763799..5403d86 100755
--- a/git-remote.perl
+++ b/git-remote.perl
@@ -128,10 +128,7 @@ sub update_ls_remote {
 	return if (($harder == 0) ||
 		   (($harder == 1) && exists $info->{'LS_REMOTE'}));
 
-	my @ref = map {
-		s|^[0-9a-f]{40}\s+refs/heads/||;
-		$_;
-	} $git->command(qw(ls-remote --heads), $info->{'URL'});
+	my @ref = keys %{$git->remote_refs($info->{'URL'}, [ 'heads' ])};
 	$info->{'LS_REMOTE'} = \@ref;
 }
 
diff --git a/perl/Git.pm b/perl/Git.pm
index 8fd3611..9818981 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -51,7 +51,7 @@ require Exporter;
 # Methods which can be called as standalone functions as well:
 @EXPORT_OK = qw(command command_oneline command_noisy
                 command_output_pipe command_input_pipe command_close_pipe
-                version exec_path hash_object git_cmd_try);
+                version exec_path hash_object git_cmd_try remote_refs);
 
 
 =head1 DESCRIPTION
@@ -550,6 +550,59 @@ sub config_bool {
 }
 
 
+=item remote_refs ( REPOSITORY [, GROUPS [, REFGLOBS ] ] )
+
+This function returns a hashref of refs stored in a given remote repository.
+The hash is in the format C<refname =\> hash>. For tags, the C<refname> entry
+contains the tag object while a C<refname^{}> entry gives the tagged objects.
+
+C<REPOSITORY> has the same meaning as the appropriate C<git-ls-remote>
+argument; either an URL or a remote name (if called on a repository instance).
+C<GROUPS> is an optional arrayref that can contain 'tags' to return all the
+tags and/or 'heads' to return all the heads. C<REFGLOB> is an optional array
+of strings containing a shell-like glob to further limit the refs returned in
+the hash; the meaning is again the same as the appropriate C<git-ls-remote>
+argument.
+
+This function may or may not be called on a repository instance. In the former
+case, remote names as defined in the repository are recognized as repository
+specifiers.
+
+=cut
+
+sub remote_refs {
+	my ($self, $repo, $groups, $refglobs) = _maybe_self(@_);
+	my @args;
+	if (ref $groups eq 'ARRAY') {
+		foreach (@$groups) {
+			if ($_ eq 'heads') {
+				push (@args, '--heads');
+			} elsif ($_ eq 'tags') {
+				push (@args, '--tags');
+			} else {
+				# Ignore unknown groups for future
+				# compatibility
+			}
+		}
+	}
+	push (@args, $repo);
+	if (ref $refglobs eq 'ARRAY') {
+		push (@args, @$refglobs);
+	}
+
+	my @self = $self ? ($self) : (); # Ultra trickery
+	my ($fh, $ctx) = Git::command_output_pipe(@self, 'ls-remote', @args);
+	my %refs;
+	while (<$fh>) {
+		chomp;
+		my ($hash, $ref) = split(/\t/, $_, 2);
+		$refs{$ref} = $hash;
+	}
+	Git::command_close_pipe(@self, $fh, $ctx);
+	return \%refs;
+}
+
+
 =item ident ( TYPE | IDENTSTR )
 
 =item ident_person ( TYPE | IDENTSTR | IDENTARRAY )

^ permalink raw reply related

* Re: [PATCH] git-gui: Build even if tclsh is not available
From: Shawn O. Pearce @ 2007-05-17  2:49 UTC (permalink / raw)
  To: Petr Baudis; +Cc: Junio C Hamano, git
In-Reply-To: <20070517023614.GL4489@pasky.or.cz>

Petr Baudis <pasky@suse.cz> wrote:
> On Thu, May 17, 2007 at 04:18:58AM CEST, Shawn O. Pearce wrote:
> > I have a couple of problems with the patch as-is.  The first is
> > of course that the patch needs to be split into two; one patch for
> > the git-gui subdirectory itself and one for git.git.
> 
> Hmm, why? It's an atomic change, one part doesn't make sense without the
> other.

Because git-gui is actually a project maintained external from
git.git.  It just happens that Junio pulls various versions of
it into git.git to distribute it along with git.git releases.

I deal with these sorts of "atomic changes" by making an evil merge
in git.git and asking Junio to pull the evil merge.  But we've only
had one such case thus far.
 
> > git-gui won't work if lib/tclIndex is missing or invalid.  So not
> > installing it means we should just disable git-gui entirely.
> 
>   (i) Makefile will autodecide on whether git-gui will be
> built+installed or not
> 
>   (ii) ./configure will, people not using configure and building on
> servers will be left to tweak config manually
> 
>   (iii) ./configure will, git-gui will default to not to be built and
> people not using configure and wanting git-gui will be left to tweak
> config manually

(iv) if tclsh is not available then create a simpler lib/tclIndex that
loads all of the lib directory, even if it isn't needed.  That makes
tclsh being available strictly an optimization, and yet git-gui still
is installable.

-- 
Shawn.

^ permalink raw reply

* Re: Smart fetch via HTTP?
From: Nicolas Pitre @ 2007-05-17  3:45 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: Johannes Schindelin, Martin Langhoff, Jan Hudec, git
In-Reply-To: <20070517010335.GU3141@spearce.org>

On Wed, 16 May 2007, Shawn O. Pearce wrote:

> Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> > Don't forget that those 10% probably do not do you the favour to be in 
> > large chunks. Chances are that _every_ _single_ wanted object is separate 
> > from the others.
> 
> That's completely possible.  Assuming the objects even are packed
> in the first place.  Its very unlikely that you would be able to
> fetch very large of a range from an existing packfile, you would be
> submitting most of your range requests for very very small sections.

Well, in the commit objects case you're likely to have a bunch of them 
all contigous.

For tree and blob objects it is less likely.

And of course there is the question of deltas for which you might or 
might not have the base object locally already.

Still... I wonder if this could be actually workable.  A typical daily 
update on the Linux kernel repository might consist of a couple hundreds 
or a few tousands objects.  This could still be faster to fetch parts of 
a pack than the whole pack if the size difference is above a certain 
treshold.  It is certainly not worse than fetching loose objects.

Things would be pretty horrid if you think of fetching a commit object, 
parsing it to find out what tree object to fetch, then parse that tree 
object to find out what other objects to fetch, and so on.

But if you only take the approach of fetching the pack index files, 
finding out about the objects that the remote has that are not available 
locally, and then fetching all those objects from within pack files 
without even looking at them (except for deltas), then it should be 
possible to issue a couple requests in parallel and possibly have decent 
performances.  And if it turns out that more than, say, 70% of a 
particular pack is to be fetched (you can determine that up front), then 
it might be decided to fetch the whole pack.

There is no way to sensibly keep those objects packed on the receiving 
end of course, but storing them as loose objects and repacking them 
afterwards should be just fine.

Of course you'll get objects from branches in the remote repository you 
might not be interested in, but that's a price to pay for such a hack.  
On average the overhead shouldn't be that big anyway if branches within 
a repository are somewhat related.

I think this is something worth experimenting.


Nicolas

^ permalink raw reply

* Re: [PATCH] gitweb: Fix few 'use of undefined value' warnings
From: Junio C Hamano @ 2007-05-17  4:05 UTC (permalink / raw)
  To: Petr Baudis; +Cc: git
In-Reply-To: <20070517013209.GJ4489@pasky.or.cz>

Petr Baudis <pasky@suse.cz> writes:

> On Fri, Apr 27, 2007 at 06:43:53PM CEST, Petr Baudis wrote:
>> diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
>> index b67ce41..b51103e 100755
>> --- a/gitweb/gitweb.perl
>> +++ b/gitweb/gitweb.perl
>> @@ -1057,6 +1058,7 @@ sub git_get_project_description {
>>  	open my $fd, "$projectroot/$path/description" or return undef;
>>  	my $descr = <$fd>;
>>  	close $fd;
>> +	$descr or return undef;
>>  	chomp $descr;
>>  	return $descr;
>>  }
>
> It looks like this hunk has been skipped...?

It is more like the whole messages was missed, and then 198a2a8a
and others tried to do the same thing but missed this one.

^ permalink raw reply

* Re: [PATCH] gitweb: Change base font size to "small"
From: Junio C Hamano @ 2007-05-17  4:07 UTC (permalink / raw)
  To: Petr Baudis; +Cc: junkio, Jakub Narebski, git, Jan Hudec, David Kågedal
In-Reply-To: <20070517021723.GK4489@pasky.or.cz>

Petr Baudis <pasky@suse.cz> writes:

> On Wed, May 16, 2007 at 12:51:38PM CEST, Jakub Narebski wrote:
>> Proposed-by: Jan Hudec <bulb@ucw.cz>
>> Signed-off-by: Jakub Narebski <jnareb@gmail.com>
>
> Acked-by: Petr Baudis <pasky@suse.cz>
>
> just for the record, since it seems to be already applied anyway. By the
> way, I think this commit message is more optimal than what ended up for
> some reason (Jakub wasn't fast enough? ;-)

Most likely timezone difference is the largest factor.

^ permalink raw reply

* Re: What's cooking in git.git (topics)
From: Junio C Hamano @ 2007-05-17  4:13 UTC (permalink / raw)
  To: Daniel Barkalow; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0705162057380.18541@iabervon.org>

Daniel Barkalow <barkalow@iabervon.org> writes:

> On Wed, 16 May 2007, Junio C Hamano wrote:
> ...
>> * db/remote (Tue May 15 22:50:19 2007 -0400) 5 commits
>>  - Update local tracking refs when pushing
>>  - Add handlers for fetch-side configuration of remotes.
>>  - Move refspec parser from connect.c and cache.h to remote.{c,h}
>>  - Move remote parsing into a library file out of builtin-push.
>>  + git-update-ref: add --no-deref option for overwriting/detaching
>>    ref
>
> AFAICT, this isn't really in my topic. Rebased too much, perhaps?

You have a new call to lock_any_ref_for_update() in the last
patch in your series, whose function signature is changed by
Sven's "add --no-deref".

Because the latter is already scheduled for 'master' post 1.5.2,
I rebased the remote series on top of it, to adjust to the
change early (i.e. while my memory is still fresh).

That's what

	This was rebased on to Sven's change to lock_any_ref_for_update();

comment was about in the earlier "[2/4] What's not in 1.5.2" message.

^ permalink raw reply

* Re: [PATCH 03/10] glossary: expand and clarify some definitions, prune cross-references
From: J. Bruce Fields @ 2007-05-17  4:30 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <f2a4b4$ein$3@sea.gmane.org>

On Mon, May 14, 2007 at 07:00:48PM +0200, Jakub Narebski wrote:
> J. Bruce Fields wrote:
> 
> > +[[def_detached_HEAD]]detached HEAD::
> > +       Normally HEAD refers to the tip of a
> > +       <<def_branch,branch>>.
> 
> Normally HEAD refers to the branch _name_ (names current branch).
> From this sentence one can think that normally HEAD is pointer
> to commit which is tip of current branch.

OK, thanks; fixed in maint branch of
git://linux-nfs.org/~bfields/git.git.

--b.

^ permalink raw reply

* Re: What's cooking in git.git (topics)
From: Daniel Barkalow @ 2007-05-17  4:31 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vzm44axzl.fsf@assigned-by-dhcp.cox.net>

On Wed, 16 May 2007, Junio C Hamano wrote:

> Daniel Barkalow <barkalow@iabervon.org> writes:
> 
> > On Wed, 16 May 2007, Junio C Hamano wrote:
> > ...
> >> * db/remote (Tue May 15 22:50:19 2007 -0400) 5 commits
> >>  - Update local tracking refs when pushing
> >>  - Add handlers for fetch-side configuration of remotes.
> >>  - Move refspec parser from connect.c and cache.h to remote.{c,h}
> >>  - Move remote parsing into a library file out of builtin-push.
> >>  + git-update-ref: add --no-deref option for overwriting/detaching
> >>    ref
> >
> > AFAICT, this isn't really in my topic. Rebased too much, perhaps?
> 
> You have a new call to lock_any_ref_for_update() in the last
> patch in your series, whose function signature is changed by
> Sven's "add --no-deref".
> 
> Because the latter is already scheduled for 'master' post 1.5.2,
> I rebased the remote series on top of it, to adjust to the
> change early (i.e. while my memory is still fresh).
> 
> That's what
> 
> 	This was rebased on to Sven's change to lock_any_ref_for_update();
> 
> comment was about in the earlier "[2/4] What's not in 1.5.2" message.

Oh, okay. I noticed the change, but missed that what it was rebased 
onto wasn't simply in the implicit base for the series, and also didn't 
realize that it was supposed to get listed that way. (I think it would be 
more clear to list merges of depended-on series rather than the contents 
of the series, when the depended-on series is also listed)

	-Daniel
*This .sig left intentionally blank*

^ permalink raw reply

* Re: [3/4] What's not in 1.5.2 (new topics)
From: Andy Parkins @ 2007-05-17  4:39 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano
In-Reply-To: <11793556371774-git-send-email-junkio@cox.net>

On Wednesday 2007, May 16, Junio C Hamano wrote:

>      (3) git-checkout finds there is .gitmodules file in the
>          tree (and the checked-out working file), which
>          describes these subprojects.  It looks at the config
>          and notices that it does not yet know about them
>          (obviously this is true, as this is the first checkout
>          after clone, but I am trying to outline how checkout
>          after a merge should work in the general case).
>
> 	 It determines where to fetch that subproject from,
> 	 perhaps it uses the default URL described in
> 	 .gitmodules file to, while asking the user for
> 	 confirmation and giving the user a chance to override
> 	 it.  And it records something in the config -- now that
> 	 project is known to this repository.

I've been thinking about this .gitmodules thing and have a concern.  
Aren't we falling into the svn:externals trap?

The svn:externals property is analagous to our .gitmodules file.  svn 
properties were basically just version controlled out-of-tree meta data 
(making them annoying to work with - in-tree is better).  

svn "submodule" support was done by writing something like

  subproject svn://host/blah/blah

In the svn:externals property attached to the directory that 
the "subproject" directory was in.  To translate:

  svn propset svn:externals "subproject svn://blah/blah/blah" .

  git clone git://blah/blah/blah subproject
  git add subproject

The hole that this sort of thing gets you in to is that the 
svn:externals property is version controlled.  Time passes since you 
added the external; in that time the URL becomes invalid.  No problem, 
you simply change the svn:externals property.  KABOOM.  Now any 
historical checkout fails because it checks out the svn:externals 
property from that checkout and tries to use the wrong URL.

Our in-tree .gitmodules will have the same problem.  I recognise that 
you've mitigated that with some "confirm with the user, store in the 
config" hand waving; but that is just hiding the problem: the submodule 
URL is not something that should be version controlled; it is an 
all-of-history property; when it changes for revision N it changes for 
revision N-1, N-2, N-3, etc.  Storing it in .gitmodules implies that 
it's value in the past has meaning - it doesn't.

You mentioned yourself that that problem is not confined to the temporal 
accuracy of .gitmodules, there is spatial accuracy too - there is no 
guarantee that user A wants to use the same submodule URL as user B.  
Fast forward to when we've got submodule support; let's say you start 
using it for git-gui (for example).  Somehow (let's leave the "how" 
till later) I've gotten a working git tree with a git-gui checked out.  
I go to my laptop and clone that repository (note: NOT the upstream 
repository).  When git-clone hits the git-gui submodule it should not 
go looking for the upstream git-gui, I will want it to clone my local 
git-gui submodule.  i.e. in-tree .gitmodules URL for git-gui will be 
wrong.

I hope the above shows that in-tree .gitmodules is wrong; it can only 
ever be a hint, and in a great number of cases it will be an incorrect 
hint.

I know it's so enticing to store it in-tree; it would be great because 
the normal repository object transfer mechanism would get the URL of 
the submodule to the receiver with no changes to current 
infrastructure.  I say: tough luck - we need another mechanism.  The 
submodule URL is a per-repository setting, not a per-project setting.  
When fetching, some out-of-band mechanism for telling the other side 
what URL _this_ repository thinks the submodule is at needs to be 
supplied.  I don't know what space there is in the git protocol for 
putting that information, but I suspect that that is where it needs to 
go.

As an alternative to that, the supermodule could be given the ability to 
proxy for the submodule during clone.  It knows where the submodule is 
stored from it's point of view; is there scope for doing a 
virtual-server-like system were the supermodule git-daemon just changes 
to the submodule repository (in the case it is local) and thereby gives 
the downstream git access to the submodule without it even needing a 
URL.

>  * Perhaps add 'tree' entries in the index.  This may make the
>    current cache-tree extension unnecessary, and I suspect it
>    will simplify various paths that deal with D/F conflicts in
>    the current codebase.
>
>    I suspect this might need 1.6, as it is a one-way backward
>    incompatible change for the 'index', but 'index' is local so
>    it might not be such a big deal.  In the worst case, when the
>    users find "git checkout" from 1.5.2 does not work in a
>    repository checked out with such an updated index format, we
>    could ask them to "rm -f .git/index && git checkout HEAD".

I don't think even that would be necessary.  Assuming that the new index 
format is a superset of the old index format the only way that tree 
entries would get in the index would be by using git-1.6.  Almost by 
definition then, if they are in there your git is up-to-date enough to 
use them.  (modulo me not really understanding what you mean)



Andy

-- 
Dr Andy Parkins, M Eng (hons), MIET
andyparkins@gmail.com

^ permalink raw reply

* Re: [PATCH] Move refspec pattern matching to match_refs().
From: Junio C Hamano @ 2007-05-17  5:04 UTC (permalink / raw)
  To: Daniel Barkalow; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0705162217250.18541@iabervon.org>

Daniel Barkalow <barkalow@iabervon.org> writes:

> This means that send-pack and http-push will support pattern refspecs,
> so builtin-push.c doesn't have to expand them, and also git push can
> just turn --tags into "refs/tags/*", further simplifying builtin-push.c

Nice.

> @@ -266,5 +174,8 @@ int cmd_push(int argc, const char **argv, const char *prefix)
>  		usage(push_usage);
>  	}
>  	set_refspecs(argv + i, argc - i);
> +	if (all && refspec)
> +		usage(push_usage);
> +
>  	return do_push(repo);
>  }

Is this hunk an independent bugfix?  I think send-pack has its
own check but I guess http-push lacked its own check?

> diff --git a/refs.c b/refs.c
> index 2ae3235..cd63f37 100644
> --- a/refs.c
> +++ b/refs.c
> @@ -603,15 +603,18 @@ int get_ref_sha1(const char *ref, unsigned char *sha1)
>  
>  static inline int bad_ref_char(int ch)
>  {
> -	return (((unsigned) ch) <= ' ' ||
> -		ch == '~' || ch == '^' || ch == ':' ||
> -		/* 2.13 Pattern Matching Notation */
> -		ch == '?' || ch == '*' || ch == '[');
> +	if (((unsigned) ch) <= ' ' ||
> +	    ch == '~' || ch == '^' || ch == ':')
> +		return 1;
> +	/* 2.13 Pattern Matching Notation */
> +	if (ch == '?' || ch == '*' || ch == '[')
> +		return 2;
> +	return 0;
>  }
>  
>  int check_ref_format(const char *ref)
>  {
> -	int ch, level;
> +	int ch, level, bad_type;
>  	const char *cp = ref;
>  
>  	level = 0;
> @@ -622,13 +625,19 @@ int check_ref_format(const char *ref)
>  			return -1; /* should not end with slashes */
>  
>  		/* we are at the beginning of the path component */
> -		if (ch == '.' || bad_ref_char(ch))
> +		if (ch == '.')
>  			return -1;
> +		bad_type = bad_ref_char(ch);
> +		if (bad_type) {
> +			return (bad_type == 2 && !*cp) ? -3 : -1;
> +		}
>  
>  		/* scan the rest of the path component */
>  		while ((ch = *cp++) != 0) {
> -			if (bad_ref_char(ch))
> -				return -1;
> +			bad_type = bad_ref_char(ch);
> +			if (bad_type) {
> +				return (bad_type == 2 && !*cp) ? -3 : -1;
> +			}
>  			if (ch == '/')
>  				break;
>  			if (ch == '.' && *cp == '.')
> diff --git a/remote.c b/remote.c
> index 46fe8d9..05b16ad 100644
> --- a/remote.c
> +++ b/remote.c
>...
> @@ -497,23 +501,48 @@ static struct ref *find_ref_by_name(struct ref *list, const char *name)
>...
>  int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
>  	       int nr_refspec, char **refspec, int all)
>  {
>  	struct refspec *rs =
>  		parse_ref_spec(nr_refspec, (const char **) refspec);
>  
> -	if (nr_refspec)
> -		return match_explicit_refs(src, dst, dst_tail, rs, nr_refspec);
> +	if (nr_refspec) {
> +		if (match_explicit_refs(src, dst, dst_tail, rs, nr_refspec))
> +			return -1;
> +	}

Style?  "if (nr_refspec && match_explicit...)" and then you can
lose the excess braces.

>  
>  	/* pick the remainder */
>  	for ( ; src; src = src->next) {
>  		struct ref *dst_peer;
>  		if (src->peer_ref)
>  			continue;
> +		if (!check_pattern_match(rs, nr_refspec, src))
> +			continue;
> +
>  		dst_peer = find_ref_by_name(dst, src->name);
> -		if ((dst_peer && dst_peer->peer_ref) || (!dst_peer && !all))
> +		if (dst_peer && dst_peer->peer_ref) {
> +			/* We're already sending something to this ref. */
> +			continue;
> +		}
> +		if (!dst_peer && !nr_refspec && !all) {
> +			/* Remote doesn't have it, and we have no
> +			 * explicit pattern, and we don't have
> +			 * --all. */
>  			continue;
> +		}
>  		if (!dst_peer) {
>  			/* Create a new one and link it */
>  			int len = strlen(src->name) + 1;

Style?  Excess braces...

> diff --git a/send-pack.c b/send-pack.c
> index 59352c8..697dbbc 100644
> --- a/send-pack.c
> +++ b/send-pack.c
> @@ -354,6 +354,7 @@ static void verify_remote_names(int nr_heads, char **heads)
>  		case -2: /* ok but a single level -- that is fine for
>  			  * a match pattern.
>  			  */
> +		case -3: /* ok but ends with a pattern-match character */
>  			continue;
>  		}
>  		die("remote part of refspec is not a valid name in %s",

I am not sure what is going on here.  Your new code returns -3
when the pattern has any metacharacter at the end, and
metacharacter in the middle gives -1.  Does that mean the code
would say "alright, that is a pattern" when it sees "refs/heads/foo["?

I think we can go two ways.

 (1) Although the current code does not support it, the intent
     for the globbing refspec "refs/*:refs/remotes/origin/*" was
     to allow "refs/heads/[a-z]*:refs/remotes/origin/[a-z]*" (I
     am not sure about the RHS, but it should be clear that what
     is intended is "grab only the ones that begin with [a-z]
     and track" in that example).  If we were to eventually do
     this, I think check_ref_format() should probably be a bit
     more careful when parsing glob() patterns (e.g. matching
     bra-ket).
     
 (2) As my uncertainty about the RHS above shows, we may not
     support more general glob patterns and stay with only the
     trailing "/*".  At least that is what we have now.  Maybe
     check_ref_format should return "good but ends with meta"
     only when the refspec consists of all good ref_char
     followed by "/*" at the end.

My current preference is the latter.

^ permalink raw reply

* [PATCH] Document core.excludesfile for git-add
From: Michael Hendricks @ 2007-05-17  5:08 UTC (permalink / raw)
  To: git; +Cc: Michael Hendricks

During the discussion of core.excludesfile in the user-manual, I realized
that the configuration wasn't mentioned in the man pages.

Signed-off-by: Michael Hendricks <michael@ndrix.org>
---
 Documentation/git-add.txt |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt
index 27b9c0f..a0c9f68 100644
--- a/Documentation/git-add.txt
+++ b/Documentation/git-add.txt
@@ -69,6 +69,15 @@ OPTIONS
 	for command-line options).
 
 
+Configuration
+-------------
+
+The optional configuration variable 'core.excludesfile' indicates a path to a
+file containing patterns of file names to exclude from git-add, similar to
+$GIT_DIR/info/exclude.  Patterns in the exclude file are used in addition to
+those in info/exclude.  See link:repository-layout.html[repository layout].
+
+
 EXAMPLES
 --------
 git-add Documentation/\\*.txt::
-- 
1.5.2.rc3.39.gaf9b-dirty

^ permalink raw reply related

* [PATCH] git-send-email: allow leading white space on mutt aliases
From: Michael Hendricks @ 2007-05-17  5:15 UTC (permalink / raw)
  To: git; +Cc: Michael Hendricks

mutt version 1.5.14 (perhaps earlier versions too) permits alias files to have
white space before the 'alias' keyword.

Signed-off-by: Michael Hendricks <michael@ndrix.org>
---
 git-send-email.perl |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/git-send-email.perl b/git-send-email.perl
index 404095f..eb876f8 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -212,7 +212,7 @@ my $aliasfiletype = $repo->config('sendemail.aliasfiletype');
 my %parse_alias = (
 	# multiline formats can be supported in the future
 	mutt => sub { my $fh = shift; while (<$fh>) {
-		if (/^alias\s+(\S+)\s+(.*)$/) {
+		if (/^\s*alias\s+(\S+)\s+(.*)$/) {
 			my ($alias, $addr) = ($1, $2);
 			$addr =~ s/#.*$//; # mutt allows # comments
 			 # commas delimit multiple addresses
-- 
1.5.2.rc3.39.gaf9b-dirty

^ permalink raw reply related

* Re: [3/4] What's not in 1.5.2 (new topics)
From: Junio C Hamano @ 2007-05-17  5:21 UTC (permalink / raw)
  To: Andy Parkins; +Cc: git
In-Reply-To: <200705170539.11402.andyparkins@gmail.com>

Andy Parkins <andyparkins@gmail.com> writes:

> Our in-tree .gitmodules will have the same problem.  I recognise that 
> you've mitigated that with some "confirm with the user, store in the 
> config" hand waving; but that is just hiding the problem: the submodule 
> URL is not something that should be version controlled; it is an 
> all-of-history property; when it changes for revision N it changes for 
> revision N-1, N-2, N-3, etc.  Storing it in .gitmodules implies that 
> it's value in the past has meaning - it doesn't.

I think that depends _WHY_ the URL recorded .gitmodules are
updated.  It would perfectly be reasonable for release #1 of an
appliance project to bind linux 2.4 tree at kernel/ subdirectory
while release #2 source to have 2.6 one; they come from two
different repository URLs.  When you seek the superproject back
to release #1, you would still want to fetch from 2.4 upstream
if you are updating.

If the URL is changed only because the logically same project
was relocated to different hosting service, then what you say is
true.

What I was "handwaving" (or "envisioning") was to have something
like this in .gitmodules:

	[subproject "kernel/"]
        	URL = git://git.kernel.org/pub/linux-2.4.git

(or 2.6, depending on the revision of the superproject) and per
repository configuration would maps this with these two entries:

	[subproject "git://git.kernel.org/pub/linux-2.4.git"]
        	URL = http://www.kernel.org/pub/linux-2.4.git

	[subproject "git://git.kernel.org/pub/linux-2.6.git"]
        	URL = http://www.kernel.org/pub/linux-2.6.git

The intent is 

	(1) "kernel/" directory is found to be a gitlink in the
            tree/index; .gitmodules is consulted to find the
            "URL", which is just a handle and the initial hint

	(2) That "initial hint" is used to look up the
            subproject entry from the configuration, to find the
            "real" URL that is used by this repository

> You mentioned yourself that that problem is not confined to the temporal 
> accuracy of .gitmodules, there is spatial accuracy too - there is no 
> guarantee that user A wants to use the same submodule URL as user B.  

which hopefully is already answered by the above handwaving ;-).

The case of "relocated to different hosting site" would also be
solved by having more than one entries in the configuration
file.  If a project that used to be hosted at git.or.cz has
migrated to git.sf.net, its .gitmodules file from an earlier
revision would have URL pointing at git.repo.cz and newer ones
would point at git.sf.net.  If you started following that
project before the migration, you would have:

	[subproject "git://git.or.cz/sub.git"]
        	URL = git://git.or.cz/sub.git

in your .git/config.  After the repository migrates to
git.sf.net, you would update that existing entry and also add
another entry, so that .git/config would have these two entries:

	[subproject "git://git.or.cz/sub.git"]
        	URL = git://git.sf.net/sub.git

	[subproject "git://git.sf.net/sub.git"]
        	URL = git://git.sf.net/sub.git

^ permalink raw reply

* Re: [PATCH] Document core.excludesfile for git-add
From: Junio C Hamano @ 2007-05-17  5:31 UTC (permalink / raw)
  To: Michael Hendricks; +Cc: git
In-Reply-To: <1179378530822-git-send-email-michael@ndrix.org>

Thanks, but wouldn't this belong to Documentation/config.txt
instead, I wonder?

^ permalink raw reply

* Re: [PATCH] Move refspec pattern matching to match_refs().
From: Daniel Barkalow @ 2007-05-17  5:55 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vhcqcavn5.fsf@assigned-by-dhcp.cox.net>

On Wed, 16 May 2007, Junio C Hamano wrote:

> Daniel Barkalow <barkalow@iabervon.org> writes:
> 
> > This means that send-pack and http-push will support pattern refspecs,
> > so builtin-push.c doesn't have to expand them, and also git push can
> > just turn --tags into "refs/tags/*", further simplifying builtin-push.c
> 
> Nice.
> 
> > @@ -266,5 +174,8 @@ int cmd_push(int argc, const char **argv, const char *prefix)
> >  		usage(push_usage);
> >  	}
> >  	set_refspecs(argv + i, argc - i);
> > +	if (all && refspec)
> > +		usage(push_usage);
> > +
> >  	return do_push(repo);
> >  }
> 
> Is this hunk an independent bugfix?  I think send-pack has its
> own check but I guess http-push lacked its own check?

This replaces the die() in expand_refspecs(), which was at the end of 
set_refspecs(). I think the idea is that "git push --all foo bar" isn't a 
consistancy problem, but it suggests that the user is confused, and so the 
error should be up front if there is one.

> > diff --git a/refs.c b/refs.c
> > index 2ae3235..cd63f37 100644
> > --- a/refs.c
> > +++ b/refs.c
> > @@ -603,15 +603,18 @@ int get_ref_sha1(const char *ref, unsigned char *sha1)
> >  
> >  static inline int bad_ref_char(int ch)
> >  {
> > -	return (((unsigned) ch) <= ' ' ||
> > -		ch == '~' || ch == '^' || ch == ':' ||
> > -		/* 2.13 Pattern Matching Notation */
> > -		ch == '?' || ch == '*' || ch == '[');
> > +	if (((unsigned) ch) <= ' ' ||
> > +	    ch == '~' || ch == '^' || ch == ':')
> > +		return 1;
> > +	/* 2.13 Pattern Matching Notation */
> > +	if (ch == '?' || ch == '*' || ch == '[')
> > +		return 2;
> > +	return 0;
> >  }
> >  
> >  int check_ref_format(const char *ref)
> >  {
> > -	int ch, level;
> > +	int ch, level, bad_type;
> >  	const char *cp = ref;
> >  
> >  	level = 0;
> > @@ -622,13 +625,19 @@ int check_ref_format(const char *ref)
> >  			return -1; /* should not end with slashes */
> >  
> >  		/* we are at the beginning of the path component */
> > -		if (ch == '.' || bad_ref_char(ch))
> > +		if (ch == '.')
> >  			return -1;
> > +		bad_type = bad_ref_char(ch);
> > +		if (bad_type) {
> > +			return (bad_type == 2 && !*cp) ? -3 : -1;
> > +		}
> >  
> >  		/* scan the rest of the path component */
> >  		while ((ch = *cp++) != 0) {
> > -			if (bad_ref_char(ch))
> > -				return -1;
> > +			bad_type = bad_ref_char(ch);
> > +			if (bad_type) {
> > +				return (bad_type == 2 && !*cp) ? -3 : -1;
> > +			}
> >  			if (ch == '/')
> >  				break;
> >  			if (ch == '.' && *cp == '.')
> > diff --git a/remote.c b/remote.c
> > index 46fe8d9..05b16ad 100644
> > --- a/remote.c
> > +++ b/remote.c
> >...
> > @@ -497,23 +501,48 @@ static struct ref *find_ref_by_name(struct ref *list, const char *name)
> >...
> >  int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
> >  	       int nr_refspec, char **refspec, int all)
> >  {
> >  	struct refspec *rs =
> >  		parse_ref_spec(nr_refspec, (const char **) refspec);
> >  
> > -	if (nr_refspec)
> > -		return match_explicit_refs(src, dst, dst_tail, rs, nr_refspec);
> > +	if (nr_refspec) {
> > +		if (match_explicit_refs(src, dst, dst_tail, rs, nr_refspec))
> > +			return -1;
> > +	}
> 
> Style?  "if (nr_refspec && match_explicit...)" and then you can
> lose the excess braces.

Actually, just "if (match_explicit(...))" is fine. It'll do nothing and 
return 0 if !nr_refspec.

> >  	/* pick the remainder */
> >  	for ( ; src; src = src->next) {
> >  		struct ref *dst_peer;
> >  		if (src->peer_ref)
> >  			continue;
> > +		if (!check_pattern_match(rs, nr_refspec, src))
> > +			continue;
> > +
> >  		dst_peer = find_ref_by_name(dst, src->name);
> > -		if ((dst_peer && dst_peer->peer_ref) || (!dst_peer && !all))
> > +		if (dst_peer && dst_peer->peer_ref) {
> > +			/* We're already sending something to this ref. */
> > +			continue;
> > +		}
> > +		if (!dst_peer && !nr_refspec && !all) {
> > +			/* Remote doesn't have it, and we have no
> > +			 * explicit pattern, and we don't have
> > +			 * --all. */
> >  			continue;
> > +		}
> >  		if (!dst_peer) {
> >  			/* Create a new one and link it */
> >  			int len = strlen(src->name) + 1;
> 
> Style?  Excess braces...

A comment doesn't count as a second "thing" to be in a conditional for the 
purposes of style? Multiple equally-indented lines without braces 
distracts me with thinking that the actual statement might be misindented.

> I am not sure what is going on here.  Your new code returns -3
> when the pattern has any metacharacter at the end, and
> metacharacter in the middle gives -1.  Does that mean the code
> would say "alright, that is a pattern" when it sees "refs/heads/foo["?
>
> I think we can go two ways.
> 
>  (1) Although the current code does not support it, the intent
>      for the globbing refspec "refs/*:refs/remotes/origin/*" was
>      to allow "refs/heads/[a-z]*:refs/remotes/origin/[a-z]*" (I
>      am not sure about the RHS, but it should be clear that what
>      is intended is "grab only the ones that begin with [a-z]
>      and track" in that example).  If we were to eventually do
>      this, I think check_ref_format() should probably be a bit
>      more careful when parsing glob() patterns (e.g. matching
>      bra-ket).
>      
>  (2) As my uncertainty about the RHS above shows, we may not
>      support more general glob patterns and stay with only the
>      trailing "/*".  At least that is what we have now.  Maybe
>      check_ref_format should return "good but ends with meta"
>      only when the refspec consists of all good ref_char
>      followed by "/*" at the end.
> 
> My current preference is the latter.

The latter is probably the way to go for now. But as far as I can tell, 
refs/heads/db-*:refs/heads/* is currently supported, too.

So, for (2), I'd make bad_ref_char only return 2 for '*', and return 1 for 
'?' and '['.

We can let more stuff get through if we make the parser able to parse it.

	-Daniel
*This .sig left intentionally blank*

^ permalink raw reply

* Re: [PATCH] Git.pm: Add remote_refs() git-ls-remote frontend
From: Junio C Hamano @ 2007-05-17  5:58 UTC (permalink / raw)
  To: Petr Baudis; +Cc: git
In-Reply-To: <20070517023743.1982.41240.stgit@rover>

Petr Baudis <pasky@suse.cz> writes:

> .... Too bad that
>
> 	git-ls-remote --heads .
> 	
> is subtly different from
>
> 	git-ls-remote . refs/heads/
>
> so we have to provide the interface for specifying both.

I've already heard you say the above elsewhere, but I am not
sure what you exactly mean here.  Mind substantiating it a bit
more clearly?

I think "ls-remote --heads ." is just a special case of giving
"refs/heads/*" as the glob pattern:

        $ git ls-remote --heads . | head -n 3
        3545193735522f733fdb4e345f16ddf131e2007a	refs/heads/ap/ident
        b7993dd57a9cfd5b989f0e2cc5d271a524339318	refs/heads/db/remote
        960ccca6803c9fb57429d43572a9545a96107e32	refs/heads/dh/pack

	$ git ls-remote . refs/heads/ | wc -l
        0

	$ git ls-remote . "refs/heads/*" | head -n 3
        3545193735522f733fdb4e345f16ddf131e2007a	refs/heads/ap/ident
        b7993dd57a9cfd5b989f0e2cc5d271a524339318	refs/heads/db/remote
        960ccca6803c9fb57429d43572a9545a96107e32	refs/heads/dh/pack

	$ git ls-remote . "refs/heads/???/*"
        7841ce79854868eaaa146c1d018b17fc4f3320be	refs/heads/mst/connect

        $ git ls-remote . "refs/*/jc/*" | head -n 4
        80a767ba3b1c69fc41fa5f5fbe4a247757a9c575	refs/heads/jc/blame
        a1481ab7b16c51d4ec7925fd9b38d9cf21f72263	refs/heads/jc/diff
        4e8daa0dca5deb9d391538241939a2a2ad6d36b8	refs/tags/hold/jc/3way
        ff77ab7919e6f31cb6c58bc004217e624b553fb6	refs/tags/hold/jc/changes

So if you really do not want separate interfaces, I think you
could just implement --heads as what it is: a shorthand for
"refs/heads/*".

^ permalink raw reply

* Re: [3/4] What's not in 1.5.2 (new topics)
From: Andy Parkins @ 2007-05-17  7:51 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano
In-Reply-To: <7v4pmcauu3.fsf@assigned-by-dhcp.cox.net>

On Thursday 2007 May 17, Junio C Hamano wrote:

> I think that depends _WHY_ the URL recorded .gitmodules are
> updated.  It would perfectly be reasonable for release #1 of an
> appliance project to bind linux 2.4 tree at kernel/ subdirectory
> while release #2 source to have 2.6 one; they come from two
> different repository URLs.  When you seek the superproject back
> to release #1, you would still want to fetch from 2.4 upstream
> if you are updating.

That's a very good point; I hadn't considered that there was a case for 
recording a change.

> What I was "handwaving" (or "envisioning") was to have something
> like this in .gitmodules:

Sorry, "handwaving" was a bit rude - I certainly didn't mean that you weren't 
supplying sufficient detail for the circumstance; I meant that in the sense 
of the tricky bits being papered over with user overrides and questions about 
which URL to /really/ use.  The fact that you even felt it necessary to 
mention those overrides signals, I think, that something is wrong.

> 	[subproject "kernel/"]
>         	URL = git://git.kernel.org/pub/linux-2.4.git
>
> (or 2.6, depending on the revision of the superproject) and per
> repository configuration would maps this with these two entries:

So now - running with your example - I'm in a project with a 2.6 URL 
in .gitmodules and config; now I check out a past revision.  .gitmodules is 
updated to show the URL at that time (2.4) - what happens to config, which 
must have higher precedence?  Am I meant to update that myself?  So, as I hop 
around between branches you expect that I will be updating the config file 
for each checkout?

> 	[subproject "git://git.kernel.org/pub/linux-2.4.git"]
>         	URL = http://www.kernel.org/pub/linux-2.4.git
>
> 	[subproject "git://git.kernel.org/pub/linux-2.6.git"]
>         	URL = http://www.kernel.org/pub/linux-2.6.git

Now this part I love.  _That_ is a proper solution.  To me though, these are a 
completely different category from the [subproject] above.  I think that 
should be highlighted with a different section name like "[urlmap]".
     
> The intent is
>
> 	(1) "kernel/" directory is found to be a gitlink in the
>             tree/index; .gitmodules is consulted to find the
>             "URL", which is just a handle and the initial hint

In which case that [subproject "kernel/"] section is not needed (I think it 
would be better to simply say "URL not found for submodule kernel/" or 
something if there is no .gitmodules rather than supplying that override).

> 	(2) That "initial hint" is used to look up the
>             subproject entry from the configuration, to find the
>             "real" URL that is used by this repository

Yes.  Excellent; the "hint" now becomes a lookup key into the url mappings.

> which hopefully is already answered by the above handwaving ;-).

Absolutely.  I'm very impressed.  It solves both the temporal and spatial 
changes problem because one can remap every URL that was ever used in the 
history of the .gitmodules file if one wanted.

> in your .git/config.  After the repository migrates to
> git.sf.net, you would update that existing entry and also add
> another entry, so that .git/config would have these two entries:
>
> 	[subproject "git://git.or.cz/sub.git"]
>         	URL = git://git.sf.net/sub.git
>
> 	[subproject "git://git.sf.net/sub.git"]
>         	URL = git://git.sf.net/sub.git

I don't suppose the second one is needed; wouldn't the default be $key = $url, 
when no override is found?

This also raises the point that these mappings would probably be 
order-dependent; because it may be that I want to do:

  [subproject "git://git.or.cz/sub.git"]
    URL = git://git.sf.net/sub.git

  [subproject "git://git.sf.net/sub.git"]
    URL = /home/andyp/git/mycopyofsub.git

In conclusion: I think that's a first class solution to the problem (and 
probably what you had in mind all along, and me screaming around wasn't 
helpful :-)).



Andy
-- 
Dr Andy Parkins, M Eng (hons), MIET
andyparkins@gmail.com

^ permalink raw reply

* Re: [PATCH] gitweb: Change base font size to "small"
From: Jakub Narebski @ 2007-05-17  8:31 UTC (permalink / raw)
  To: Petr Baudis; +Cc: Junio C Hamano, git, Jan Hudec, David Kågedal
In-Reply-To: <20070517021723.GK4489@pasky.or.cz>

On Thu, 17 May 2007, Petr Baudis wrote:
> On Wed, May 16, 2007 at 12:51:38PM CEST, Jakub Narebski wrote:

>> Proposed-by: Jan Hudec <bulb@ucw.cz>
>> Signed-off-by: Jakub Narebski <jnareb@gmail.com>
> 
> Acked-by: Petr Baudis <pasky@suse.cz>
> 
> just for the record, since it seems to be already applied anyway. By the
> way, I think this commit message is more optimal than what ended up for
> some reason (Jakub wasn't fast enough? ;-) as
> b211c320eb5d753a7a44a03eccb9a15cfbcc563b - especially the subject of
> that commit is really weird.

Second 'gitweb: Do not use absolute font sizes' commit in git.git repo
is from (authordate) Wed May 16 01:59:55 2007 +0200, while this one:
'gitweb: Change base font size to "small"' commit in my repo is from
Wed May 16 12:16:02 2007 +0200

So it looks like my patch without commit message in
  Message-ID: <200705160159.55590.jnareb@gmail.com>
was taken, and commit message was added by Junio, and not ready commit
from this subthread (in message you have replied to, and which you Ack)
  Message-ID: <200705161251.38729.jnareb@gmail.com>

Gah, either I shouldn't have send bare patch, or I have should send
reply that I'm working on commit message for this change.


I have tagged my commit message in git/jnareb-git.git repo as 
gitweb/change-base-font-size:

  http://repo.or.cz/w/git/jnareb-git.git?a=tag;h=gitweb/change-base-font-size

to protect it against rebase + prune.
-- 
Jakub Narebski
Poland

^ permalink raw reply

* Re: [PATCH] gitweb: Add support for grep searches
From: Jakub Narebski @ 2007-05-17  9:00 UTC (permalink / raw)
  To: git
In-Reply-To: <20070517023112.21056.62390.stgit@rover>

Petr Baudis wrote:

> This second revision makes it in documentation explicit that grep accepts
> regexps, and makes grep accept extended regexps instead of basic regexps.

I have thought about adding "[ ] regular expression" (or "Perl
extended regexp", or something like that) checkbox for all searches:
'commit' (message), 'pickaxe' and the new 'grep'.

I have thought also about replaceing pickaxe search pipeline by
  git log --pretty=format:%H -r --no-abbrev --raw -S<search> <hash>
but I'm not sure if pager would be turned off, and of performance
compared to current pipeline:
  git rev-list <hash> | git diff-tree -r --stdin -S<search>

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply

* Re: Smart fetch via HTTP?
From: Johannes Schindelin @ 2007-05-17 10:48 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: Shawn O. Pearce, Martin Langhoff, Jan Hudec, git
In-Reply-To: <alpine.LFD.0.99.0705162309310.24220@xanadu.home>

Hi,

On Wed, 16 May 2007, Nicolas Pitre wrote:

> Still... I wonder if this could be actually workable.  A typical daily 
> update on the Linux kernel repository might consist of a couple hundreds 
> or a few tousands objects.  This could still be faster to fetch parts of 
> a pack than the whole pack if the size difference is above a certain 
> treshold.  It is certainly not worse than fetching loose objects.
> 
> Things would be pretty horrid if you think of fetching a commit object, 
> parsing it to find out what tree object to fetch, then parse that tree 
> object to find out what other objects to fetch, and so on.
> 
> But if you only take the approach of fetching the pack index files, 
> finding out about the objects that the remote has that are not available 
> locally, and then fetching all those objects from within pack files 
> without even looking at them (except for deltas), then it should be 
> possible to issue a couple requests in parallel and possibly have decent 
> performances.  And if it turns out that more than, say, 70% of a 
> particular pack is to be fetched (you can determine that up front), then 
> it might be decided to fetch the whole pack.
> 
> There is no way to sensibly keep those objects packed on the receiving 
> end of course, but storing them as loose objects and repacking them 
> afterwards should be just fine.
> 
> Of course you'll get objects from branches in the remote repository you 
> might not be interested in, but that's a price to pay for such a hack.  
> On average the overhead shouldn't be that big anyway if branches within 
> a repository are somewhat related.
> 
> I think this is something worth experimenting.

I am a bit wary about that, because it is so complex. IMHO a cgi which 
gets, say, up to a hundred refs (maybe something like ref~0, ref~1, ref~2, 
ref~4, ref~8, ref~16, ... for the refs), and then makes a bundle for that 
case on the fly, is easier to do.

Of course, as with all cgi scripts, you have to make sure that DOS attacks 
have a low probability of success.

Ciao,
Dscho

^ permalink raw reply

* Re: [3/4] What's not in 1.5.2 (new topics)
From: Alex Riesen @ 2007-05-17 11:02 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Andy Parkins, git
In-Reply-To: <7v4pmcauu3.fsf@assigned-by-dhcp.cox.net>

Junio C Hamano, Thu, May 17, 2007 07:21:40 +0200:
> What I was "handwaving" (or "envisioning") was to have something
> like this in .gitmodules:
> 
> 	[subproject "kernel/"]
>         	URL = git://git.kernel.org/pub/linux-2.4.git

So, assuming .gitmodules is versioned (afaics, it is), it would mean
that after a some unlucky git-pull, where someone changed the upstream
.gitmodules ("linux-2.4" for whatever reason is changed to just
"linux"). And suddenly all such local configuration is useless:

> (or 2.6, depending on the revision of the superproject) and per
> repository configuration would maps this with these two entries:
> 
> 	[subproject "git://git.kernel.org/pub/linux-2.4.git"]
>         	URL = http://www.kernel.org/pub/linux-2.4.git
>
> 	[subproject "git://git.kernel.org/pub/linux-2.6.git"]

isn't there a typo somewhere around "2.6"?

>         	URL = http://www.kernel.org/pub/linux-2.6.git

because there is no URL to map from.

why can't I just have _repo_ configuration:

 	[subproject "kernel/"]
         	URL = http://www.kernel.org/pub/linux-2.6.git
?
It can be first-time cloned from the upstream, but it stays after
people change it to suit their systems. They can depend on it not to
be broken by upstream.

> The intent is 
> 
> 	(1) "kernel/" directory is found to be a gitlink in the
>             tree/index; .gitmodules is consulted to find the
>             "URL", which is just a handle and the initial hint
> 
> 	(2) That "initial hint" is used to look up the
>             subproject entry from the configuration, to find the
>             "real" URL that is used by this repository

It is quite long-living to be just initial hint. And will be redundant
after the hint loses all meaning (after some time it _will_ happen,
sites do move around), and is just a strange looking mapping key.

Can I suggest a part of repo configuration to be clonable? So that
there is a something in .git/config.dist, which is _cloned_ with
git-clone. The obviuos thing to put there would be subproject
configuration, and maybe there will be something else in the future
(I'd think of description, which is a separate file now, and as for
now, the only way to get this description is to use gitweb or ssh).
git-ls-remote could be made to show this "remote-accessible"
configuration, in case someone have to update/compare local copy of
this config.

^ permalink raw reply

* Re: [PATCH] gitweb: Fix few 'use of undefined value' warnings
From: Petr Baudis @ 2007-05-17 11:25 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vabw4ccy5.fsf@assigned-by-dhcp.cox.net>

On Thu, May 17, 2007 at 06:05:06AM CEST, Junio C Hamano wrote:
> Petr Baudis <pasky@suse.cz> writes:
> 
> > On Fri, Apr 27, 2007 at 06:43:53PM CEST, Petr Baudis wrote:
> >> diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
> >> index b67ce41..b51103e 100755
> >> --- a/gitweb/gitweb.perl
> >> +++ b/gitweb/gitweb.perl
> >> @@ -1057,6 +1058,7 @@ sub git_get_project_description {
> >>  	open my $fd, "$projectroot/$path/description" or return undef;
> >>  	my $descr = <$fd>;
> >>  	close $fd;
> >> +	$descr or return undef;
> >>  	chomp $descr;
> >>  	return $descr;
> >>  }
> >
> > It looks like this hunk has been skipped...?
> 
> It is more like the whole messages was missed, and then 198a2a8a
> and others tried to do the same thing but missed this one.

Oh, aha - I thought that it was applied when you replied "thanks"...

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
Ever try. Ever fail. No matter. // Try again. Fail again. Fail better.
		-- Samuel Beckett

^ permalink raw reply

* Re: Smart fetch via HTTP?
From: Matthieu Moy @ 2007-05-17 11:28 UTC (permalink / raw)
  To: git
In-Reply-To: <Pine.LNX.4.64.0705170152470.6410@racer.site>

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> Hi,
>
> On Thu, 17 May 2007, Martin Langhoff wrote:
>
>> On 5/16/07, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
>> > On Wed, 16 May 2007, Martin Langhoff wrote:
>> > > Do the indexes have enough info to use them with http ranges? It'd be
>> > > chunkier than a smart protocol, but it'd still work with dumb servers.
>> > It would not be really performant, would it? Besides, not all Web servers
>> > speak HTTP/1.1...
>> 
>> Performant compared to downloading a huge packfile to get 10% of it?
>> Sure! It'd probably take a few trips, and you'd end up fetching 20% of
>> the file, still better than 100%.
>
> Don't forget that those 10% probably do not do you the favour to be in 
> large chunks. Chances are that _every_ _single_ wanted object is separate 
> from the others.

FYI, bzr uses HTTP range requests, and the introduction of this
feature lead to significant performance improvement for them (bzr is
more dumb-protocol oriented than git is, so that's really important
there). They have this "index file+data file" system too, so you
download the full index file, and then send an HTTP range request to
get only the relevant parts of the data file.

The thing is, AAUI, they don't send N range requests to get N chunks,
but one HTTP request, requesting the N ranges at a time, and get the N
chunks a a whole (IIRC, a kind of MIME-encoded response from the
server). So, you pay the price of a longer HTTP request, but not the
price of N networks round-trips.

That's surely not as efficient as anything smart on the server, but
might really help for the cases where the server is /not/ smart.

-- 
Matthieu

^ permalink raw reply


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