Git development
 help / color / mirror / Atom feed
* Re: [PATCH] gitweb: Fix "Use of uninitialized value" warning in git_feed
From: Jakub Narebski @ 2007-05-19  2:08 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vtzu937t6.fsf@assigned-by-dhcp.cox.net>

Junio C Hamano wrote:
> Jakub Narebski <jnareb@gmail.com> writes:
> 
>> Initial (root) commit has no parents, and $co{'parent'} is
>> undefined. Use '--root' for initial commit.
>>
>> This fixes "Use of uninitialized value in open at gitweb/gitweb.perl
>> line 4925." warning.
[...]
>> --- a/gitweb/gitweb.perl
>> +++ b/gitweb/gitweb.perl
>> @@ -4923,7 +4923,8 @@ XML
>>  
>>  		# get list of changed files
>>  		open my $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts,
>> -			$co{'parent'}, $co{'id'}, "--", (defined $file_name ? $file_name : ())
>> +			$co{'parent'} || "--root",
>> +			$co{'id'}, "--", (defined $file_name ? $file_name : ())
>>  			or next;
>>  		my @difftree = map { chomp; $_ } <$fd>;
>>  		close $fd
> 
> I do not think you would need to make --root conditional...

I need at last make $co{'parent'} conditional, i.e. at least 
"$co{'parent'} || ()" or equivalent (e.g. like for $file_name).
I cannot omit $co{'parent'} because parents might be rewritten;
feeds accept now path limiting. So why not this way?
-- 
Jakub Narebski
Poland

^ permalink raw reply

* Re: [PATCH] gitweb: Fix "Use of uninitialized value" warning in git_feed
From: Junio C Hamano @ 2007-05-19  1:45 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <1179535671566-git-send-email-jnareb@gmail.com>

Jakub Narebski <jnareb@gmail.com> writes:

> Initial (root) commit has no parents, and $co{'parent'} is
> undefined. Use '--root' for initial commit.
>
> This fixes "Use of uninitialized value in open at gitweb/gitweb.perl
> line 4925." warning.
>
> Signed-off-by: Jakub Narebski <jnareb@gmail.com>
> ---
>  gitweb/gitweb.perl |    3 ++-
>  1 files changed, 2 insertions(+), 1 deletions(-)
>
> diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
> index fa8cc02..091cf9c 100755
> --- a/gitweb/gitweb.perl
> +++ b/gitweb/gitweb.perl
> @@ -4923,7 +4923,8 @@ XML
>  
>  		# get list of changed files
>  		open my $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts,
> -			$co{'parent'}, $co{'id'}, "--", (defined $file_name ? $file_name : ())
> +			$co{'parent'} || "--root",
> +			$co{'id'}, "--", (defined $file_name ? $file_name : ())
>  			or next;
>  		my @difftree = map { chomp; $_ } <$fd>;
>  		close $fd

I do not think you would need to make --root conditional...

^ permalink raw reply

* Re: [3/4] What's not in 1.5.2 (new topics)
From: Steven Grimm @ 2007-05-19  1:02 UTC (permalink / raw)
  To: Andy Parkins
  Cc: git, Josef Weidendorfer, Michael S. Tsirkin, Junio C Hamano,
	Nicolas Pitre
In-Reply-To: <200705180857.18182.andyparkins@gmail.com>

Andy Parkins wrote:
> Bear in mind that what you're suggesting is no different in implementation 
> from what Junio is suggesting but with one difference: in Junio's option 
> the "identifier" will act as a default URL if no override is found.
>   

I don't like using the URL as the key for one simple reason: while it 
technically doesn't conflate the two cases of "I want to use a different 
code base for this subproject starting in version X of the superproject" 
and "I want to use the same code base I've been using all along, but it 
has moved" (in that you can, as you point out, simply map the old URL to 
a new one independent of the project's history) it does encourage people 
to conflate the two in their minds.

Relatively few users will look at an identifier that is a valid URL and 
think of it as anything but a URL, especially if, in the absence of any 
overrides, the software (from the user's perspective) treats it as a 
URL. The override capability is almost certain to remain obscure since 
you won't need to use it in the normal case. Therefore, when the 
submodule's home gets moved to a different host, the first thing a lot 
of people are going to think to do is not to leave the submodule's 
identifier (the original URL) alone and create a mapping config entry, 
but rather to change the submodule to use a brand-new identifier that 
happens to be the same as the new URL. At which point you're right back 
to the original problem of checking out an old version of the 
superproject and having it point to a now-nonexistent subproject.

That's why I suggested making the identifiers look nothing like URLs, 
though of course to the extent they're arbitrary strings, one could use 
a URL if one chose to. I don't object to the *capability* of using a URL 
as an identifier in a three-level scheme like I described -- it would be 
silly to forbid -- but I think it would be a dangerous convention to 
establish because it will eventually encourage people to shoot 
themselves in the foot for lack of knowing what's actually going on.

-Steve

^ permalink raw reply

* Re: [3/4] What's not in 1.5.2 (new topics)
From: Torgil Svensson @ 2007-05-19  0:56 UTC (permalink / raw)
  To: Josef Weidendorfer
  Cc: Petr Baudis, Steven Grimm, Michael S. Tsirkin, Junio C Hamano,
	Andy Parkins, git, Nicolas Pitre
In-Reply-To: <200705181118.17307.Josef.Weidendorfer@gmx.de>

On 5/18/07, Josef Weidendorfer <Josef.Weidendorfer@gmx.de> wrote:
> On Friday 18 May 2007, Petr Baudis wrote:
> So what is the best identifier for a subprobject? It is one that
> probably never clashes with any subproject identifier of another
> superproject. At least, it should not clash between any superprojects
> which ever could be a candidate for merging the two into one.

Put all root-commit SHA1 in a file, call it something like "project
object" and take the SHA1 of that object the identifier. The
SHA1-route has been successful so far as distributed "keys".

//Torgil

^ permalink raw reply

* Re: Smart fetch via HTTP?
From: david @ 2007-05-19  0:50 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Matthieu Moy, git
In-Reply-To: <alpine.LFD.0.98.0705181123590.3890@woody.linux-foundation.org>

On Fri, 18 May 2007, Linus Torvalds wrote:

> On Thu, 17 May 2007, Matthieu Moy wrote:
>>
>> Many (if not most?) of the people working in a big company, I'd say.
>> Year, it sucks, but people having used a paranoid firewall with a
>> not-less-paranoid and broken proxy understand what I mean.
>
> Well, we could try to support the git protocol over port 80..
>
> IOW, it's probably easier to try to get people to use
>
> 	git clone git://some.host:80/project
>
> and just run git-daemon on port 80, than it is to try to set of magic cgi
> scripts etc.
>
> Doing that with virtual hosts etc should be pretty trivial. Much more so
> than trying to make a git-cgi script.
>
> And yes, I do realize that in theory you can have http-aware firewalls
> that expect to see the normal http sequences in the first few packets in
> order to pass things through, but I seriously doubt it's very common.

they are actually more common than you think, and getting even more common 
thanks to IE

when a person browsing a hostile website will allow that website to take 
over the machine the demand is created for 'malware filters' for http, to 
do this the firewalls need to decode the http, and in the process limit 
you to only doing legitimate http.

it's also the case that the companies that have firewalls paranoid enough 
to not let you get to the git port are highly likely to be paranoid enough 
to have a malware filtering http firewall.

David Lang

^ permalink raw reply

* [PATCH] gitweb: Fix "Use of uninitialized value" warning in git_feed
From: Jakub Narebski @ 2007-05-19  0:47 UTC (permalink / raw)
  To: git; +Cc: Jakub Narebski

Initial (root) commit has no parents, and $co{'parent'} is
undefined. Use '--root' for initial commit.

This fixes "Use of uninitialized value in open at gitweb/gitweb.perl
line 4925." warning.

Signed-off-by: Jakub Narebski <jnareb@gmail.com>
---
 gitweb/gitweb.perl |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index fa8cc02..091cf9c 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -4923,7 +4923,8 @@ XML
 
 		# get list of changed files
 		open my $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts,
-			$co{'parent'}, $co{'id'}, "--", (defined $file_name ? $file_name : ())
+			$co{'parent'} || "--root",
+			$co{'id'}, "--", (defined $file_name ? $file_name : ())
 			or next;
 		my @difftree = map { chomp; $_ } <$fd>;
 		close $fd
-- 
1.5.1.4

^ permalink raw reply related

* Re: [PATCH] gitweb: Add support for grep searches
From: Jakub Narebski @ 2007-05-19  0:43 UTC (permalink / raw)
  To: Petr Baudis; +Cc: git, Junio C Hamano
In-Reply-To: <20070518123538.GW4489@pasky.or.cz>

Petr Baudis wrote:
> On Fri, May 18, 2007 at 01:58:28PM CEST, Jakub Narebski wrote:

>> Additionally it would be nice to have links from search results page to
>> have search match highlighted, like search results on GitWiki.

For example 
  http://git.or.cz/gitwiki/SubprojectSupport?highlight=%28Subproject%29
 
> I'm sorry, I don't understand.

For example search results for commit search ('author', 'committer'
and 'commit' searches have link to 'commit' view. Pickaxe has link
to 'commitdiff' view. Grep search would have link(s) to blob views.
In those views the 's' (searchtext) parameter could be passed, and
matched fragment should be somehow higlighted, e.g. using background
color to not interfere with syntax highlighting.

-- 
Jakub Narebski
Poland

^ permalink raw reply

* Re: [PATCH 10/16] git-checkout: pass --submodules option to git-read-tree
From: Petr Baudis @ 2007-05-19  0:36 UTC (permalink / raw)
  To: skimo; +Cc: git, Junio C Hamano
In-Reply-To: <11795163073176-git-send-email-skimo@liacs.nl>

On Fri, May 18, 2007 at 09:24:59PM CEST, skimo@liacs.nl wrote:
> From: Sven Verdoolaege <skimo@kotnet.org>
> 
> Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
> ---
>  git-checkout.sh |   20 +++++++++++++++-----
>  1 files changed, 15 insertions(+), 5 deletions(-)
> 
> diff --git a/git-checkout.sh b/git-checkout.sh
> index 6b6facf..cbb1f00 100755
> --- a/git-checkout.sh
> +++ b/git-checkout.sh
> @@ -1,6 +1,6 @@
>  #!/bin/sh
>  
> -USAGE='[-q] [-f] [-b <new_branch>] [-m] [<branch>] [<paths>...]'
> +USAGE='[-q] [-f] [--submodules] [--no-submodules] [-b <new_branch>] [-m] [<branch>] [<paths>...]'
>  SUBDIRECTORY_OK=Sometimes
>  . git-sh-setup
>  require_work_tree

Thus Documentation/git-checkout.txt needs to be updated as well.

-- 
				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: [PATCH 07/16] git-read-tree: take --submodules option
From: Petr Baudis @ 2007-05-19  0:34 UTC (permalink / raw)
  To: skimo; +Cc: git, Junio C Hamano
In-Reply-To: <11795163061588-git-send-email-skimo@liacs.nl>

On Fri, May 18, 2007 at 09:24:56PM CEST, skimo@liacs.nl wrote:
> From: Sven Verdoolaege <skimo@kotnet.org>
> 
> This option currently has no effect.
> 
> Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>

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

Please do not add more undocumented parameters - include documentation
in the patch adding the parameter.

-- 
				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] gitweb: Add test t9500 for gitweb (as standalone script)
From: Jakub Narebski @ 2007-05-19  0:19 UTC (permalink / raw)
  To: git; +Cc: Jakub Narebski

This test runs gitweb (git web interface) as CGI script from
commandline, and checks that it would not write any errors
or warnings to log.

Signed-off-by: Jakub Narebski <jnareb@gmail.com>
---
This is test I have used to find errors and warnings fixed in the
late 'Fix "Use of uninitialized value" warning ...' series.

It is not perfect, it does not offer full coverage, and tests
only if there are no errors or warning not checking the output,
not even HTTP code, but it helps.

 t/t9500-gitweb-standalone-no-errors.sh |  490 ++++++++++++++++++++++++++++++++
 1 files changed, 490 insertions(+), 0 deletions(-)
 create mode 100755 t/t9500-gitweb-standalone-no-errors.sh

diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh
new file mode 100755
index 0000000..b92ab63
--- /dev/null
+++ b/t/t9500-gitweb-standalone-no-errors.sh
@@ -0,0 +1,490 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Jakub Narebski
+#
+
+test_description='gitweb as standalone script (basic tests).
+
+This test runs gitweb (git web interface) as CGI script from
+commandline, and checks that it would not write any errors
+or warnings to log.'
+
+gitweb_init () {
+	cat >gitweb_config.perl <<EOF
+#!/usr/bin/perl
+
+# gitweb configuration for tests
+
+our \$version = "current";
+our \$GIT = "git";
+our \$projectroot = "$(pwd)";
+our \$home_link_str = "projects";
+our \$site_name = "[localhost]";
+our \$site_header = "";
+our \$site_footer = "";
+our \$home_text = "indextext.html";
+our @stylesheets = ("file:///$(pwd)/../../gitweb/gitweb.css");
+our \$logo = "file:///$(pwd)/../../gitweb/git-logo.png";
+our \$favicon = "file:///$(pwd)/../../gitweb/git-favicon.png";
+our \$projects_list = "";
+our \$export_ok = "";
+our \$strict_export = "";
+
+CGI::Carp::set_programname("gitweb/gitweb.cgi");
+EOF
+
+	cat >.git/description <<EOF
+$0 test repository
+EOF
+}
+
+gitweb_run () {
+	export GATEWAY_INTERFACE="CGI/1.1"
+	export HTTP_ACCEPT="*/*"
+	export REQUEST_METHOD="GET"
+	export QUERY_STRING=""$1""
+	export PATH_INFO=""$2""
+
+	export GITWEB_CONFIG=$(pwd)/gitweb_config.perl
+
+	# some of git commands write to STDERR on error, but this is not
+	# written to web server logs, so we are not interested in that:
+	# we are interested only in properly formatted errors/warnings
+	rm -f gitweb.log &&
+	perl -- $(pwd)/../../gitweb/gitweb.perl \
+		>/dev/null 2>gitweb.log &&
+	if grep -q -s "^[[]" gitweb.log >/dev/null; then false; else true; fi
+
+	# gitweb.log is left for debugging
+}
+
+. ./test-lib.sh
+
+gitweb_init
+
+# ----------------------------------------------------------------------
+# no commits (empty, just initialized repository)
+
+test_expect_success \
+	'no commits: projects_list (implicit)' \
+	'gitweb_run'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'no commits: projects_index' \
+	'gitweb_run "a=project_index"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'no commits: .git summary (implicit)' \
+	'gitweb_run "p=.git"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'no commits: .git commit (implicit HEAD)' \
+	'gitweb_run "p=.git;a=commit"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'no commits: .git commitdiff (implicit HEAD)' \
+	'gitweb_run "p=.git;a=commitdiff"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'no commits: .git tree (implicit HEAD)' \
+	'gitweb_run "p=.git;a=tree"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'no commits: .git heads' \
+	'gitweb_run "p=.git;a=heads"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'no commits: .git tags' \
+	'gitweb_run "p=.git;a=tags"'
+test_debug 'cat gitweb.log'
+
+
+# ----------------------------------------------------------------------
+# initial commit
+
+test_expect_success \
+	'Make initial commit' \
+	'echo "Not an empty file." > file &&
+	 git add file &&
+	 git commit -a -m "Initial commit." &&
+	 git branch b'
+
+test_expect_success \
+	'projects_list (implicit)' \
+	'gitweb_run'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'projects_index' \
+	'gitweb_run "a=project_index"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'.git summary (implicit)' \
+	'gitweb_run "p=.git"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'.git commit (implicit HEAD)' \
+	'gitweb_run "p=.git;a=commit"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'.git commitdiff (implicit HEAD, root commit)' \
+	'gitweb_run "p=.git;a=commitdiff"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'.git commitdiff_plain (implicit HEAD, root commit)' \
+	'gitweb_run "p=.git;a=commitdiff_plain"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'.git commit (HEAD)' \
+	'gitweb_run "p=.git;a=commit;h=HEAD"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'.git tree (implicit HEAD)' \
+	'gitweb_run "p=.git;a=tree"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'.git blob (file)' \
+	'gitweb_run "p=.git;a=blob;f=file"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'.git blob_plain (file)' \
+	'gitweb_run "p=.git;a=blob_plain;f=file"'
+test_debug 'cat gitweb.log'
+
+# ----------------------------------------------------------------------
+# nonexistent objects
+
+test_expect_success \
+	'.git commit (non-existent)' \
+	'gitweb_run "p=.git;a=commit;h=non-existent"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'.git commitdiff (non-existent)' \
+	'gitweb_run "p=.git;a=commitdiff;h=non-existent"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'.git commitdiff (non-existent vs HEAD)' \
+	'gitweb_run "p=.git;a=commitdiff;hp=non-existent;h=HEAD"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'.git tree (0000000000000000000000000000000000000000)' \
+	'gitweb_run "p=.git;a=tree;h=0000000000000000000000000000000000000000"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'.git tag (0000000000000000000000000000000000000000)' \
+	'gitweb_run "p=.git;a=tag;h=0000000000000000000000000000000000000000"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'.git blob (non-existent)' \
+	'gitweb_run "p=.git;a=blob;f=non-existent"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'.git blob_plain (non-existent)' \
+	'gitweb_run "p=.git;a=blob_plain;f=non-existent"'
+test_debug 'cat gitweb.log'
+
+
+# ----------------------------------------------------------------------
+# commitdiff testing (implicit, one implicit tree-ish)
+
+test_expect_success \
+	'commitdiff(0): root' \
+	'gitweb_run "p=.git;a=commitdiff"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'commitdiff(0): file added' \
+	'echo "New file" > new_file &&
+	 git add new_file &&
+	 git commit -a -m "File added." &&
+	 gitweb_run "p=.git;a=commitdiff"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'commitdiff(0): mode change' \
+	'chmod a+x new_file &&
+	 git commit -a -m "Mode changed." &&
+	 gitweb_run "p=.git;a=commitdiff"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'commitdiff(0): file renamed' \
+	'git mv new_file renamed_file &&
+	 git commit -a -m "File renamed." &&
+	 gitweb_run "p=.git;a=commitdiff"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'commitdiff(0): file to symlink' \
+	'rm renamed_file &&
+	 ln -s file renamed_file &&
+	 git commit -a -m "File to symlink." &&
+	 gitweb_run "p=.git;a=commitdiff"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'commitdiff(0): file deleted' \
+	'git rm renamed_file &&
+	 rm -f renamed_file &&
+	 git commit -a -m "File removed." &&
+	 gitweb_run "p=.git;a=commitdiff"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'commitdiff(0): file copied / new file' \
+	'cp file file2 &&
+	 git add file2 &&
+	 git commit -a -m "File copied." &&
+	 gitweb_run "p=.git;a=commitdiff"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'commitdiff(0): mode change and modified' \
+	'echo "New line" >> file2 &&
+	 chmod a+x file2 &&
+	 git commit -a -m "Mode change and modification." &&
+	 gitweb_run "p=.git;a=commitdiff"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'commitdiff(0): renamed and modified' \
+	'cat >file2<<EOF &&
+Dominus regit me,
+et nihil mihi deerit.
+In loco pascuae ibi me collocavit,
+super aquam refectionis educavit me;
+animam meam convertit,
+deduxit me super semitas jusitiae,
+propter nomen suum.
+EOF
+	 git commit -a -m "File added." &&
+	 git mv file2 file3 &&
+	 echo "Propter nomen suum." >> file3 &&
+	 git commit -a -m "File rename and modification." &&
+	 gitweb_run "p=.git;a=commitdiff"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'commitdiff(0): renamed, mode change and modified' \
+	'git mv file3 file2 &&
+	 echo "Propter nomen suum." >> file2 &&
+	 chmod a+x file2 &&
+	 git commit -a -m "File rename, mode change and modification." &&
+	 gitweb_run "p=.git;a=commitdiff"'
+test_debug 'cat gitweb.log'
+
+# ----------------------------------------------------------------------
+# commitdiff testing (taken from t4114-apply-typechange.sh)
+
+test_expect_success 'setup typechange commits' '
+	echo "hello world" > foo &&
+	echo "hi planet" > bar &&
+	git update-index --add foo bar &&
+	git commit -m initial &&
+	git branch initial &&
+	rm -f foo &&
+	ln -s bar foo &&
+	git update-index foo &&
+	git commit -m "foo symlinked to bar" &&
+	git branch foo-symlinked-to-bar &&
+	rm -f foo &&
+	echo "how far is the sun?" > foo &&
+	git update-index foo &&
+	git commit -m "foo back to file" &&
+	git branch foo-back-to-file &&
+	rm -f foo &&
+	git update-index --remove foo &&
+	mkdir foo &&
+	echo "if only I knew" > foo/baz &&
+	git update-index --add foo/baz &&
+	git commit -m "foo becomes a directory" &&
+	git branch "foo-becomes-a-directory" &&
+	echo "hello world" > foo/baz &&
+	git update-index foo/baz &&
+	git commit -m "foo/baz is the original foo" &&
+	git branch foo-baz-renamed-from-foo
+	'
+
+test_expect_success \
+	'commitdiff(2): file renamed from foo to foo/baz' \
+	'gitweb_run "p=.git;a=commitdiff;hp=initial;h=foo-baz-renamed-from-foo"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'commitdiff(2): file renamed from foo/baz to foo' \
+	'gitweb_run "p=.git;a=commitdiff;hp=foo-baz-renamed-from-foo;h=initial"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'commitdiff(2): directory becomes file' \
+	'gitweb_run "p=.git;a=commitdiff;hp=foo-becomes-a-directory;h=initial"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'commitdiff(2): file becomes directory' \
+	'gitweb_run "p=.git;a=commitdiff;hp=initial;h=foo-becomes-a-directory"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'commitdiff(2): file becomes symlink' \
+	'gitweb_run "p=.git;a=commitdiff;hp=initial;h=foo-symlinked-to-bar"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'commitdiff(2): symlink becomes file' \
+	'gitweb_run "p=.git;a=commitdiff;hp=foo-symlinked-to-bar;h=foo-back-to-file"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'commitdiff(2): symlink becomes directory' \
+	'gitweb_run "p=.git;a=commitdiff;hp=foo-symlinked-to-bar;h=foo-becomes-a-directory"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'commitdiff(2): directory becomes symlink' \
+	'gitweb_run "p=.git;a=commitdiff;hp=foo-becomes-a-directory;h=foo-symlinked-to-bar"'
+test_debug 'cat gitweb.log'
+
+# ----------------------------------------------------------------------
+# commit, commitdiff: merge, large
+test_expect_success \
+	'Create a merge' \
+	'git checkout b &&
+	 echo "Branch" >> b &&
+	 git add b &&
+	 git commit -a -m "On branch" &&
+	 git checkout master &&
+	 git pull . b'
+
+test_expect_success \
+	'commit(0): merge commit' \
+	'gitweb_run "p=.git;a=commit"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'commitdiff(0): merge commit' \
+	'gitweb_run "p=.git;a=commitdiff"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'Prepare large commit' \
+	'git checkout b &&
+	 echo "To be changed" > 01-change &&
+	 echo "To be renamed" > 02-pure-rename-from &&
+	 echo "To be deleted" > 03-delete &&
+	 echo "To be renamed and changed" > 04-rename-from &&
+	 echo "To have mode changed" > 05-mode-change &&
+	 echo "File to symlink" > 06-file-or-symlink &&
+	 echo "To be changed and have mode changed" > 07-change-mode-change	&&
+	 git add 0* &&
+	 git commit -a -m "Prepare large commit" &&
+	 echo "Changed" > 01-change &&
+	 git mv 02-pure-rename-from 02-pure-rename-to &&
+	 git rm 03-delete && rm -f 03-delete &&
+	 echo "A new file" > 03-new &&
+	 git add 03-new &&
+	 git mv 04-rename-from 04-rename-to &&
+	 echo "Changed" >> 04-rename-to &&
+	 chmod a+x 05-mode-change &&
+	 rm -f 06-file-or-symlink && ln -s 01-change 06-file-or-symlink &&
+	 echo "Changed and have mode changed" > 07-change-mode-change	&&
+	 chmod a+x 07-change-mode-change &&
+	 git commit -a -m "Large commit" &&
+	 git checkout master'
+
+test_expect_success \
+	'commit(1): large commit' \
+	'gitweb_run "p=.git;a=commit;h=b"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'commitdiff(1): large commit' \
+	'gitweb_run "p=.git;a=commitdiff;h=b"'
+test_debug 'cat gitweb.log'
+
+# ----------------------------------------------------------------------
+# tags testing
+
+test_expect_success \
+	'tags: list of different types of tags' \
+	'git checkout master &&
+	 git tag -a -m "Tag commit object" tag-commit HEAD &&
+	 git tag -a -m "" tag-commit-nomessage HEAD &&
+	 git tag -a -m "Tag tag object" tag-tag tag-commit &&
+	 git tag -a -m "Tag tree object" tag-tree HEAD^{tree} &&
+	 git tag -a -m "Tag blob object" tag-blob HEAD:file &&
+	 git tag lightweight/tag-commit HEAD &&
+	 git tag lightweight/tag-tag tag-commit &&
+	 git tag lightweight/tag-tree HEAD^{tree} &&
+	 git tag lightweight/tag-blob HEAD:file &&
+	 gitweb_run "p=.git;a=tags"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'tag: Tag to commit object' \
+	'gitweb_run "p=.git;a=tag;h=tag-commit"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'tag: on lightweight tag (invalid)' \
+	'gitweb_run "p=.git;a=tag;h=lightweight/tag-commit"'
+test_debug 'cat gitweb.log'
+
+# ----------------------------------------------------------------------
+# logs
+
+test_expect_success \
+	'logs: log (implicit HEAD)' \
+	'gitweb_run "p=.git;a=log"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'logs: shortlog (implicit HEAD)' \
+	'gitweb_run "p=.git;a=shortlog"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'logs: history (implicit HEAD, file)' \
+	'gitweb_run "p=.git;a=history;f=file"'
+test_debug 'cat gitweb.log'
+
+# ----------------------------------------------------------------------
+# feed generation
+
+test_expect_success \
+	'feeds: OPML' \
+	'gitweb_run "a=opml"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'feed: RSS' \
+	'gitweb_run "p=.git;a=rss"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+	'feed: Atom' \
+	'gitweb_run "p=.git;a=atom"'
+test_debug 'cat gitweb.log'
+
+test_done
-- 
1.5.1.4

^ permalink raw reply related

* Re: [PATCH] gitweb: Extra columns in blame
From: Junio C Hamano @ 2007-05-19  0:18 UTC (permalink / raw)
  To: Petr Baudis; +Cc: git
In-Reply-To: <20070518221916.GZ4489@pasky.or.cz>

Petr Baudis <pasky@suse.cz> writes:

>> Also the incremental thing using JavaScript does not seem to
>> work for me incrementally for some reason, although if I wait
>> long enough I get the fully blamed picture that seems to match
>> nonincremental one.  While I am waiting, the browser goes silent
>> and does not even let me switch to other tabs, so it is not all
>> that useful to me in its current shape.
>
> Strange, what browser are you using?

Firefox (I think it is 2.0) running on a W2k box behind two http
proxies.

^ permalink raw reply

* [PATCH 3/3] gitweb: Clearly distinguish regexp / exact match searches
From: Petr Baudis @ 2007-05-19  0:13 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Jakub Narebski, Petr Baudis
In-Reply-To: <20070519001329.28618.31334.stgit@rover>

This patch does a couple of things:

* Makes commit/author/committer search case insensitive

	To be consistent with the grep search; I see no convincing
	reason for the search to be case sensitive, and you might
	get in trouble especially with contributors e.g. from Japan
	or France where they sometimes like to uppercase their last
	name.

* Makes grep search by default grep for fixed strings

	Since we will have a checkbox.

* Introduces 're' checkbox that enables POSIX extended regexp searches

	This works for all the search types. The idea comes from Jakub.

It does not make much sense (and is not easy at all) to untangle most of
these changes from each other, thus they all go in a single patch.

Cc: Jakub Narebski <jnareb@gmail.com>
Signed-off-by: Petr Baudis <pasky@suse.cz>
---

 gitweb/gitweb.perl |   50 +++++++++++++++++++++++++++++++++-----------------
 1 files changed, 33 insertions(+), 17 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 4ccb4e3..846392e 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -401,13 +401,15 @@ if (defined $searchtype) {
 	}
 }
 
+our $search_use_regexp = $cgi->param('sr');
+
 our $searchtext = $cgi->param('s');
 our $search_regexp;
 if (defined $searchtext) {
 	if (length($searchtext) < 2) {
 		die_error(undef, "At least two characters are required for search parameter");
 	}
-	$search_regexp = quotemeta $searchtext;
+	$search_regexp = $search_use_regexp ? $searchtext : quotemeta $searchtext;
 }
 
 # now read PATH_INFO and use it as alternative to parameters
@@ -535,6 +537,7 @@ sub href(%) {
 		order => "o",
 		searchtext => "s",
 		searchtype => "st",
+		search_use_regexp => "sr",
 	);
 	my %mapping = @mapping;
 
@@ -1579,7 +1582,7 @@ sub parse_commit {
 }
 
 sub parse_commits {
-	my ($commit_id, $maxcount, $skip, $arg, $filename) = @_;
+	my ($commit_id, $maxcount, $skip, $filename, @args) = @_;
 	my @cos;
 
 	$maxcount ||= 1;
@@ -1589,7 +1592,7 @@ sub parse_commits {
 
 	open my $fd, "-|", git_cmd(), "rev-list",
 		"--header",
-		($arg ? ($arg) : ()),
+		@args,
 		("--max-count=" . $maxcount),
 		("--skip=" . $skip),
 		$commit_id,
@@ -2007,6 +2010,9 @@ EOF
 		      $cgi->sup($cgi->a({-href => href(action=>"search_help")}, "?")) .
 		      " search:\n",
 		      $cgi->textfield(-name => "s", -value => $searchtext) . "\n" .
+		      "<span title=\"Extended regular expression\">" .
+		      $cgi->checkbox(-name => 'sr', -value => 1, -checked => $search_use_regexp, -label => 're') .
+		      "</span>" .
 		      "</div>" .
 		      $cgi->end_form() . "\n";
 	}
@@ -4655,7 +4661,7 @@ sub git_history {
 		$ftype = git_get_type($hash);
 	}
 
-	my @commitlist = parse_commits($hash_base, 101, (100 * $page), "--full-history", $file_name);
+	my @commitlist = parse_commits($hash_base, 101, (100 * $page), $file_name, "--full-history");
 
 	my $paging_nav = '';
 	if ($page > 0) {
@@ -4745,7 +4751,9 @@ sub git_search {
 			$greptype = "--committer=";
 		}
 		$greptype .= $search_regexp;
-		my @commitlist = parse_commits($hash, 101, (100 * $page), $greptype);
+		my @commitlist = parse_commits($hash, 101, (100 * $page), undef,
+		                               $greptype, $search_use_regexp ? ('--extended-regexp') : (),
+					       '--regexp-ignore-case');
 
 		my $paging_nav = '';
 		if ($page > 0) {
@@ -4795,8 +4803,9 @@ sub git_search {
 		my $git_command = git_cmd_str();
 		my $searchqtext = $searchtext;
 		$searchqtext =~ s/'/'\\''/;
+		my $pickaxe_flags = $search_use_regexp ? '--pickaxe-regex' : '';
 		open my $fd, "-|", "$git_command rev-list $hash | " .
-			"$git_command diff-tree -r --stdin -S\'$searchqtext\'";
+			"$git_command diff-tree -r --stdin -S\'$searchqtext\' $pickaxe_flags";
 		undef %co;
 		my @files;
 		while (my $line = <$fd>) {
@@ -4859,7 +4868,9 @@ sub git_search {
 		my $alternate = 1;
 		my $matches = 0;
 		$/ = "\n";
-		open my $fd, "-|", git_cmd(), 'grep', '-n', '-i', '-E', $searchtext, $co{'tree'};
+		open my $fd, "-|", git_cmd(), 'grep', '-n',
+			$search_use_regexp ? ('-E', '-i') : '-F',
+			$searchtext, $co{'tree'};
 		my $lastfile = '';
 		while (my $line = <$fd>) {
 			chomp $line;
@@ -4889,7 +4900,7 @@ sub git_search {
 				print "<div class=\"binary\">Binary file</div>\n";
 			} else {
 				$ltext = untabify($ltext);
-				if ($ltext =~ m/^(.*)($searchtext)(.*)$/i) {
+				if ($ltext =~ m/^(.*)($search_regexp)(.*)$/i) {
 					$ltext = esc_html($1, -nbsp=>1);
 					$ltext .= '<span class="match">';
 					$ltext .= esc_html($2, -nbsp=>1);
@@ -4924,27 +4935,31 @@ sub git_search_help {
 	git_header_html();
 	git_print_page_nav('','', $hash,$hash,$hash);
 	print <<EOT;
+<p><strong>Pattern</strong> is by default a normal string that is matched precisely (but without
+regard to case, except in the case of pickaxe). However, when you check the <em>re</em> checkbox,
+the pattern entered is recognized as the POSIX extended
+<a href="http://en.wikipedia.org/wiki/Regular_expression">regular expression</a> (also case
+insensitive).</p>
 <dl>
 <dt><b>commit</b></dt>
-<dd>The commit messages and authorship information will be scanned for the given string.</dd>
+<dd>The commit messages and authorship information will be scanned for the given pattern.</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>
+    a different one) are searched for the given pattern. On large trees, this search can take
+a while and put some strain on the server, so please use it with some consideration. Note that
+due to git-grep peculiarity, currently if regexp mode is turned off, the matches are
+case-sensitive.</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>
+<dd>Name and e-mail of the change author and date of birth of the patch will be scanned for the given pattern.</dd>
 <dt><b>committer</b></dt>
-<dd>Name and e-mail of the committer and date of commit will be scanned for the given string.</dd>
+<dd>Name and e-mail of the committer and date of commit will be scanned for the given pattern.</dd>
 EOT
 	my ($have_pickaxe) = gitweb_check_feature('pickaxe');
 	if ($have_pickaxe) {
@@ -4952,7 +4967,8 @@ EOT
 <dt><b>pickaxe</b></dt>
 <dd>All commits that caused the string to appear or disappear from any file (changes that
 added, removed or "modified" the string) will be listed. This search can take a while and
-takes a lot of strain on the server, so please use it wisely.</dd>
+takes a lot of strain on the server, so please use it wisely. Note that since you may be
+interested even in changes just changing the case as well, this search is case sensitive.</dd>
 EOT
 	}
 	print "</dl>\n";

^ permalink raw reply related

* [PATCH 2/3] gitweb: Lift any characters restriction on searched strings
From: Petr Baudis @ 2007-05-19  0:13 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Petr Baudis
In-Reply-To: <20070519001329.28618.31334.stgit@rover>

Everything is already fully quoted along the way so I believe this to be
unnecessary at this point. It would pose trouble for regexp searches.

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

 gitweb/gitweb.perl |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 0143183..4ccb4e3 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -404,9 +404,6 @@ if (defined $searchtype) {
 our $searchtext = $cgi->param('s');
 our $search_regexp;
 if (defined $searchtext) {
-	if ($searchtype ne 'grep' and $searchtype ne 'pickaxe' and $searchtext =~ m/[^a-zA-Z0-9_\.\/\-\+\:\@ ]/) {
-		die_error(undef, "Invalid search parameter");
-	}
 	if (length($searchtext) < 2) {
 		die_error(undef, "At least two characters are required for search parameter");
 	}

^ permalink raw reply related

* [PATCH 1/3] git-rev-list: Add regexp tuning options
From: Petr Baudis @ 2007-05-19  0:13 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Petr Baudis

This patch introduces --extended-regexp and --regexp-ignore-case options to
tune what kind of patterns the pattern-limiting options (--grep, --author,
...) accept.

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

 Documentation/git-rev-list.txt |   10 ++++++++++
 revision.c                     |   12 ++++++++++++
 2 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt
index c3c2043..0dba73f 100644
--- a/Documentation/git-rev-list.txt
+++ b/Documentation/git-rev-list.txt
@@ -25,6 +25,7 @@ SYNOPSIS
 	     [ \--cherry-pick ]
 	     [ \--encoding[=<encoding>] ]
 	     [ \--(author|committer|grep)=<pattern> ]
+	     [ \--regexp-ignore-case ] [ \--extended-regexp ]
 	     [ \--date={local|relative|default} ]
 	     [ [\--objects | \--objects-edge] [ \--unpacked ] ]
 	     [ \--pretty | \--header ]
@@ -214,6 +215,15 @@ limiting may be applied.
 	Limit the commits output to ones with log message that
 	matches the specified pattern (regular expression).
 
+--regexp-ignore-case::
+
+	Match the regexp limiting patterns without regard to letters case.
+
+--extended-regexp::
+
+	Consider the limiting patterns to be extended regular expressions
+	instead of the default basic regular expressions.
+
 --remove-empty::
 
 	Stop when a given path disappears from the tree.
diff --git a/revision.c b/revision.c
index 0125d41..0a29b53 100644
--- a/revision.c
+++ b/revision.c
@@ -881,6 +881,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
 	const char **unrecognized = argv + 1;
 	int left = 1;
 	int all_match = 0;
+	int regflags = 0;
 
 	/* First, search for "--" */
 	seen_dashdash = 0;
@@ -1152,6 +1153,14 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
 				add_message_grep(revs, arg+7);
 				continue;
 			}
+			if (!prefixcmp(arg, "--extended-regexp")) {
+				regflags |= REG_EXTENDED;
+				continue;
+			}
+			if (!prefixcmp(arg, "--regexp-ignore-case")) {
+				regflags |= REG_ICASE;
+				continue;
+			}
 			if (!strcmp(arg, "--all-match")) {
 				all_match = 1;
 				continue;
@@ -1200,6 +1209,9 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
 		}
 	}
 
+	if (revs->grep_filter)
+		revs->grep_filter->regflags |= regflags;
+
 	if (show_merge)
 		prepare_show_merge(revs);
 	if (def && !revs->pending.nr) {

^ permalink raw reply related

* [StGIT PATCH 5/5] Add --binary flag to commands that generate diffs
From: Karl Hasselström @ 2007-05-19  0:10 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: git
In-Reply-To: <20070519000451.4906.87089.stgit@yoghurt>

This just passes the --binary option to git-diff-*, which causes the
generated diffs to contain an applyable diff even when binary files
differ. It's necessary to do this if you want to mail patches to
binary files.

Signed-off-by: Karl Hasselström <kha@treskal.com>
---

 stgit/commands/diff.py   |    6 +++++-
 stgit/commands/export.py |    5 ++++-
 stgit/commands/mail.py   |    6 +++++-
 stgit/git.py             |   16 ++++++++++++----
 4 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/stgit/commands/diff.py b/stgit/commands/diff.py
index 8678a0a..d3e1190 100644
--- a/stgit/commands/diff.py
+++ b/stgit/commands/diff.py
@@ -44,6 +44,9 @@ shows the specified patch (defaulting to the current one)."""
 options = [make_option('-r', '--range',
                        metavar = 'rev1[..[rev2]]', dest = 'revs',
                        help = 'show the diff between revisions'),
+           make_option('--binary',
+                       help = 'output a diff even for binary files',
+                       action = 'store_true'),
            make_option('-s', '--stat',
                        help = 'show the stat instead of the diff',
                        action = 'store_true')]
@@ -79,6 +82,7 @@ def func(parser, options, args):
     if options.stat:
         print git.diffstat(args, git_id(rev1), git_id(rev2))
     else:
-        diff_str = git.diff(args, git_id(rev1), git_id(rev2))
+        diff_str = git.diff(args, git_id(rev1), git_id(rev2),
+                            binary = options.binary)
         if diff_str:
             pager(diff_str)
diff --git a/stgit/commands/export.py b/stgit/commands/export.py
index 79b8630..20d8f67 100644
--- a/stgit/commands/export.py
+++ b/stgit/commands/export.py
@@ -62,6 +62,9 @@ options = [make_option('-d', '--dir',
                        help = 'Use FILE as a template'),
            make_option('-b', '--branch',
                        help = 'use BRANCH instead of the default one'),
+           make_option('--binary',
+                       help = 'output a diff even for binary files',
+                       action = 'store_true'),
            make_option('-s', '--stdout',
                        help = 'dump the patches to the standard output',
                        action = 'store_true')]
@@ -172,7 +175,7 @@ def func(parser, options, args):
         # write the diff
         git.diff(rev1 = patch.get_bottom(),
                  rev2 = patch.get_top(),
-                 out_fd = f)
+                 out_fd = f, binary = options.binary)
         if not options.stdout:
             f.close()
         patch_no += 1
diff --git a/stgit/commands/mail.py b/stgit/commands/mail.py
index 151a408..2fcaa5f 100644
--- a/stgit/commands/mail.py
+++ b/stgit/commands/mail.py
@@ -120,6 +120,9 @@ options = [make_option('-a', '--all',
                        help = 'username for SMTP authentication'),
            make_option('-b', '--branch',
                        help = 'use BRANCH instead of the default one'),
+           make_option('--binary',
+                       help = 'output a diff even for binary files',
+                       action = 'store_true'),
            make_option('-m', '--mbox',
                        help = 'generate an mbox file instead of sending',
                        action = 'store_true')]
@@ -390,7 +393,8 @@ def __build_message(tmpl, patch, patch_nr, total_nr, msg_id, ref_id, options):
                  # for backward template compatibility
                  'endofheaders': '',
                  'diff':         git.diff(rev1 = git_id('%s//bottom' % patch),
-                                          rev2 = git_id('%s//top' % patch)),
+                                          rev2 = git_id('%s//top' % patch),
+                                          binary = options.binary),
                  'diffstat':     git.diffstat(rev1 = git_id('%s//bottom'%patch),
                                               rev2 = git_id('%s//top' % patch)),
                  # for backward template compatibility
diff --git a/stgit/git.py b/stgit/git.py
index 837f927..86630ce 100644
--- a/stgit/git.py
+++ b/stgit/git.py
@@ -771,20 +771,28 @@ def status(files = None, modified = False, new = False, deleted = False,
         else:
             print '%s' % fs[1]
 
-def diff(files = None, rev1 = 'HEAD', rev2 = None, out_fd = None):
+def diff(files = None, rev1 = 'HEAD', rev2 = None, out_fd = None,
+         binary = False):
     """Show the diff between rev1 and rev2
     """
     if not files:
         files = []
 
+    args = []
+    if binary:
+        args.append('--binary')
+
     if rev1 and rev2:
-        diff_str = _output(['git-diff-tree', '-p', rev1, rev2, '--'] + files)
+        diff_str = _output(['git-diff-tree', '-p'] + args
+                           + [rev1, rev2, '--'] + files)
     elif rev1 or rev2:
         refresh_index()
         if rev2:
-            diff_str = _output(['git-diff-index', '-p', '-R', rev2, '--'] + files)
+            diff_str = _output(['git-diff-index', '-p', '-R']
+                               + args + [rev2, '--'] + files)
         else:
-            diff_str = _output(['git-diff-index', '-p', rev1, '--'] + files)
+            diff_str = _output(['git-diff-index', '-p']
+                               + args + [rev1, '--'] + files)
     else:
         diff_str = ''
 

^ permalink raw reply related

* [StGIT PATCH 4/5] Test the format version upgrade code
From: Karl Hasselström @ 2007-05-19  0:10 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: git
In-Reply-To: <20070519000451.4906.87089.stgit@yoghurt>

This test contains tarballs of repositories created with older
versions of StGIT. It also contains the script used to generate them,
but at some point we will lose the ability to easily run old versions
-- for example, if git changes incompatibly -- so tarballs will be the
only practical option for sufficiently old versions.

Signed-off-by: Karl Hasselström <kha@treskal.com>
---

 t/t4000-upgrade.sh           |   40 ++++++++++++++++++++++++
 t/t4000-upgrade/.gitignore   |    4 ++
 t/t4000-upgrade/0.12.tar.gz  |  Bin
 t/t4000-upgrade/0.8.tar.gz   |  Bin
 t/t4000-upgrade/make-repo.sh |   71 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 115 insertions(+), 0 deletions(-)

diff --git a/t/t4000-upgrade.sh b/t/t4000-upgrade.sh
new file mode 100755
index 0000000..8a308fb
--- /dev/null
+++ b/t/t4000-upgrade.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Karl Hasselström
+#
+
+test_description='Make sure that we can use old StGIT repositories'
+
+. ./test-lib.sh
+
+for ver in 0.12 0.8; do
+
+    tar zxf ../t4000-upgrade/$ver.tar.gz
+    cd $ver
+
+    test_expect_success \
+        "v$ver: Check the list of applied and unapplied patches" '
+        [ "$(echo $(stg applied))" = "p0 p1 p2" ] &&
+        [ "$(echo $(stg unapplied))" = "p3 p4" ]
+    '
+
+    test_expect_success \
+        "v$ver: Make sure the 'description' file is no longer there" '
+        [ ! -e .git/patches/master/description ] &&
+        [ "$(echo $(git config branch.master.description))" = "cool branch" ]
+    '
+
+    test_expect_success \
+        "v$ver: Make sure the 'current' file is no longer there" '
+        [ ! -e .git/patches/master/current ]
+    '
+
+    test_expect_success \
+        "v$ver: Make sure the base ref is no longer there" '
+        ! git show-ref --verify --quiet refs/bases/master
+    '
+
+    cd ..
+done
+
+test_done
diff --git a/t/t4000-upgrade/.gitignore b/t/t4000-upgrade/.gitignore
new file mode 100644
index 0000000..d412eb6
--- /dev/null
+++ b/t/t4000-upgrade/.gitignore
@@ -0,0 +1,4 @@
+/stgit-0.8
+/stgit-0.12
+/0.8
+/0.12
diff --git a/t/t4000-upgrade/0.12.tar.gz b/t/t4000-upgrade/0.12.tar.gz
new file mode 100644
index 0000000000000000000000000000000000000000..b183fcb1983eaa11c1a2eba3f0bb47b5c1c845c8
GIT binary patch
literal 11077
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
Hi12>^a3NeI

literal 0
Hc$@<O00001

diff --git a/t/t4000-upgrade/0.8.tar.gz b/t/t4000-upgrade/0.8.tar.gz
new file mode 100644
index 0000000000000000000000000000000000000000..7a7d3c2f8d916dc79c55f0f0b2426005224aca97
GIT binary patch
literal 8224
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
S0001J1N;{VbU3j97y$r>Aaw))

literal 0
Hc$@<O00001

diff --git a/t/t4000-upgrade/make-repo.sh b/t/t4000-upgrade/make-repo.sh
new file mode 100644
index 0000000..98b5020
--- /dev/null
+++ b/t/t4000-upgrade/make-repo.sh
@@ -0,0 +1,71 @@
+# This script makes several versions of a small test repository that
+# can be used for testing the format version upgrade code.
+
+LANG=C
+LC_ALL=C
+PAGER=cat
+TZ=UTC
+export LANG LC_ALL PAGER TZ
+unset AUTHOR_DATE
+unset AUTHOR_EMAIL
+unset AUTHOR_NAME
+unset COMMIT_AUTHOR_EMAIL
+unset COMMIT_AUTHOR_NAME
+unset GIT_ALTERNATE_OBJECT_DIRECTORIES
+unset GIT_AUTHOR_DATE
+GIT_AUTHOR_EMAIL=author@example.com
+GIT_AUTHOR_NAME='A U Thor'
+unset GIT_COMMITTER_DATE
+GIT_COMMITTER_EMAIL=committer@example.com
+GIT_COMMITTER_NAME='C O Mitter'
+unset GIT_DIFF_OPTS
+unset GIT_DIR
+unset GIT_EXTERNAL_DIFF
+unset GIT_INDEX_FILE
+unset GIT_OBJECT_DIRECTORY
+unset SHA1_FILE_DIRECTORIES
+unset SHA1_FILE_DIRECTORY
+export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME
+export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME
+
+for ver in 0.12 0.8; do
+    if [ -e $ver.tar.gz ]; then continue; fi
+
+    # Get the required stgit version.
+    (
+        cd ../..
+        git archive --format=tar --prefix=stgit-$ver/ v$ver
+    ) | tar xf -
+
+    # Set up a repository.
+    mkdir $ver
+    cd $ver
+    git init
+    touch foo
+    git add foo
+    git commit -m 'Initial commit'
+
+    # Use the old stgit.
+    (
+        pwd
+        PATH=../stgit-$ver:$PATH
+
+        stg --version
+        stg init
+        echo 'cool branch' > .git/patches/master/description
+
+        for i in 0 1 2 3 4; do
+            stg new p$i -m "Patch $i"
+            echo "Line $i" >> foo
+            stg refresh
+        done
+        stg pop -n 2
+    )
+
+    # Reduce the number of small files.
+    git gc
+
+    # Make a tarball.
+    cd ..
+    tar zcf $ver.tar.gz $ver
+done

^ permalink raw reply related

* [StGIT PATCH 3/5] Upgrade old StGIT branches to new-format metadata
From: Karl Hasselström @ 2007-05-19  0:10 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: git
In-Reply-To: <20070519000451.4906.87089.stgit@yoghurt>

There used to be a "stg branch --convert" command that switched
between "old" and "new" format metadata. But my recent metadata
cleanup patches introduced a "new new" format, and more are hopefully
on the way, so it was time to start versioning the metadata format
explicitly in order to avoid future headaches.

This patch removes the "stg branch --convert" command, and makes StGIT
automatically upgrade older formats to the latest format. It stores
the format (as an integer) in the config file. The current metadata
format version number is 2 (the "old" format is 0, and the "new"
format is 1).

Signed-off-by: Karl Hasselström <kha@treskal.com>
---

 Documentation/stg-branch.txt |    4 -
 stgit/commands/branch.py     |   11 ---
 stgit/stack.py               |  153 ++++++++++++++++++++++++------------------
 3 files changed, 86 insertions(+), 82 deletions(-)

diff --git a/Documentation/stg-branch.txt b/Documentation/stg-branch.txt
index 25c9c19..25ca951 100644
--- a/Documentation/stg-branch.txt
+++ b/Documentation/stg-branch.txt
@@ -20,7 +20,6 @@ SYNOPSIS
 'stg' branch --protect [<branch>]
 'stg' branch --unprotect [<branch>]
 'stg' branch --delete [--force] <branch>
-'stg' branch --convert
 
 DESCRIPTION
 -----------
@@ -91,9 +90,6 @@ the "master" branch if it exists.
 Branch "master" is treated specially (see bug #8732), in that only the
 StGIT metadata are removed, the GIT branch itself is not destroyed.
 
-'stg' branch --convert::
-	Switch current stack between old and new format.
-
 OPTIONS
 -------
 
diff --git a/stgit/commands/branch.py b/stgit/commands/branch.py
index b043c69..5e7b0df 100644
--- a/stgit/commands/branch.py
+++ b/stgit/commands/branch.py
@@ -45,9 +45,6 @@ options = [make_option('-c', '--create',
            make_option('--clone',
                        help = 'clone the contents of the current branch',
                        action = 'store_true'),
-           make_option('--convert',
-                       help = 'switch between old and new format branches',
-                       action = 'store_true'),
            make_option('--delete',
                        help = 'delete an existing development branch',
                        action = 'store_true'),
@@ -186,14 +183,6 @@ def func(parser, options, args):
 
         return
 
-    elif options.convert:
-
-        if len(args) != 0:
-            parser.error('incorrect number of arguments')
-
-        crt_series.convert()
-        return
-
     elif options.delete:
 
         if len(args) != 1:
diff --git a/stgit/stack.py b/stgit/stack.py
index d9c4b99..223f3ee 100644
--- a/stgit/stack.py
+++ b/stgit/stack.py
@@ -273,6 +273,79 @@ class Patch(StgitObject):
         self._set_field('log', value)
         self.__update_log_ref(value)
 
+# The current StGIT metadata format version.
+FORMAT_VERSION = 2
+
+def format_version_key(branch):
+    return 'branch.%s.stgitformatversion' % branch
+
+def update_to_current_format_version(branch, git_dir):
+    """Update a potentially older StGIT directory structure to the
+    latest version. Note: This function should depend as little as
+    possible on external functions that may change during a format
+    version bump, since it must remain able to process older formats."""
+
+    branch_dir = os.path.join(git_dir, 'patches', branch)
+    def get_format_version():
+        """Return the integer format version number, or None if the
+        branch doesn't have any StGIT metadata at all, of any version."""
+        fv = config.get(format_version_key(branch))
+        if fv:
+            # Great, there's an explicitly recorded format version
+            # number, which means that the branch is initialized and
+            # of that exact version.
+            return int(fv)
+        elif os.path.isdir(os.path.join(branch_dir, 'patches')):
+            # There's a .git/patches/<branch>/patches dirctory, which
+            # means this is an initialized version 1 branch.
+            return 1
+        elif os.path.isdir(branch_dir):
+            # There's a .git/patches/<branch> directory, which means
+            # this is an initialized version 0 branch.
+            return 0
+        else:
+            # The branch doesn't seem to be initialized at all.
+            return None
+    def set_format_version(v):
+        config.set(format_version_key(branch), '%d' % v)
+    def mkdir(d):
+        if not os.path.isdir(d):
+            os.makedirs(d)
+    def rm(f):
+        if os.path.exists(f):
+            os.remove(f)
+
+    # Update 0 -> 1.
+    if get_format_version() == 0:
+        mkdir(os.path.join(branch_dir, 'trash'))
+        patch_dir = os.path.join(branch_dir, 'patches')
+        mkdir(patch_dir)
+        refs_dir = os.path.join(git_dir, 'refs', 'patches', branch)
+        mkdir(refs_dir)
+        for patch in (file(os.path.join(branch_dir, 'unapplied')).readlines()
+                      + file(os.path.join(branch_dir, 'applied')).readlines()):
+            patch = patch.strip()
+            os.rename(os.path.join(branch_dir, patch),
+                      os.path.join(patch_dir, patch))
+            Patch(patch, patch_dir, refs_dir).update_top_ref()
+        set_format_version(1)
+
+    # Update 1 -> 2.
+    if get_format_version() == 1:
+        desc_file = os.path.join(branch_dir, 'description')
+        if os.path.isfile(desc_file):
+            desc = read_string(desc_file)
+            if desc:
+                config.set('branch.%s.description' % branch, desc)
+            rm(desc_file)
+        rm(os.path.join(branch_dir, 'current'))
+        rm(os.path.join(git_dir, 'refs', 'bases', branch))
+        set_format_version(2)
+
+    # Make sure we're at the latest version.
+    if not get_format_version() in [None, FORMAT_VERSION]:
+        raise StackException('Branch %s is at format version %d, expected %d'
+                             % (branch, get_format_version(), FORMAT_VERSION))
 
 class Series(StgitObject):
     """Class including the operations on series
@@ -290,6 +363,11 @@ class Series(StgitObject):
             raise StackException, 'GIT tree not initialised: %s' % ex
 
         self._set_dir(os.path.join(self.__base_dir, 'patches', self.__name))
+
+        # Update the branch to the latest format version if it is
+        # initialized, but don't touch it if it isn't.
+        update_to_current_format_version(self.__name, self.__base_dir)
+
         self.__refs_dir = os.path.join(self.__base_dir, 'refs', 'patches',
                                        self.__name)
 
@@ -299,19 +377,9 @@ class Series(StgitObject):
 
         # where this series keeps its patches
         self.__patch_dir = os.path.join(self._dir(), 'patches')
-        if not os.path.isdir(self.__patch_dir):
-            self.__patch_dir = self._dir()
-
-        # if no __refs_dir, create and populate it (upgrade old repositories)
-        if self.is_initialised() and not os.path.isdir(self.__refs_dir):
-            os.makedirs(self.__refs_dir)
-            for patch in self.get_applied() + self.get_unapplied():
-                self.get_patch(patch).update_top_ref()
 
         # trash directory
         self.__trash_dir = os.path.join(self._dir(), 'trash')
-        if self.is_initialised() and not os.path.isdir(self.__trash_dir):
-            os.makedirs(self.__trash_dir)
 
     def __patch_name_valid(self, name):
         """Raise an exception if the patch name is not valid.
@@ -410,19 +478,13 @@ class Series(StgitObject):
         return 'branch.%s.description' % self.get_branch()
 
     def get_description(self):
-        # Fall back to the .git/patches/<branch>/description file if
-        # the config variable is unset.
-        return (config.get(self.__branch_descr())
-                or self._get_field('description') or '')
+        return config.get(self.__branch_descr())
 
     def set_description(self, line):
         if line:
             config.set(self.__branch_descr(), line)
         else:
             config.unset(self.__branch_descr())
-        # Delete the old .git/patches/<branch>/description file if it
-        # exists.
-        self._set_field('description', None)
 
     def get_parent_remote(self):
         value = config.get('branch.%s.remote' % self.__name)
@@ -503,15 +565,16 @@ class Series(StgitObject):
     def is_initialised(self):
         """Checks if series is already initialised
         """
-        return os.path.isdir(self.__patch_dir)
+        return bool(config.get(format_version_key(self.get_branch())))
 
     def init(self, create_at=False, parent_remote=None, parent_branch=None):
         """Initialises the stgit series
         """
-        if os.path.exists(self.__patch_dir):
-            raise StackException, self.__patch_dir + ' already exists'
-        if os.path.exists(self.__refs_dir):
-            raise StackException, self.__refs_dir + ' already exists'
+        if self.is_initialised():
+            raise StackException, '%s already initialized' % self.get_branch()
+        for d in [self._dir(), self.__refs_dir]:
+            if os.path.exists(d):
+                raise StackException, '%s already exists' % d
 
         if (create_at!=False):
             git.create_branch(self.__name, create_at)
@@ -522,45 +585,10 @@ class Series(StgitObject):
 
         self.create_empty_field('applied')
         self.create_empty_field('unapplied')
-        os.makedirs(os.path.join(self._dir(), 'patches'))
         os.makedirs(self.__refs_dir)
         self._set_field('orig-base', git.get_head())
 
-    def convert(self):
-        """Either convert to use a separate patch directory, or
-        unconvert to place the patches in the same directory with
-        series control files
-        """
-        if self.__patch_dir == self._dir():
-            print 'Converting old-style to new-style...',
-            sys.stdout.flush()
-
-            self.__patch_dir = os.path.join(self._dir(), 'patches')
-            os.makedirs(self.__patch_dir)
-
-            for p in self.get_applied() + self.get_unapplied():
-                src = os.path.join(self._dir(), p)
-                dest = os.path.join(self.__patch_dir, p)
-                os.rename(src, dest)
-
-            print 'done'
-
-        else:
-            print 'Converting new-style to old-style...',
-            sys.stdout.flush()
-
-            for p in self.get_applied() + self.get_unapplied():
-                src = os.path.join(self.__patch_dir, p)
-                dest = os.path.join(self._dir(), p)
-                os.rename(src, dest)
-
-            if not os.listdir(self.__patch_dir):
-                os.rmdir(self.__patch_dir)
-                print 'done'
-            else:
-                print 'Patch directory %s is not empty.' % self.__patch_dir
-
-            self.__patch_dir = self._dir()
+        config.set(format_version_key(self.get_branch()), str(FORMAT_VERSION))
 
     def rename(self, to_name):
         """Renames a series
@@ -666,15 +694,6 @@ class Series(StgitObject):
             if os.path.exists(self._dir()+'/orig-base'):
                 os.remove(self._dir()+'/orig-base')
 
-            # Remove obsolete files that StGIT no longer uses, but
-            # that might still be around if this is an old repository.
-            for obsolete in ([os.path.join(self._dir(), fn)
-                              for fn in ['current', 'description']]
-                             + [os.path.join(self.__base_dir,
-                                             'refs', 'bases', self.__name)]):
-                if os.path.exists(obsolete):
-                    os.remove(obsolete)
-
             if not os.listdir(self.__patch_dir):
                 os.rmdir(self.__patch_dir)
             else:

^ permalink raw reply related

* [StGIT PATCH 2/5] Have only a single command in each test_expect_failure
From: Karl Hasselström @ 2007-05-19  0:09 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: git
In-Reply-To: <20070519000451.4906.87089.stgit@yoghurt>

Otherwise, we can't know which one failed.

Signed-off-by: Karl Hasselström <kha@treskal.com>
---

 t/t1000-branch-create.sh |   71 ++++++++++++++++++++++++++++------------------
 1 files changed, 43 insertions(+), 28 deletions(-)

diff --git a/t/t1000-branch-create.sh b/t/t1000-branch-create.sh
index 58209e7..cca5504 100755
--- a/t/t1000-branch-create.sh
+++ b/t/t1000-branch-create.sh
@@ -12,57 +12,72 @@ Exercises the "stg branch" commands.
 
 stg init
 
+test_expect_success \
+    'Create a spurious refs/patches/ entry' '
+    find .git -name foo | xargs rm -rf &&
+    touch .git/refs/patches/foo
+'
+
 test_expect_failure \
-    'Try to create an stgit branch with a spurious refs/patches/ entry' \
-    'find .git -name foo | xargs rm -rf &&
-     touch .git/refs/patches/foo &&
-     stg branch -c foo
+    'Try to create an stgit branch with a spurious refs/patches/ entry' '
+    stg branch -c foo
+'
+
+test_expect_success \
+    'Check that no part of the branch was created' '
+    test "`find .git -name foo | tee /dev/stderr`" = ".git/refs/patches/foo" &&
+    ( grep foo .git/HEAD; test $? = 1 )
 '
 
 test_expect_success \
-    'Check no part of the branch was created' \
-    'test "`find .git -name foo | tee /dev/stderr`" = ".git/refs/patches/foo" &&
-     ( grep foo .git/HEAD; test $? = 1 )
+    'Create a spurious patches/ entry' '
+    find .git -name foo | xargs rm -rf &&
+    touch .git/patches/foo
 '
 
 test_expect_failure \
-    'Try to create an stgit branch with a spurious patches/ entry' \
-    'find .git -name foo | xargs rm -rf &&
-     touch .git/patches/foo &&
-     stg branch -c foo
+    'Try to create an stgit branch with a spurious patches/ entry' '
+    stg branch -c foo
 '
 
 test_expect_success \
-    'Check no part of the branch was created' \
-    'test "`find .git -name foo | tee /dev/stderr`" = ".git/patches/foo" &&
-     ( grep foo .git/HEAD; test $? = 1 )
+    'Check that no part of the branch was created' '
+    test "`find .git -name foo | tee /dev/stderr`" = ".git/patches/foo" &&
+    ( grep foo .git/HEAD; test $? = 1 )
+'
+
+test_expect_success \
+    'Create a git branch' '
+    find .git -name foo | xargs rm -rf &&
+    cp .git/refs/heads/master .git/refs/heads/foo
 '
 
 test_expect_failure \
-    'Try to create an stgit branch with an existing git branch by that name' \
-    'find .git -name foo | xargs rm -rf &&
-     cp .git/refs/heads/master .git/refs/heads/foo &&
-     stg branch -c foo
+    'Try to create an stgit branch with an existing git branch by that name' '
+    stg branch -c foo
 '
 
 test_expect_success \
-    'Check no part of the branch was created' \
-    'test "`find .git -name foo | tee /dev/stderr`" = ".git/refs/heads/foo" &&
-     ( grep foo .git/HEAD; test $? = 1 )
+    'Check that no part of the branch was created' '
+    test "`find .git -name foo | tee /dev/stderr`" = ".git/refs/heads/foo" &&
+    ( grep foo .git/HEAD; test $? = 1 )
 '
 
+test_expect_success \
+    'Create an invalid refs/heads/ entry' '
+    find .git -name foo | xargs rm -rf &&
+    touch .git/refs/heads/foo
+'
 
 test_expect_failure \
-    'Try to create an stgit branch with an invalid refs/heads/ entry' \
-    'find .git -name foo | xargs rm -rf &&
-     touch .git/refs/heads/foo &&
-     stg branch -c foo
+    'Try to create an stgit branch with an invalid refs/heads/ entry' '
+    stg branch -c foo
 '
 
 test_expect_success \
-    'Check no part of the branch was created' \
-    'test "`find .git -name foo | tee /dev/stderr`" = ".git/refs/heads/foo" &&
-     ( grep foo .git/HEAD; test $? = 1 )
+    'Check that no part of the branch was created' '
+    test "`find .git -name foo | tee /dev/stderr`" = ".git/refs/heads/foo" &&
+    ( grep foo .git/HEAD; test $? = 1 )
 '
 
 test_done

^ permalink raw reply related

* [StGIT PATCH 1/5] Fix config caching so that get, set, get works
From: Karl Hasselström @ 2007-05-19  0:09 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: git
In-Reply-To: <20070519000451.4906.87089.stgit@yoghurt>

The config caching was never invalidated or updated, which caused the
two gets to always return the same value regardless of the value
passed to set.

Signed-off-by: Karl Hasselström <kha@treskal.com>
---

 stgit/config.py |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/stgit/config.py b/stgit/config.py
index 79cd12f..2fd1273 100644
--- a/stgit/config.py
+++ b/stgit/config.py
@@ -99,12 +99,15 @@ class GitConfig:
 
     def rename_section(self, from_name, to_name):
         self.__run('git-repo-config --rename-section', [from_name, to_name])
+        self.__cache.clear()
 
     def set(self, name, value):
         self.__run('git-repo-config', [name, value])
+        self.__cache[name] = value
 
     def unset(self, name):
         self.__run('git-repo-config --unset', [name])
+        self.__cache[name] = None
 
     def sections_matching(self, regexp):
         """Takes a regexp with a single group, matches it against all

^ permalink raw reply related

* [StGIT PATCH 0/5] Metadata format versioning
From: Karl Hasselström @ 2007-05-19  0:09 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: git
In-Reply-To: <20070516062711.GA7235@diana.vm.bytemark.co.uk>

On 2007-05-16 08:27:11 +0200, Karl Hasselström wrote:

> I'll probably have time to whip up a patch later today.

OK, so this turned out to be a slight miscalculation. But here it is,
with a test! The test contains two small tarballs, so I had to whip up
binary patch support as well.

> I'll make a single version bump for the format changes you've alreay
> applied, and re-do the format-changing patches you haven't applied
> yet so that they have version bumping integrated.

This contains a single version bump (1 -> 2) for the applied changes,
but i haven't updated the DAG patch to use this yet. That's for
another day.

-- 
Karl Hasselström, kha@treskal.com
      www.treskal.com/kalle

^ permalink raw reply

* Re: [PATCH] Fix crlf attribute handling to match documentation
From: Junio C Hamano @ 2007-05-19  0:02 UTC (permalink / raw)
  To: Andy Parkins; +Cc: git
In-Reply-To: <200705181333.32719.andyparkins@gmail.com>

Andy Parkins <andyparkins@gmail.com> writes:

> gitattributes.txt says, of the crlf attribute:
>
>  Set::
>     Setting the `crlf` attribute on a path is meant to mark
>     the path as a "text" file.  'core.autocrlf' conversion
>     takes place without guessing the content type by
>     inspection.
>
> That is to say that the crlf attribute does not force the file to have
> CRLF line endings, instead it removes the autocrlf guesswork and forces
> the file to be treated as text.  Then, whatever line ending is defined
> by the autocrlf setting is applied.

Thanks; I looked at the patch (although I am still _physically_
at work ;-).  I think your code is correct but the explanation
is slightly misleading.

> However, that is not what convert.c was doing.  The conversion to CRLF
> was being skipped in crlf_to_worktree() when the following condition was
> true:
>
>  action == CRLF_GUESS && auto_crlf <= 0

The check you modified in the first hunk is not the above '<='
comparison but is this:

	(action == CRLF_GUESS && !auto_crlf)

and "core.autocrlf = input" makes "auto_crlf = -1", so when
action is not GUESS, or even when action is GUESS, if the config
is set to "input", the if() statement you patched in the first
hunk should not trigger.  The above description is different from
what the code was doing.

The logic (in crlf_to_git, which is the input codepath) should be:

	* if action is BINARY, do nothing (obviously -- and the
          code gets this right).

	* if action is GUESS, do nothing if config says false
          (we want 'input' and 'true' to apply the munging after
          guessing).

	* if action is TEXT or INPUT, do not guess but do CRLF
          only on platforms that need it -- which means where
          auto_crlf is -1 (input) or 1 (true).  Otherwise do not
          do the conversion.

The original code gets the third case incorrectly, and your
patch fixes it by returning early in that case as well.

The output codepath is the same.  Regardless of action
(GUESS/TEXT/INPUT), we will not do anything if config says 'false'
or 'input', so removing the check with "action == GUESS" is the
right thing.

^ permalink raw reply

* Re: merge summaries
From: Junio C Hamano @ 2007-05-18 23:34 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: J. Bruce Fields, Steffen Prohaska, Git Mailing List
In-Reply-To: <alpine.LFD.0.98.0705181611520.3890@woody.linux-foundation.org>

Linus Torvalds <torvalds@linux-foundation.org> writes:

> On Fri, 18 May 2007, J. Bruce Fields wrote:
>> 
>> I never quite understood what they're for--do they add any information
>> not already available in the history?  If not, and if people still find
>> them helpful anyway, then I dunno, it looks like a sign of some sort of
>> failure of our history display tools.
>
> I don't think they add much in the case of a graphical viewer, but for 
> "git log", it does make it look nicer..

Especially if you do "git log --first-parent" ;-).

^ permalink raw reply

* [PATCH] Documentation: git-rev-list's "patterns"
From: Petr Baudis @ 2007-05-18 23:21 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

git-rev-list(1) talks about patterns as values for the
--grep, --committed etc. parameters, without going into detail.
This patch mentions that these patterns are actually regexps.

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

 Documentation/git-rev-list.txt |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt
index ab90a22..c3c2043 100644
--- a/Documentation/git-rev-list.txt
+++ b/Documentation/git-rev-list.txt
@@ -207,12 +207,12 @@ limiting may be applied.
 --author='pattern', --committer='pattern'::
 
 	Limit the commits output to ones with author/committer
-	header lines that match the specified pattern.
+	header lines that match the specified pattern (regular expression).
 
 --grep='pattern'::
 
 	Limit the commits output to ones with log message that
-	matches the specified pattern.
+	matches the specified pattern (regular expression).
 
 --remove-empty::
 

^ permalink raw reply related

* Re: merge summaries
From: Linus Torvalds @ 2007-05-18 23:12 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: Junio C Hamano, Steffen Prohaska, Git Mailing List
In-Reply-To: <20070518215603.GS15393@fieldses.org>



On Fri, 18 May 2007, J. Bruce Fields wrote:
> 
> I never quite understood what they're for--do they add any information
> not already available in the history?  If not, and if people still find
> them helpful anyway, then I dunno, it looks like a sign of some sort of
> failure of our history display tools.

I don't think they add much in the case of a graphical viewer, but for 
"git log", it does make it look nicer..

		Linus

^ permalink raw reply

* [PATCH] gitweb: Remove redundant $searchtype setup
From: Petr Baudis @ 2007-05-18 23:12 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Sorry, this was inadverently introduced by my grep search patch. It causes
annoying "redefined" warnings.

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

 gitweb/gitweb.perl |    7 -------
 1 files changed, 0 insertions(+), 7 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index ac78a10..0143183 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -413,13 +413,6 @@ if (defined $searchtext) {
 	$search_regexp = quotemeta $searchtext;
 }
 
-our $searchtype = $cgi->param('st');
-if (defined $searchtype) {
-	if ($searchtype =~ m/[^a-z]/) {
-		die_error(undef, "Invalid searchtype parameter");
-	}
-}
-
 # now read PATH_INFO and use it as alternative to parameters
 sub evaluate_path_info {
 	return if defined $project;

^ 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