Git development
 help / color / mirror / Atom feed
* Re: [PATCH] tutorial.txt renamed
From: Brian Foster @ 2009-01-08  9:21 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Brian Gernhardt, Christian Couder, Joey Hess
In-Reply-To: <7vljtnbpha.fsf@gitster.siamese.dyndns.org>

On Wednesday 07 January 2009 07:27:13 Junio C Hamano wrote:
> Brian Gernhardt <benji@silverinsanity.com> writes:
> > This is the README file for the project, so it should advise looking  
> > at the Documentation directory as neither the man pages or git command  
> > are likely installed at this point.
> 
> I think that is a sane suggestion.  It is better to keep the number of
> prerequisites to the minimum for the user in order to follow README (and
> INSTALL, of course).

 It is indeed a sane suggestion.  However, there is no (obvious?)
 harm in *also* mentioning that ‘git help tutorial’ should also
 display the tutorial.  Something like “If git has been correctly
 installed, then this tutorial can also be read with the command
 ‘git help tutorial’.”

cheers!
	-blf-
-- 
“How many surrealists does it take to   | Brian Foster
 change a lightbulb? Three. One calms   | somewhere in south of France
 the warthog, and two fill the bathtub  |   Stop E$$o (ExxonMobil)!
 with brightly-coloured machine tools.” |      http://www.stopesso.com

^ permalink raw reply

* Re: [PATCH (topgit) 1/2] Implement setup_pager just like in git
From: Kirill Smelkov @ 2009-01-08  9:23 UTC (permalink / raw)
  To: martin f krafft
  Cc: Thomas Rast, Bert Wesarg, Pierre Habouzit, Petr Baudis, git
In-Reply-To: <20090108020650.GC7345@lapse.rw.madduck.net>

On Thu, Jan 08, 2009 at 03:06:50PM +1300, martin f krafft wrote:
> also sprach Kirill Smelkov <kirr@landau.phys.spbu.ru> [2009.01.08.1100 +1300]:
> > > So I suppose you could use
> > > 
> > >   ${GIT_PAGER-${PAGER-less}}
> > > 
> > > or similar.
> > 
> > Good eyes, thanks!
> > 
> > I'll rework it.
> 
> I am not 100% on this, but I think nested {}'s are a bashism.

It seems to be ok:

kirr@roro3:~$ dash 
$ unset GIT_PAGER
$ unset PAGER
$ echo ${GIT_PAGER-${PAGER-less}}
less
$ PAGER=more
$ echo ${GIT_PAGER-${PAGER-less}}
more
$ GIT_PAGER=''
$ echo ${GIT_PAGER-${PAGER-less}}

$ GIT_PAGER=/bin/cat
$ echo ${GIT_PAGER-${PAGER-less}}
/bin/cat


> > On Wed, Jan 07, 2009 at 03:24:02PM +0100, Bert Wesarg wrote:
> > > On Wed, Jan 7, 2009 at 12:27, Kirill Smelkov <kirr@landau.phys.spbu.ru> wrote:
> > > > Martin, thanks for your review.
> > > > +       # atexit(close(1); wait pager)
> > > > +       trap "exec >&-; rm "$_pager_fifo"; rmdir "$_pager_fifo_dir"; wait" EXIT
> > > I think you need to escape the double quotes.
> > 
> > Good eyes -- corrected and thanks!
> 
> You could also just use single quotes inside the double quotes.

Thanks for the tip - I'll keep it in mind. Or is it the preferred way?


Thanks,
Kirill

^ permalink raw reply

* Re: [PATCH] Support ref logs for refs/*
From: Nanako Shiraishi @ 2009-01-08  9:08 UTC (permalink / raw)
  To: Neil Macneale; +Cc: git
In-Reply-To: <20090108082827.GA6177@tesla.theory.org>

Quoting Neil Macneale <mac4-git@theory.org>:

> The documentation for git update-ref seems to imply that logging of ref
> updates should be done for anything in refs/...

The documementation for git-update-ref is part of git, and git does not use anything outside of refs/{heads,tags,remotes}/ for its normal operation. 

I think it is generally assumed that there is nothing of interest outside of these areas that deserves the automated creation of reflogs, and the code you are touching is about that. Once you have reflog for any ref you are interested outside of these areas, your actions will be logged regardless. 

Most notably, refs/stash itself is exempt from this code path and it makes sure that reflog exists without relying on log_all_ref_updates configuration. 

Also the documentation for the configuration variable explicitly says it is about the branch heads.

core.logAllRefUpdates::
	Enable the reflog. Updates to a ref <ref> is logged to the file
	"$GIT_DIR/logs/<ref>", by appending the new and old
	SHA1, the date/time and the reason of the update, but
	only when the file exists.  If this configuration
	variable is set to true, missing "$GIT_DIR/logs/<ref>"
	file is automatically created for branch heads.

-- 
Nanako Shiraishi
http://ivory.ap.teacup.com/nanako3/

^ permalink raw reply

* Git for Product Line Engineering
From: Michail Anastasopoulos @ 2009-01-08  9:01 UTC (permalink / raw)
  To: git

Hello,
I was wondering if anyone of you has applied git to manage the evolution of a
product line. In such a context management of software reuse and permanent
variation becomes necessary.

I think that the distributed character of git as well the easier handling of
branches could be very beneficial in such a context.

Yet I was wondering how the relations between reusable and reused things could
be managed?

If for example I am the maintainer of a library in a product line context I want
to know who pulls from me and whether my library had to undergo any
product-specific changes in any of the other repositories that belong to my
product line.

Regards,
Michalis

^ permalink raw reply

* Re: Can I prevent someone clone my git repository?
From: Johannes Sixt @ 2009-01-08  8:59 UTC (permalink / raw)
  To: Emily Ren; +Cc: Junio C Hamano, git
In-Reply-To: <7vr63e42ke.fsf@gitster.siamese.dyndns.org>

Junio C Hamano schrieb:
> The git-daemon transport deliberately omits authentication, and you cannot
> restrict when they come over the git native transport using a URL like
> git://your-host/repository.git

But you can wrap git daemon by tcpd and configure hosts.allow and
hosts.deny (with all its caveats), if this suits your needs.

-- Hannes

^ permalink raw reply

* [PATCH] Support ref logs for refs/*
From: Neil Macneale @ 2009-01-08  8:28 UTC (permalink / raw)
  To: git

The documentation for git update-ref seems to imply that logging of ref
updates should be done for anything in refs/, though the code looks like it
restricts changes to heads and remotes. Any reason not so support arbitrary
refs?

I don't see much point in logging for tags, so the patch ignores refs/tags.

Thanks,
Neil

Signed-off-by: Neil Macneale <mac4-git@theory.org>
---
 refs.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/refs.c b/refs.c
index 33ced65..cfff22b 100644
--- a/refs.c
+++ b/refs.c
@@ -1154,9 +1154,9 @@ static int log_ref_write(const char *ref_name, const
unsigned char *old_sha1,
        git_snpath(log_file, sizeof(log_file), "logs/%s", ref_name);
 
        if (log_all_ref_updates &&
-           (!prefixcmp(ref_name, "refs/heads/") ||
-            !prefixcmp(ref_name, "refs/remotes/") ||
-            !strcmp(ref_name, "HEAD"))) {
+           (!prefixcmp(ref_name, "refs/") ||
+            !strcmp(ref_name, "HEAD")) &&
+           prefixcmp(ref_name, "refs/tags/")) {
                if (safe_create_leading_directories(log_file) < 0)
                        return error("unable to create directory for %s",
                                     log_file);
-- 
1.6.1.141.gfe98e.dirty

^ permalink raw reply related

* Re: Can I prevent someone clone my git repository?
From: Junio C Hamano @ 2009-01-08  8:36 UTC (permalink / raw)
  To: Emily Ren; +Cc: git
In-Reply-To: <856bfe0e0901072303i4fcd3bf6u99790ab9f4170937@mail.gmail.com>

"Emily Ren" <lingyan.ren@gmail.com> writes:

> I want some person can clone my git repository, others can't clone my
> git repository. Is it realizable ? How to do it?

It depends on what transport these people come from.

On the local filesystem transport (either same host or network-mounted
filesystem), you do it the same way as you solve "how do I show these
files of mine on the local computer to some but not others".  Typically,
you place these group members in the same UNIX group, make the toplevel
directory of the hierarchy owned by the group, and "chmod g+rx,o=" it (and
make everything underneath group readable).  Setting core.sharedrepository
configuration variable would help maintain the group readability.

If they come over the http transport, you would solve it the same way as
you solve "how do I allow access to these files on my webserver to only
selected few?"  Probably .htaccess file in the toplevel directory will be
involved.

You can set up gitosis and have it serve your repository, and register
group members' SSH keys to gitosis.  It allows you to categorize these
users into different groups, and assign read-only or read-write access to
repositories.  When this is done, these people will be coming over the
"git over ssh" transport, i.e. git@your-host:/path/to/repository.git/
or its synonym ssh://git@your-host/path/to/repository.git/

The git-daemon transport deliberately omits authentication, and you cannot
restrict when they come over the git native transport using a URL like
git://your-host/repository.git

-jc

^ permalink raw reply

* Re: [BUG PATCH RFC] mailinfo: correctly handle multiline 'Subject:' header
From: Junio C Hamano @ 2009-01-08  8:35 UTC (permalink / raw)
  To: Kirill Smelkov; +Cc: git
In-Reply-To: <7vy6xm5i6h.fsf@gitster.siamese.dyndns.org>

Junio C Hamano <gitster@pobox.com> writes:

> Kirill Smelkov <kirr@landau.phys.spbu.ru> writes:
> ...
>> http://marc.info/?l=git&m=123031899307286&w=2
>
> I have not had chance to look at your patch at marc yet, but from the look
> of your problem description, I presume you could trigger this with any
> utf-8 b-encoded loooooong subject line?

Ok, I took a look at it after downloading from the marc archive.

> diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
> index e890f7a..d138bc3 100644
> --- a/builtin-mailinfo.c
> +++ b/builtin-mailinfo.c
> @@ -436,6 +436,14 @@ static struct strbuf *decode_b_segment(const struct strbuf *b_seg)
>  			 * for now we just trust the data.
>  			 */
>  			c = 0;
> +
> +			/* XXX: the following is needed not to output NUL in
> +			 * the resulting string
> +			 *
> +			 * This seems to be ok, but I'm not 100% sure -- that's
> +			 * why this is an RFC.
> +			 */
> +			continue;
>  		}
>  		else
>  			continue; /* garbage */

B encoding (RFC 2045) encodes an octet stream into a sequence of groups of
4 letters from 64-char alphabet, each of which encodes 6-bit, plus zero or
more padding char '=' to make the result multiple of 4.

 * If the length of the payload is a multiple of 3 octets, there is no
   special handling.  Padding char '=' is not produced;

 * If it is a multiple of 3 octets plus one, the remaining one octet is
   encoded with two letters, and two more padding char '=' is added;

 * If it is a multiple of 3 octets plus two, the remaining two octets are
   encoded with three letters, and one padding char '=' is added.

Hence, a "correct" implementation should decode the input as if '=' were
the same as 'A' (which encodes 6 bits of 0) til the end, making sure that
the padding char '=' appears only at the end of the input, that no char
outside the Base64 encoding alphabet appears in the input, and that the
length of the entire encoded string is multiple of 4.  Finally it would
discard either one or two octets (depending on the number of padding chars
it saw) from the end of the output.

Our decode_b_segment() however emits each octet as it completes, without
waiting for the 24-bit group that contains it to complete.  When decoding
a correctly encoded input, by the time we see a padding '=', all the real
payload octets are complete and we would not have any real information
still kept in the variable "acc" (accumulator), so ignoring '=' (you do
not even need to assign c = 0) like your patch did would work just fine.
An alternative would be to count the number of padding at the end and drop
the NULs from the output as necessary after the loop but that does not add
any value to the current code.

Ideally we should validate the encoded string a bit more carefully (see
the "correct" implementation about), and warn if a malformed input is
found (but probably not reject outright).  But as a low-impact fix for the
maintenance branches, I think your fix is very good.

	Side note: I suspect that the existing code was Ok before strbuf
	conversion as we assumed NUL terminated output buffer.

> @@ -513,7 +521,15 @@ static int decode_header_bq(struct strbuf *it)
>  		strbuf_reset(&piecebuf);
>  		rfc2047 = 1;
>  
> -		if (in != ep) {
> +		/* XXX: the follwoing is needed not to output '\n' on every
> +		 * multi-line segment in Subject.
> +		 *
> +		 * I suspect this is not 100% correct, but I'm not a MIME guy
> +		 * -- that's why this is an RFC.
> +		 */
> +
> +		/* if in does not end with '=?=', we emit it as is */
> +		if (in <= (ep-2) && !(ep[-1]=='\n' && ep[-2]=='=')) {
>  			strbuf_add(&outbuf, in, ep - in);
>  			in = ep;
> 
>  		}

I am not a MIME guy either (and mailinfo has a big comment that says we do
not really do MIME --- we just pretend to do), but let me give it a try.

RFC2046 specifies that an encoded-word ("=?charset?encoding?...?=") may
not be more than 75 characters long, and multiple encoded-words, separated
by CRLF SPACE can be used to encode more text if needed.

It further specifies that an encoded-word can appear next to ordinary text
or another encoded-word but it must be separated by linear white space,
and says that such linear white space is to be ignored when displaying.

Which means that we should be eating the CRLF SPACE we see if we have seen
an encoded-word immediately before and we are about to process another
encoded-word.

Based on the above discussion, here is what I came up with.  It passes
your test, but I ran out of energy to try breaking it seriously in any
other way than just running the existing test suite.  

We might want to steal some test cases from the "8. Examples" section of
RFC2047 and add them to t5100.

Thanks.

 builtin-mailinfo.c |   27 +++++++++++++++++++--------
 1 files changed, 19 insertions(+), 8 deletions(-)

diff --git c/builtin-mailinfo.c w/builtin-mailinfo.c
index e890f7a..fcb32c9 100644
--- c/builtin-mailinfo.c
+++ w/builtin-mailinfo.c
@@ -430,13 +430,6 @@ static struct strbuf *decode_b_segment(const struct strbuf *b_seg)
 			c -= 'a' - 26;
 		else if ('0' <= c && c <= '9')
 			c -= '0' - 52;
-		else if (c == '=') {
-			/* padding is almost like (c == 0), except we do
-			 * not output NUL resulting only from it;
-			 * for now we just trust the data.
-			 */
-			c = 0;
-		}
 		else
 			continue; /* garbage */
 		switch (pos++) {
@@ -514,7 +507,25 @@ static int decode_header_bq(struct strbuf *it)
 		rfc2047 = 1;
 
 		if (in != ep) {
-			strbuf_add(&outbuf, in, ep - in);
+			/*
+			 * We are about to process an encoded-word
+			 * that begins at ep, but there is something
+			 * before the encoded word.
+			 */
+			char *scan;
+			for (scan = in; scan < ep; scan++)
+				if (!isspace(*scan))
+					break;
+
+			if (scan != ep || in == it->buf) {
+				/*
+				 * We should not lose that "something",
+				 * unless we have just processed an
+				 * encoded-word, and there is only LWS
+				 * before the one we are about to process.
+				 */
+				strbuf_add(&outbuf, in, ep - in);
+			}
 			in = ep;
 		}
 		/* E.g.

^ permalink raw reply related

* Re: [BUG PATCH RFC] mailinfo: correctly handle multiline 'Subject:' header
From: Junio C Hamano @ 2009-01-08  8:13 UTC (permalink / raw)
  To: Kirill Smelkov; +Cc: git
In-Reply-To: <20090107224342.GB4946@roro3>

Kirill Smelkov <kirr@landau.phys.spbu.ru> writes:

> On Fri, Dec 26, 2008 at 09:38:41PM +0300, Kirill Smelkov wrote:
>> When native language (RU) is in use, subject header usually contains several
>> parts, e.g.
> ...
> Junio, All,
>
> What about this patch?

What's most interesting is that I do not recall seeing this patch before.
Neither gmane (which is my back-up interface to the mailing list) nor my
mailbox seems to have a copy, and from the look of quoted parts (namely,
some Russian strings in the message), it is not implausible that my spam
filter (either on my receiving end or at the ISP) may have eaten it.

> It at least exposes bug in git-mailinfo wrt handling of multiline
> subjects, and in very details documents it and adds a test for it.
>
> ..., but may I try to attract git
> community attention one more time?

It is very appreciated.

> P.S. original post with patch:
>
> http://marc.info/?l=git&m=123031899307286&w=2

I have not had chance to look at your patch at marc yet, but from the look
of your problem description, I presume you could trigger this with any
utf-8 b-encoded loooooong subject line?

^ permalink raw reply

* Re: [PATCH] gitweb: support the rel=vcs-* microformat
From: Giuseppe Bilotta @ 2009-01-08  7:56 UTC (permalink / raw)
  To: git
In-Reply-To: <20090107232427.GA18958@gnu.kitenet.net>

Hello Joey,

On Thursday 08 January 2009 00:24, Joey Hess wrote:

> The rel=vcs-* microformat allows a web page to indicate the locations of
> repositories related to it in a machine-parseable manner.
> (See http://kitenet.net/~joey/rfc/rel-vcs/)

Have you considered submitting the microformat to microformats.org?
That would make the microformat more official and would be an good
first step to have wider coverage of it, and additional reviews.

> Make gitweb use the microformat if it has been configured with project url
> information in any of the usual ways. On the project summary page, the
> repository URL display is simply marked up using the microformat. On the
> project list page and forks list page, the microformat is embedded in the
> header, since the URLs do not appear on the page.
> 
> The microformat could be included on other pages too, but I've skipped
> doing so for now, since it would mean reading another file for every page
> displayed.
> 
> There is a small overhead in including the microformat on project list
> and forks list pages, but getting the project descriptions for those pages
> already incurs a similar overhead, and the ability to get every repo url
> in one place seems worthwhile.

I agree with this, although people with very large project lists may
differ ... do we have timings on these?
 
> This changes git_get_project_url_list() to not check wantarray, and only
> return in list context -- the only way it is used AFAICS. It memoizes
> both that function and git_get_project_description(), to avoid redundant
> file reads.

You may want to consider splitting the patch into three: memoizing
of git_get_project_description(), reworking of
git_get_project_url_list(), and the actual rel=vc-* insertions.

> Signed-off-by: Joey Hess <joey@gnu.kitenet.net>
> ---
>  gitweb/gitweb.perl |   78 +++++++++++++++++++++++++++++++++++++++++----------
>  1 files changed, 62 insertions(+), 16 deletions(-)
> 
> This incorporates Giuseppe Bilotta's feedback, and uses new features
> of the microformat. You can see this version running at
> http://git.ikiwiki.info/

Oh, and do consider cc'ing jnareb and paski when submitting patches
for gitweb, as they are the (unofficial?) maintainers. I usually cc
gitster (Junio C Hamano) too.

[ Also cc'ing me for this round would have been a nice idea too,
since we had the review going on ;-) ]

> diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
> index 99f71b4..c238717 100755
> --- a/gitweb/gitweb.perl
> +++ b/gitweb/gitweb.perl
> @@ -2020,9 +2020,14 @@ sub git_get_path_by_hash {
>  ## ......................................................................
>  ## git utility functions, directly accessing git repository
>  
> +{
> +my %project_descriptions; # cache
> +

Out of curiosity, why the grouping? I would have had

our %project_descriptions;

up above with all the global variables.

>  sub git_get_project_description {
>       my $path = shift;
>  
> +     return $project_descriptions{$path} if exists $project_descriptions{$path};
> +

This line is bordering on the 80 characters, so you may want to
consider moving 'my $descr' here, with something such as

my $descr = $project_descriptions{$path};
return $descr if exists $descr;

Also, I'm no perl guru so I'm not sure about exists vs defined here.

>       $git_dir = "$projectroot/$path";
>       open my $fd, "$git_dir/description"
>               or return git_get_project_config('description');
> @@ -2031,7 +2036,9 @@ sub git_get_project_description {
>       if (defined $descr) {
>               chomp $descr;
>       }
> -     return $descr;
> +     return $project_descriptions{$path}=$descr;
> +}
> +
>  }

[This is where I would end the first patch]

>  
>  sub git_get_project_ctags {
> @@ -2099,18 +2106,30 @@ sub git_show_project_tagcloud {
>       }
>  }
>  
> +{
> +my %project_url_lists; # cache
> +

Ditto for this: why not our %project_url_lists; without scoping?

>  sub git_get_project_url_list {
> +     # use per project git URL list in $projectroot/$path/cloneurl
> +     # or make project git URL from git base URL and project name
>       my $path = shift;
>  
> +     return @{$project_url_lists{$path}} if exists $project_url_lists{$path};
> +
> +     my @ret;
>       $git_dir = "$projectroot/$path";
> -     open my $fd, "$git_dir/cloneurl"
> -             or return wantarray ?
> -             @{ config_to_multi(git_get_project_config('url')) } :
> -                config_to_multi(git_get_project_config('url'));
> -     my @git_project_url_list = map { chomp; $_ } <$fd>;
> -     close $fd;
> +     if (open my $fd, "$git_dir/cloneurl") {
> +             @ret = map { chomp; $_ } <$fd>;
> +             close $fd;
> +     } else {
> +            @ret = @{ config_to_multi(git_get_project_config('url')) };
> +     }
> +     @ret=map { "$_/$project" } @git_base_url_list if ! @ret;
> +
> +     $project_url_lists{$path}=\@ret;
> +     return @ret;
> +}
>  
> -     return wantarray ? @git_project_url_list : \@git_project_url_list;
>  }

[This is where I would end the second patch]

>  
>  sub git_get_projects_list {
> @@ -2856,6 +2875,7 @@ sub blob_contenttype {
>  sub git_header_html {
>       my $status = shift || "200 OK";
>       my $expires = shift;
> +     my $extraheader = shift;
>  
>       my $title = "$site_name";
>       if (defined $project) {
> @@ -2953,6 +2973,8 @@ EOF
>               print qq(<link rel="shortcut icon" href="$favicon" type="image/png" />\n);
>       }
>  
> +     print $extraheader if defined $extraheader;
> +
>       print "</head>\n" .
>             "<body>\n";
>  
> @@ -4365,6 +4387,26 @@ sub git_search_grep_body {
>       print "</table>\n";
>  }
>  
> +sub git_link_title {
> +     my $project=shift;
> +     
> +     my $description=git_get_project_description($project);
> +     return $project.(length $description ? " - $description" : "");
> +}

Nice.

> +
> +# generates header with links to the specified projects
> +sub git_links_header {
> +     my $ret='';
> +     foreach my $project (@_) {
> +             # rel=vcs-* microformat
> +             my $title=git_link_title($project);
> +             foreach my $url git_get_project_url_list($project) {
> +                     $ret.=qq{<link rel="vcs-git" href="$url" title="$title"/>\n}
> +             }
> +     }
> +     return $ret;
> +}
> +
>  ## ======================================================================
>  ## ======================================================================
>  ## actions
> @@ -4380,7 +4422,9 @@ sub git_project_list {
>               die_error(404, "No projects found");
>       }
>  
> -     git_header_html();
> +     my $extraheader=git_links_header(map { $_->{path} } @list);
> +
> +     git_header_html(undef, undef, $extraheader);
>       if (-f $home_text) {
>               print "<div class=\"index_include\">\n";
>               insert_file($home_text);
> @@ -4405,8 +4449,10 @@ sub git_forks {
>       if (!@list) {
>               die_error(404, "No forks found");
>       }
> +     
> +     my $extraheader=git_links_header(map { $_->{path} } @list);
>  
> -     git_header_html();
> +     git_header_html(undef, undef, $extraheader);

This makes me wonder if it would be worth it to turn git_header_html
into -param => value style, but I'm not really sure it's worth it.

>       git_print_page_nav('','');
>       git_print_header_div('summary', "$project forks");
>       git_project_list_body(\@list, $order);
> @@ -4468,14 +4514,14 @@ sub git_summary {
>               print "<tr id=\"metadata_lchange\"><td>last change</td><td>$cd{'rfc2822'}</td></tr>\n";
>       }
>  
> -     # use per project git URL list in $projectroot/$project/cloneurl
> -     # or make project git URL from git base URL and project name
>       my $url_tag = "URL";
> -     my @url_list = git_get_project_url_list($project);
> -     @url_list = map { "$_/$project" } @git_base_url_list unless @url_list;
> -     foreach my $git_url (@url_list) {
> +     my $title=git_link_title($project);
> +     foreach my $git_url (git_get_project_url_list($project)) {
>               next unless $git_url;
> -             print "<tr class=\"metadata_url\"><td>$url_tag</td><td>$git_url</td></tr>\n";
> +             print "<tr class=\"metadata_url\"><td>$url_tag</td><td>".
> +                   # rel=vcs-* microformat
> +                   "<a rel=\"vcs-git\" href=\"$git_url\" title=\"$title\">$git_url</a>".
> +                   "</td></tr>\n";
>               $url_tag = "";
>       }

Good. Of course the comment removal (which is actually a due move to
git_get_project_url_list) would go in the appropriate patch if you
split them 8-)

-- 
Giuseppe "Oblomov" Bilotta

^ permalink raw reply

* Re: Google Summer of Code 2009
From: Sam Vilain @ 2009-01-08  7:55 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Shawn O. Pearce, Alex Riesen, git
In-Reply-To: <alpine.DEB.1.00.0901080024170.7496@intel-tinevez-2-302>

On Thu, 2009-01-08 at 00:30 +0100, Johannes Schindelin wrote:
> However, from what Sam said at the GitTogether, it might be a much better 
> idea to look at the existing code as a fact-finding experiment, scrap it 
> (excluding the experience), and start modifying git-daemon.
> 
> AFAICT Sam has a pretty clear idea how to go about it, and staying with C 
> should make it much easier for other people to comment.
> 
> Note that there has been a flurry of emails on the gittorrent list a few 
> weeks back, where somebody challenged the approach Sam wants to take, 
> saying that BitTorrent has some very nice features that are absolutely 
> necessary, such as its pretty awkward custom encoding.
> 
> But AFAICT Sam did a pretty good job at dispelling all of the objections.

Yes, this is accurate as I know it.  I've renamed and reworded the
heading under the SoC2009Ideas page to point to the most current design.
It's all in a "just add JFDI" point right now I think ;-).

Sam.

^ permalink raw reply

* Re: Problems with large compressed binaries when converting from svn
From: Øyvind Harboe @ 2009-01-08  7:33 UTC (permalink / raw)
  To: Alex Riesen; +Cc: git
In-Reply-To: <81b0412b0901071555t62c1da3ar2b2cfd14222b502e@mail.gmail.com>

>> Does git have some capability to store diffs of compressed files efficiently?
>
> No, but you can unpack the tarballs and include the toolchains as submodules
> (aka subprojects) in the projects which need them.
>
> See man page to git submodule, the user-manual.txt on "submodule" and
> gitmodules.txt (submodule configuration formats and conventions).

I'll need the submodule stuff for sure, but in this particular case I was
trying to see if there was a way to keep the svn abuse patterns from
svn under git without a lot of retraining.



-- 
Øyvind Harboe
http://www.zylin.com/zy1000.html
ARM7 ARM9 XScale Cortex
JTAG debugger and flash programmer

^ permalink raw reply

* Re: why still no empty directory support in git
From: Asheesh Laroia @ 2009-01-08  7:12 UTC (permalink / raw)
  To: Git Mailing List
In-Reply-To: <20090101200651.GB6536@coredump.intra.peff.net>

On Thu, 1 Jan 2009, Jeff King wrote:

> On Tue, Dec 30, 2008 at 03:58:46AM -0500, Asheesh Laroia wrote:
>
>> So, let's say I take your suggestion.
>>
>> $ touch ~/Maildir/new/.exists
>> $ git add ~/Maildir/new/.exists && git commit -m "La di da"
>>
>> Now a spec-compliant Maildir user agent will attempt to deliver this new
>> "email message" of zero bytes into the mail spool and assign it a message
>> UID.  Doing so will remove it from Maildir/new.
>
> No. The maildir spec says:
>
>  A unique name can be anything that doesn't contain a colon (or slash)
>  and doesn't start with a dot.
>     -- http://cr.yp.to/proto/maildir.html
>
> where a "unique name" is the filename used for a message. In practice,
> every maildir implementation I have seen ignores files starting with a
> dot. Do you have one that doesn't?

My apologies. This works just fine, and I'm a dolt.

Happy new year!

(I'm still academically interested in how to avoid the rmdir(), but as I 
said before, that's a topic for someone else to pick up now.)

-- Asheesh.

-- 
English literature's performing flea.
 		-- Sean O'Casey on P. G. Wodehouse

^ permalink raw reply

* Can I prevent someone clone my git repository?
From: Emily Ren @ 2009-01-08  7:03 UTC (permalink / raw)
  To: git

All,

I want some person can clone my git repository, others can't clone my
git repository. Is it realizable ? How to do it?

Thanks,
Emily

^ permalink raw reply

* Re: Public repro case! Re: [PATCH/RFC] Allow writing loose objects that are corrupted in a pack file
From: Shawn O. Pearce @ 2009-01-08  6:04 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: James Pickens, Git ML, R. Tyler Ballance, Nicolas Pitre,
	Jan Krüger, kb, Linus Torvalds
In-Reply-To: <7v4p0a8if2.fsf@gitster.siamese.dyndns.org>

Junio C Hamano <gitster@pobox.com> wrote:
> "Shawn O. Pearce" <spearce@spearce.org> writes:
> > For those following along at home, Linus' 2.6 tree:
> >
> > $ ulimit -v `echo '150 * 1024'|bc -l`
> > $ git co 56d18e9932ebf4e8eca42d2ce509450e6c9c1666
> 
> Hmm, without any "wrap zlib to die on error" patch, this step already
> fails with:
> 
>     $ git checkout 56d18e9932ebf4e8eca42d2ce509450e6c9c1666
>     fatal: Out of memory? mmap failed: Cannot allocate memory
> 
> I guess that is because our test repositories are packed differently.
> I'll retry after repacking..

Yup.  I actually did something more like this to get the test
repository:

  git clone git://android.git.kernel.org/kernel/common.git
  git fetch git://kernel.org/pub/.../torvalds/linux-2.6.git master

The android kernel repository I had handy on my local system was
quite a bit away from Linus' so I wound up with two different but
sizable packs.  I thought android was closer to upstream, but its
apparently not.  I started from there because it was local and I
thought it would be a quick way to get a test environment, but
sadly it didn't even have the base 56d18e we were talking about.

-- 
Shawn.

^ permalink raw reply

* Re: Public repro case! Re: [PATCH/RFC] Allow writing loose objects that are corrupted in a pack file
From: Junio C Hamano @ 2009-01-08  5:40 UTC (permalink / raw)
  To: Shawn O. Pearce
  Cc: James Pickens, Git ML, R. Tyler Ballance, Nicolas Pitre,
	Jan Krüger, kb, Linus Torvalds
In-Reply-To: <20090108024325.GE10790@spearce.org>

"Shawn O. Pearce" <spearce@spearce.org> writes:

> For those following along at home, Linus' 2.6 tree:
>
> $ ulimit -v `echo '150 * 1024'|bc -l`
> $ git co 56d18e9932ebf4e8eca42d2ce509450e6c9c1666

Hmm, without any "wrap zlib to die on error" patch, this step already
fails with:

    $ git checkout 56d18e9932ebf4e8eca42d2ce509450e6c9c1666
    fatal: Out of memory? mmap failed: Cannot allocate memory

I guess that is because our test repositories are packed differently.
I'll retry after repacking..

^ permalink raw reply

* Re: [PATCH] Wrap inflateInit to retry allocation after releasing pack memory
From: Junio C Hamano @ 2009-01-08  5:23 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Shawn O. Pearce, R. Tyler Ballance, Nicolas Pitre,
	Jan Krüger, Git ML, kb
In-Reply-To: <alpine.LFD.2.00.0901071941210.3283@localhost.localdomain>

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

> +int git_inflate(z_streamp strm, int flush)
> +{
> +...
> +	/* Z_BUF_ERROR: normal, needs a buffer output buffer */
> +	case Z_BUF_ERROR:

Thanks, but "needs a buffer output buffer" made me scratch my head
somewhat.

  ... Z_BUF_ERROR if no progress is possible or if there was not enough
  room in the output buffer when Z_FINISH is used. Note that Z_BUF_ERROR
  is not fatal, and inflate() can be called again with more input and more
  output space to continue decompressing.

^ permalink raw reply

* Re: collapsing commits with rebase
From: Boyd Stephen Smith Jr. @ 2009-01-08  4:23 UTC (permalink / raw)
  To: Sitaram Chamarty; +Cc: git
In-Reply-To: <slrngmav3b.20e.sitaramc@sitaramc.homelinux.net>

[-- Attachment #1: Type: text/plain, Size: 585 bytes --]

On Wednesday 2009 January 07 22:09:15 Sitaram Chamarty wrote:
>[Haven't tested, but I *think* I understand rebase well
>enough now to say so...]

Probably understand it better than me.  I just haven't needed to use it for 
this that much.  This also might not be much better than setting GIT_PAGER to 
a script, but it seems less fragile to me.
-- 
Boyd Stephen Smith Jr.                     ,= ,-_-. =. 
bss@iguanasuicide.net                     ((_/)o o(\_))
ICQ: 514984 YM/AIM: DaTwinkDaddy           `-'(. .)`-' 
http://iguanasuicide.net/                      \_/     

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply

* Re: collapsing commits with rebase
From: Sitaram Chamarty @ 2009-01-08  4:09 UTC (permalink / raw)
  To: git
In-Reply-To: <200901072011.37299.bss@iguanasuicide.net>

On 2009-01-08, Boyd Stephen Smith Jr. <bss@iguanasuicide.net> wrote:
>>    A---B---C---D---E---F

> Assuming you also have a ref (e.g. Foo) that points to F:
> git checkout sha(B)
> git merge -s sha(D)

I think you now need to do a commit (assuming you meant
"--squash").  Squash will not commit, and your rebase below
(if it runs at all -- I suspect it will refuse to run) will
hard reset to B, the current HEAD.  IOW

> After the merge:
> A -> B -> C -> D -> E -> F [Foo]
>      |
>      +--> [HEAD]

is not true.  You have C+D in the index, not in the tree.

> git rebase --onto $(cat .git/HEAD) sha(E) Foo

Also I think you have an off-by-one error here; you need
sha(D) in that rebase command, not sha(E).

As your rebase command stands, you will lose commit E
completely; neither the merge nor the rebase will pick it
up.

[Haven't tested, but I *think* I understand rebase well
enough now to say so...]

^ permalink raw reply

* Re: [PATCH] Wrap inflateInit to retry allocation after releasing pack memory
From: Linus Torvalds @ 2009-01-08  3:54 UTC (permalink / raw)
  To: Shawn O. Pearce
  Cc: Junio C Hamano, R. Tyler Ballance, Nicolas Pitre, Jan Krüger,
	Git ML, kb
In-Reply-To: <20090108031655.GH10790@spearce.org>



On Wed, 7 Jan 2009, Shawn O. Pearce wrote:
>
> If we are running low on virtual memory we should release pack
> windows if zlib's inflateInit fails due to an out of memory error.
> It may be that we are running under a low ulimit and are getting
> tight on address space.  Shedding unused windows may get us
> sufficient working space to continue.

Let's do this (more complete) wrapping instead, ok?

This one _just_ wraps things, btw - it doesn't do the "retry on low memory 
error" part, at least not yet. I think that's an independent issue from 
the reporting.

Hmm? 

Tyler - does this make the corruption errors go away, and be replaced by 
hard failures with "out of memory" reporting?

This patch is potentially pretty noisy, on purpose. I didn't remove the 
reporting from places that already do so - some of them have stricter 
errors than this.

For example: Z_BUF_ERROR can be valid depending on circumstance, so the 
wrapper doesn't complain about it, but the caller may not accept it. 

		Linus

---
 builtin-apply.c          |    5 ++-
 builtin-pack-objects.c   |    6 ++--
 builtin-unpack-objects.c |    6 ++--
 cache.h                  |    4 +++
 http-push.c              |    8 +++---
 http-walker.c            |    8 +++---
 index-pack.c             |   12 ++++----
 sha1_file.c              |   24 +++++++++---------
 wrapper.c                |   60 ++++++++++++++++++++++++++++++++++++++++++++++
 9 files changed, 99 insertions(+), 34 deletions(-)

diff --git a/builtin-apply.c b/builtin-apply.c
index 07244b0..ed02b6d 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -1253,8 +1253,9 @@ static char *inflate_it(const void *data, unsigned long size,
 	stream.avail_in = size;
 	stream.next_out = out = xmalloc(inflated_size);
 	stream.avail_out = inflated_size;
-	inflateInit(&stream);
-	st = inflate(&stream, Z_FINISH);
+	git_inflate_init(&stream);
+	st = git_inflate(&stream, Z_FINISH);
+	git_inflate_end(&stream);
 	if ((st != Z_STREAM_END) || stream.total_out != inflated_size) {
 		free(out);
 		return NULL;
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index e851534..cb51916 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -195,16 +195,16 @@ static int check_pack_inflate(struct packed_git *p,
 	int st;
 
 	memset(&stream, 0, sizeof(stream));
-	inflateInit(&stream);
+	git_inflate_init(&stream);
 	do {
 		in = use_pack(p, w_curs, offset, &stream.avail_in);
 		stream.next_in = in;
 		stream.next_out = fakebuf;
 		stream.avail_out = sizeof(fakebuf);
-		st = inflate(&stream, Z_FINISH);
+		st = git_inflate(&stream, Z_FINISH);
 		offset += stream.next_in - in;
 	} while (st == Z_OK || st == Z_BUF_ERROR);
-	inflateEnd(&stream);
+	git_inflate_end(&stream);
 	return (st == Z_STREAM_END &&
 		stream.total_out == expect &&
 		stream.total_in == len) ? 0 : -1;
diff --git a/builtin-unpack-objects.c b/builtin-unpack-objects.c
index 47ed610..9a77323 100644
--- a/builtin-unpack-objects.c
+++ b/builtin-unpack-objects.c
@@ -99,10 +99,10 @@ static void *get_data(unsigned long size)
 	stream.avail_out = size;
 	stream.next_in = fill(1);
 	stream.avail_in = len;
-	inflateInit(&stream);
+	git_inflate_init(&stream);
 
 	for (;;) {
-		int ret = inflate(&stream, 0);
+		int ret = git_inflate(&stream, 0);
 		use(len - stream.avail_in);
 		if (stream.total_out == size && ret == Z_STREAM_END)
 			break;
@@ -118,7 +118,7 @@ static void *get_data(unsigned long size)
 		stream.next_in = fill(1);
 		stream.avail_in = len;
 	}
-	inflateEnd(&stream);
+	git_inflate_end(&stream);
 	return buf;
 }
 
diff --git a/cache.h b/cache.h
index 231c06d..49e54fb 100644
--- a/cache.h
+++ b/cache.h
@@ -18,6 +18,10 @@
 #define deflateBound(c,s)  ((s) + (((s) + 7) >> 3) + (((s) + 63) >> 6) + 11)
 #endif
 
+void git_inflate_init(z_streamp strm);
+void git_inflate_end(z_streamp strm);
+int git_inflate(z_streamp strm, int flush);
+
 #if defined(DT_UNKNOWN) && !defined(NO_D_TYPE_IN_DIRENT)
 #define DTYPE(de)	((de)->d_type)
 #else
diff --git a/http-push.c b/http-push.c
index 7c64609..809002b 100644
--- a/http-push.c
+++ b/http-push.c
@@ -208,7 +208,7 @@ static size_t fwrite_sha1_file(void *ptr, size_t eltsize, size_t nmemb,
 	do {
 		request->stream.next_out = expn;
 		request->stream.avail_out = sizeof(expn);
-		request->zret = inflate(&request->stream, Z_SYNC_FLUSH);
+		request->zret = git_inflate(&request->stream, Z_SYNC_FLUSH);
 		git_SHA1_Update(&request->c, expn,
 			    sizeof(expn) - request->stream.avail_out);
 	} while (request->stream.avail_in && request->zret == Z_OK);
@@ -268,7 +268,7 @@ static void start_fetch_loose(struct transfer_request *request)
 
 	memset(&request->stream, 0, sizeof(request->stream));
 
-	inflateInit(&request->stream);
+	git_inflate_init(&request->stream);
 
 	git_SHA1_Init(&request->c);
 
@@ -309,7 +309,7 @@ static void start_fetch_loose(struct transfer_request *request)
 	   file; also rewind to the beginning of the local file. */
 	if (prev_read == -1) {
 		memset(&request->stream, 0, sizeof(request->stream));
-		inflateInit(&request->stream);
+		git_inflate_init(&request->stream);
 		git_SHA1_Init(&request->c);
 		if (prev_posn>0) {
 			prev_posn = 0;
@@ -741,7 +741,7 @@ static void finish_request(struct transfer_request *request)
 			if (request->http_code == 416)
 				fprintf(stderr, "Warning: requested range invalid; we may already have all the data.\n");
 
-			inflateEnd(&request->stream);
+			git_inflate_end(&request->stream);
 			git_SHA1_Final(request->real_sha1, &request->c);
 			if (request->zret != Z_STREAM_END) {
 				unlink(request->tmpfile);
diff --git a/http-walker.c b/http-walker.c
index 7271c7d..0dbad3c 100644
--- a/http-walker.c
+++ b/http-walker.c
@@ -82,7 +82,7 @@ static size_t fwrite_sha1_file(void *ptr, size_t eltsize, size_t nmemb,
 	do {
 		obj_req->stream.next_out = expn;
 		obj_req->stream.avail_out = sizeof(expn);
-		obj_req->zret = inflate(&obj_req->stream, Z_SYNC_FLUSH);
+		obj_req->zret = git_inflate(&obj_req->stream, Z_SYNC_FLUSH);
 		git_SHA1_Update(&obj_req->c, expn,
 			    sizeof(expn) - obj_req->stream.avail_out);
 	} while (obj_req->stream.avail_in && obj_req->zret == Z_OK);
@@ -142,7 +142,7 @@ static void start_object_request(struct walker *walker,
 
 	memset(&obj_req->stream, 0, sizeof(obj_req->stream));
 
-	inflateInit(&obj_req->stream);
+	git_inflate_init(&obj_req->stream);
 
 	git_SHA1_Init(&obj_req->c);
 
@@ -183,7 +183,7 @@ static void start_object_request(struct walker *walker,
 	   file; also rewind to the beginning of the local file. */
 	if (prev_read == -1) {
 		memset(&obj_req->stream, 0, sizeof(obj_req->stream));
-		inflateInit(&obj_req->stream);
+		git_inflate_init(&obj_req->stream);
 		git_SHA1_Init(&obj_req->c);
 		if (prev_posn>0) {
 			prev_posn = 0;
@@ -243,7 +243,7 @@ static void finish_object_request(struct object_request *obj_req)
 		return;
 	}
 
-	inflateEnd(&obj_req->stream);
+	git_inflate_end(&obj_req->stream);
 	git_SHA1_Final(obj_req->real_sha1, &obj_req->c);
 	if (obj_req->zret != Z_STREAM_END) {
 		unlink(obj_req->tmpfile);
diff --git a/index-pack.c b/index-pack.c
index 60ed41a..c0a3d97 100644
--- a/index-pack.c
+++ b/index-pack.c
@@ -275,10 +275,10 @@ static void *unpack_entry_data(unsigned long offset, unsigned long size)
 	stream.avail_out = size;
 	stream.next_in = fill(1);
 	stream.avail_in = input_len;
-	inflateInit(&stream);
+	git_inflate_init(&stream);
 
 	for (;;) {
-		int ret = inflate(&stream, 0);
+		int ret = git_inflate(&stream, 0);
 		use(input_len - stream.avail_in);
 		if (stream.total_out == size && ret == Z_STREAM_END)
 			break;
@@ -287,7 +287,7 @@ static void *unpack_entry_data(unsigned long offset, unsigned long size)
 		stream.next_in = fill(1);
 		stream.avail_in = input_len;
 	}
-	inflateEnd(&stream);
+	git_inflate_end(&stream);
 	return buf;
 }
 
@@ -382,9 +382,9 @@ static void *get_data_from_pack(struct object_entry *obj)
 	stream.avail_out = obj->size;
 	stream.next_in = src;
 	stream.avail_in = len;
-	inflateInit(&stream);
-	while ((st = inflate(&stream, Z_FINISH)) == Z_OK);
-	inflateEnd(&stream);
+	git_inflate_init(&stream);
+	while ((st = git_inflate(&stream, Z_FINISH)) == Z_OK);
+	git_inflate_end(&stream);
 	if (st != Z_STREAM_END || stream.total_out != obj->size)
 		die("serious inflate inconsistency");
 	free(src);
diff --git a/sha1_file.c b/sha1_file.c
index 52d1ead..8600b04 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1196,8 +1196,8 @@ static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned lon
 	stream->avail_out = bufsiz;
 
 	if (legacy_loose_object(map)) {
-		inflateInit(stream);
-		return inflate(stream, 0);
+		git_inflate_init(stream);
+		return git_inflate(stream, 0);
 	}
 
 
@@ -1217,7 +1217,7 @@ static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned lon
 	/* Set up the stream for the rest.. */
 	stream->next_in = map;
 	stream->avail_in = mapsize;
-	inflateInit(stream);
+	git_inflate_init(stream);
 
 	/* And generate the fake traditional header */
 	stream->total_out = 1 + snprintf(buffer, bufsiz, "%s %lu",
@@ -1254,11 +1254,11 @@ static void *unpack_sha1_rest(z_stream *stream, void *buffer, unsigned long size
 		stream->next_out = buf + bytes;
 		stream->avail_out = size - bytes;
 		while (status == Z_OK)
-			status = inflate(stream, Z_FINISH);
+			status = git_inflate(stream, Z_FINISH);
 	}
 	buf[size] = 0;
 	if (status == Z_STREAM_END && !stream->avail_in) {
-		inflateEnd(stream);
+		git_inflate_end(stream);
 		return buf;
 	}
 
@@ -1348,15 +1348,15 @@ unsigned long get_size_from_delta(struct packed_git *p,
 	stream.next_out = delta_head;
 	stream.avail_out = sizeof(delta_head);
 
-	inflateInit(&stream);
+	git_inflate_init(&stream);
 	do {
 		in = use_pack(p, w_curs, curpos, &stream.avail_in);
 		stream.next_in = in;
-		st = inflate(&stream, Z_FINISH);
+		st = git_inflate(&stream, Z_FINISH);
 		curpos += stream.next_in - in;
 	} while ((st == Z_OK || st == Z_BUF_ERROR) &&
 		 stream.total_out < sizeof(delta_head));
-	inflateEnd(&stream);
+	git_inflate_end(&stream);
 	if ((st != Z_STREAM_END) && stream.total_out != sizeof(delta_head)) {
 		error("delta data unpack-initial failed");
 		return 0;
@@ -1585,14 +1585,14 @@ static void *unpack_compressed_entry(struct packed_git *p,
 	stream.next_out = buffer;
 	stream.avail_out = size;
 
-	inflateInit(&stream);
+	git_inflate_init(&stream);
 	do {
 		in = use_pack(p, w_curs, curpos, &stream.avail_in);
 		stream.next_in = in;
-		st = inflate(&stream, Z_FINISH);
+		st = git_inflate(&stream, Z_FINISH);
 		curpos += stream.next_in - in;
 	} while (st == Z_OK || st == Z_BUF_ERROR);
-	inflateEnd(&stream);
+	git_inflate_end(&stream);
 	if ((st != Z_STREAM_END) || stream.total_out != size) {
 		free(buffer);
 		return NULL;
@@ -2017,7 +2017,7 @@ static int sha1_loose_object_info(const unsigned char *sha1, unsigned long *size
 		status = error("unable to parse %s header", sha1_to_hex(sha1));
 	else if (sizep)
 		*sizep = size;
-	inflateEnd(&stream);
+	git_inflate_end(&stream);
 	munmap(map, mapsize);
 	return status;
 }
diff --git a/wrapper.c b/wrapper.c
index 93562f0..29afa96 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -196,3 +196,63 @@ int xmkstemp(char *template)
 		die("Unable to create temporary file: %s", strerror(errno));
 	return fd;
 }
+
+/*
+ * zlib wrappers to make sure we don't silently miss errors
+ * at init time.
+ */
+void git_inflate_init(z_streamp strm)
+{
+	const char *err;
+
+	switch (inflateInit(strm)) {
+	case Z_OK:
+		return;
+
+	case Z_MEM_ERROR:
+		err = "out of memory";
+		break;
+	case Z_VERSION_ERROR:
+		err = "wrong version";
+		break;
+	default:
+		err = "error";
+	}
+	die("inflateInit: %s (%s)", err, strm->msg ? strm->msg : "no message");
+}
+
+void git_inflate_end(z_streamp strm)
+{
+	if (inflateEnd(strm) != Z_OK)
+		error("inflateEnd: %s", strm->msg ? strm->msg : "failed");
+}
+
+int git_inflate(z_streamp strm, int flush)
+{
+	int ret = inflate(strm, flush);
+	const char *err;
+
+	switch (ret) {
+	/* Out of memory is fatal. */
+	case Z_MEM_ERROR:
+		die("inflate: out of memory");
+
+	/* Data corruption errors: we may want to recover from them (fsck) */
+	case Z_NEED_DICT:
+		err = "needs dictionary"; break;
+	case Z_DATA_ERROR:
+		err = "data stream error"; break;
+	case Z_STREAM_ERROR:
+		err = "stream consistency error"; break;
+	default:
+		err = "unknown error"; break;
+
+	/* Z_BUF_ERROR: normal, needs a buffer output buffer */
+	case Z_BUF_ERROR:
+	case Z_OK:
+	case Z_STREAM_END:
+		return ret;
+	}
+	error("inflate: %s (%s)", err, strm->msg ? strm->msg : "no message");
+	return ret;
+}

^ permalink raw reply related

* Re: [PATCH (topgit) 1/2] Implement setup_pager just like in git
From: martin f krafft @ 2009-01-08  2:06 UTC (permalink / raw)
  To: Kirill Smelkov, Thomas Rast, Bert Wesarg, Pierre Habouzit,
	Petr Baudis
In-Reply-To: <20090107220027.GA4946@roro3>

[-- Attachment #1: Type: text/plain, Size: 1133 bytes --]

also sprach Kirill Smelkov <kirr@landau.phys.spbu.ru> [2009.01.08.1100 +1300]:
> > So I suppose you could use
> > 
> >   ${GIT_PAGER-${PAGER-less}}
> > 
> > or similar.
> 
> Good eyes, thanks!
> 
> I'll rework it.

I am not 100% on this, but I think nested {}'s are a bashism.

> On Wed, Jan 07, 2009 at 03:24:02PM +0100, Bert Wesarg wrote:
> > On Wed, Jan 7, 2009 at 12:27, Kirill Smelkov <kirr@landau.phys.spbu.ru> wrote:
> > > Martin, thanks for your review.
> > > +       # atexit(close(1); wait pager)
> > > +       trap "exec >&-; rm "$_pager_fifo"; rmdir "$_pager_fifo_dir"; wait" EXIT
> > I think you need to escape the double quotes.
> 
> Good eyes -- corrected and thanks!

You could also just use single quotes inside the double quotes.

-- 
martin | http://madduck.net/ | http://two.sentenc.es/
 
"he gave me his card
 he said, 'call me if they die'
 i shook his hand and said goodbye
 ran out to the street
 when a bowling ball came down the road
 and knocked me off my feet"
                                                        -- bob dylan
 
spamtraps: madduck.bogus@madduck.net

[-- Attachment #2: Digital signature (see http://martin-krafft.net/gpg/) --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply

* [PATCH] Wrap inflateInit to retry allocation after releasing pack memory
From: Shawn O. Pearce @ 2009-01-08  3:16 UTC (permalink / raw)
  To: Linus Torvalds, Junio C Hamano
  Cc: R. Tyler Ballance, Nicolas Pitre, Jan Krüger, Git ML, kb
In-Reply-To: <20090108031314.GG10790@spearce.org>

If we are running low on virtual memory we should release pack
windows if zlib's inflateInit fails due to an out of memory error.
It may be that we are running under a low ulimit and are getting
tight on address space.  Shedding unused windows may get us
sufficient working space to continue.

Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
  "Shawn O. Pearce" <spearce@spearce.org> wrote:
  > Linus Torvalds <torvalds@linux-foundation.org> wrote:
  > > The Z_STREAM_ERROR probably comes from inflate() itself - and could very 
  > > easily be due to a allocation error in inflateInit leaving the stream data 
  > > incomplete.
  > > 
  > > Let me try wrapping that dang thing and send a patch. 
  > 
  > Yup.  I'm actually doing the same thing...

 builtin-apply.c          |    2 +-
 builtin-pack-objects.c   |    2 +-
 builtin-unpack-objects.c |    2 +-
 cache.h                  |    1 +
 http-push.c              |    4 ++--
 http-walker.c            |    4 ++--
 index-pack.c             |    4 ++--
 sha1_file.c              |    8 ++++----
 wrapper.c                |   20 ++++++++++++++++++++
 9 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/builtin-apply.c b/builtin-apply.c
index af25ee9..cb2663e 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -1258,7 +1258,7 @@ static char *inflate_it(const void *data, unsigned long size,
 	stream.avail_in = size;
 	stream.next_out = out = xmalloc(inflated_size);
 	stream.avail_out = inflated_size;
-	inflateInit(&stream);
+	xinflateInit(&stream);
 	st = inflate(&stream, Z_FINISH);
 	if ((st != Z_STREAM_END) || stream.total_out != inflated_size) {
 		free(out);
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index e851534..09576c6 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -195,7 +195,7 @@ static int check_pack_inflate(struct packed_git *p,
 	int st;
 
 	memset(&stream, 0, sizeof(stream));
-	inflateInit(&stream);
+	xinflateInit(&stream);
 	do {
 		in = use_pack(p, w_curs, offset, &stream.avail_in);
 		stream.next_in = in;
diff --git a/builtin-unpack-objects.c b/builtin-unpack-objects.c
index 47ed610..cb9edac 100644
--- a/builtin-unpack-objects.c
+++ b/builtin-unpack-objects.c
@@ -99,7 +99,7 @@ static void *get_data(unsigned long size)
 	stream.avail_out = size;
 	stream.next_in = fill(1);
 	stream.avail_in = len;
-	inflateInit(&stream);
+	xinflateInit(&stream);
 
 	for (;;) {
 		int ret = inflate(&stream, 0);
diff --git a/cache.h b/cache.h
index 231c06d..7d5c38d 100644
--- a/cache.h
+++ b/cache.h
@@ -17,6 +17,7 @@
 #if defined(NO_DEFLATE_BOUND) || ZLIB_VERNUM < 0x1200
 #define deflateBound(c,s)  ((s) + (((s) + 7) >> 3) + (((s) + 63) >> 6) + 11)
 #endif
+extern void xinflateInit(z_stream *stream);
 
 #if defined(DT_UNKNOWN) && !defined(NO_D_TYPE_IN_DIRENT)
 #define DTYPE(de)	((de)->d_type)
diff --git a/http-push.c b/http-push.c
index a4b7d08..906ca48 100644
--- a/http-push.c
+++ b/http-push.c
@@ -269,7 +269,7 @@ static void start_fetch_loose(struct transfer_request *request)
 
 	memset(&request->stream, 0, sizeof(request->stream));
 
-	inflateInit(&request->stream);
+	xinflateInit(&request->stream);
 
 	git_SHA1_Init(&request->c);
 
@@ -310,7 +310,7 @@ static void start_fetch_loose(struct transfer_request *request)
 	   file; also rewind to the beginning of the local file. */
 	if (prev_read == -1) {
 		memset(&request->stream, 0, sizeof(request->stream));
-		inflateInit(&request->stream);
+		xinflateInit(&request->stream);
 		git_SHA1_Init(&request->c);
 		if (prev_posn>0) {
 			prev_posn = 0;
diff --git a/http-walker.c b/http-walker.c
index 7271c7d..6aa8486 100644
--- a/http-walker.c
+++ b/http-walker.c
@@ -142,7 +142,7 @@ static void start_object_request(struct walker *walker,
 
 	memset(&obj_req->stream, 0, sizeof(obj_req->stream));
 
-	inflateInit(&obj_req->stream);
+	xinflateInit(&obj_req->stream);
 
 	git_SHA1_Init(&obj_req->c);
 
@@ -183,7 +183,7 @@ static void start_object_request(struct walker *walker,
 	   file; also rewind to the beginning of the local file. */
 	if (prev_read == -1) {
 		memset(&obj_req->stream, 0, sizeof(obj_req->stream));
-		inflateInit(&obj_req->stream);
+		xinflateInit(&obj_req->stream);
 		git_SHA1_Init(&obj_req->c);
 		if (prev_posn>0) {
 			prev_posn = 0;
diff --git a/index-pack.c b/index-pack.c
index 2931511..c6bfc12 100644
--- a/index-pack.c
+++ b/index-pack.c
@@ -275,7 +275,7 @@ static void *unpack_entry_data(unsigned long offset, unsigned long size)
 	stream.avail_out = size;
 	stream.next_in = fill(1);
 	stream.avail_in = input_len;
-	inflateInit(&stream);
+	xinflateInit(&stream);
 
 	for (;;) {
 		int ret = inflate(&stream, 0);
@@ -382,7 +382,7 @@ static void *get_data_from_pack(struct object_entry *obj)
 	stream.avail_out = obj->size;
 	stream.next_in = src;
 	stream.avail_in = len;
-	inflateInit(&stream);
+	xinflateInit(&stream);
 	while ((st = inflate(&stream, Z_FINISH)) == Z_OK);
 	inflateEnd(&stream);
 	if (st != Z_STREAM_END || stream.total_out != obj->size)
diff --git a/sha1_file.c b/sha1_file.c
index 52d1ead..9aabae2 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1196,7 +1196,7 @@ static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned lon
 	stream->avail_out = bufsiz;
 
 	if (legacy_loose_object(map)) {
-		inflateInit(stream);
+		xinflateInit(stream);
 		return inflate(stream, 0);
 	}
 
@@ -1217,7 +1217,7 @@ static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned lon
 	/* Set up the stream for the rest.. */
 	stream->next_in = map;
 	stream->avail_in = mapsize;
-	inflateInit(stream);
+	xinflateInit(stream);
 
 	/* And generate the fake traditional header */
 	stream->total_out = 1 + snprintf(buffer, bufsiz, "%s %lu",
@@ -1348,7 +1348,7 @@ unsigned long get_size_from_delta(struct packed_git *p,
 	stream.next_out = delta_head;
 	stream.avail_out = sizeof(delta_head);
 
-	inflateInit(&stream);
+	xinflateInit(&stream);
 	do {
 		in = use_pack(p, w_curs, curpos, &stream.avail_in);
 		stream.next_in = in;
@@ -1585,7 +1585,7 @@ static void *unpack_compressed_entry(struct packed_git *p,
 	stream.next_out = buffer;
 	stream.avail_out = size;
 
-	inflateInit(&stream);
+	xinflateInit(&stream);
 	do {
 		in = use_pack(p, w_curs, curpos, &stream.avail_in);
 		stream.next_in = in;
diff --git a/wrapper.c b/wrapper.c
index 93562f0..f255eef 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -196,3 +196,23 @@ int xmkstemp(char *template)
 		die("Unable to create temporary file: %s", strerror(errno));
 	return fd;
 }
+
+void xinflateInit(z_stream *stream)
+{
+	switch (inflateInit(stream)) {
+	case Z_OK:
+		return;
+
+	case Z_MEM_ERROR:
+		release_pack_memory(128 * 1024, -1);
+		if (inflateInit(stream) == Z_OK)
+			return;
+		die("Out of memory? inflateInit failed");
+
+	case Z_VERSION_ERROR:
+		die("Wrong zlib version? inflateInit failed");
+
+	default:
+		die("Unknown inflateInit failure");
+	}
+}
-- 
1.6.1.141.gfe98e

^ permalink raw reply related

* Re: Public repro case! Re: [PATCH/RFC] Allow writing loose objects that are corrupted in a pack file
From: Shawn O. Pearce @ 2009-01-08  3:13 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: R. Tyler Ballance, Nicolas Pitre, Jan Krüger, Git ML, kb
In-Reply-To: <alpine.LFD.2.00.0901071904380.3283@localhost.localdomain>

Linus Torvalds <torvalds@linux-foundation.org> wrote:
> The Z_STREAM_ERROR probably comes from inflate() itself - and could very 
> easily be due to a allocation error in inflateInit leaving the stream data 
> incomplete.
> 
> Let me try wrapping that dang thing and send a patch. 

Yup.  I'm actually doing the same thing...

-- 
Shawn.

^ permalink raw reply

* Re: Public repro case! Re: [PATCH/RFC] Allow writing loose objects that are corrupted in a pack file
From: Linus Torvalds @ 2009-01-08  3:06 UTC (permalink / raw)
  To: Shawn O. Pearce
  Cc: R. Tyler Ballance, Nicolas Pitre, Jan Krüger, Git ML, kb
In-Reply-To: <20090108030115.GF10790@spearce.org>



On Wed, 7 Jan 2009, Shawn O. Pearce wrote:
> 
> Ok, well, in this case I've been able to reproduce a zlib inflate
> failure on the base object in a 2 deep delta chain.  We got back:
> 
>   #define Z_STREAM_ERROR (-2)
> 
> this causes the buffer to be freed and NULL to come back out of
> unpack_compressed_entry(), and then everything is corrupt...

I bet you actually got an earlier error already from the inflateInit. 

The Z_STREAM_ERROR probably comes from inflate() itself - and could very 
easily be due to a allocation error in inflateInit leaving the stream data 
incomplete.

Let me try wrapping that dang thing and send a patch. 

		Linus

^ permalink raw reply

* Re: Error : git svn fetch
From: Eric Wong @ 2009-01-08  2:55 UTC (permalink / raw)
  To: chongyc; +Cc: git
In-Reply-To: <E48CF49FF0FE4F96BE206B2689165AF9@VMware>

chongyc <chongyc27@gmail.com> wrote:
> Hi
> 
> I found that 'git svn fetch' failed in cloning the hudson svn reposotory.
> 
> I want to git-clone the svn repository
> 
> svn repository URL : https://svn.dev.java.net/svn/hudson/
> username : guest
> password :
> 
> 
> So I run followings to git-clone
> 
> [root@localhost hudson]# git --version
> git version 1.6.0.6
> [root@localhost hudson]# git svn init -T trunk -t tags -b branches 
> https://svn.dev.java.net/svn/hudson/
> [root@localhost hudson]# git svn fetch
> Found possible branch point: 
> https://svn.dev.java.net/svn/hudson/tags/hudson-1_230 => 
> https://svn.dev.java.net/svn/hudson/branches/buildnav-1636, 10490
> Initializing parent: buildnav-1636@10490
> Found possible branch point: 
> https://svn.dev.java.net/svn/hudson/trunk/hudson/main => 
> https://svn.dev.java.net/svn/hudson/tags/hudson-1_230, 10450
> Initializing parent: buildnav-1636@10450
> Found branch parent: (buildnav-1636@10490) a1c395e5db063ca1ffbbe008e309c5
> 11d56219e0
> Following parent with do_switch
> remoting/pom.xml was not found in commit 
> a1c395e5db063ca1ffbbe008e309c511d56219e0 (r10447)
> [root@localhost hudson]#
> 
> What shall I do to git-clone it ?
> 
> Please help me

Hi, sorry for the late reply, I've been very distracted.

Looking at the hudson repository, the layout is non-standard and very
complex, with subdirectories being branched and tagged all over.  The
standard globbing that git-svn uses for most repositories does won't
work.  You'll have to map things manually:

[svn-remote "svn"]
        url = https://svn.dev.java.net/svn/hudson
        fetch = trunk/hudson:refs/remotes/trunk
        fetch = branches/tom:refs/remotes/tom
	...

Alternately, you could just clone the root and have all the branches all
over the place in one tree (your eventually working copy will be huge).

  git svn clone https://svn.dev.java.net/svn/hudson


Basically this is the equivalent of:

  svn co https://svn.dev.java.net/svn/hudson

Except you'll have the full history.

-- 
Eric Wong

^ 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