Git development
 help / color / mirror / Atom feed
* Re: Remote git-cat-file?
From: Jakub Narebski @ 2006-05-28 12:00 UTC (permalink / raw)
  To: git
In-Reply-To: <loom.20060528T124835-757@post.gmane.org>

Elrond wrote:

> Linus Torvalds <torvalds <at> osdl.org> writes:
>> 
>> Just out of interest, why would you ever want to just look at a single 
>> object?
[...]
>
> The other possible use for remote git-cat-file:
> It might be useful in shallow repos to selectively load objects "on demand".
> (In fact, I screwed my repo by trying to make it shallow.)

It would be nice I think to be able to have remote alternatives, loading
(downloading and saving) objects "on demand" ("lazy alternatives"). Not necessary
only with "shallow repo"/"shallow clone".

-- 
Jakub Narebski
Warsaw, Poland

^ permalink raw reply

* Re: [PATCH] Fixed Cygwin CR-munging problem in mailsplit
From: Christopher Faylor @ 2006-05-28 16:39 UTC (permalink / raw)
  To: Zakirov, Salikh, git
In-Reply-To: <E124AAE027DA384D8B919F93E4D8C70801EFFB52@mssmsx402nb>

On Sun, May 28, 2006 at 12:57:35AM +0400, Zakirov, Salikh wrote:
>Junio C Hamano <junkio@cox.net> writes:
>> So even in this modern day, preserving CRLF is not
>> something that happens by default -- you would need to make sure
>> that everybody on your mailpath to the recipient is set up the
>> right way.
>
>> So now I am less in favor of the change than when I wrote that
>> response.
>
>I understand this reasoning, and I am not sure if the fix is correct
>from the "GIT world" point of view.
>
>However, I believe that the command sequence git-format-patch, git-am
>without any e-mail transfer in between and in the same repository
>should work perfectly regardless of the contents of the files, 
>no matter if they are binary, text, or "CRLF text" or even 
>"broken LF and CRLF text". This is a requirement from a nasty "real
>world".
>
>Junio, could you point at a right place to fix to get git-format-patch, 
>git-am sequence work flawlessly on Cygwin?
>
>By the way, the change affects only non-Unix users, as fopen(..., "rt")
>is equivalent to fopen(..., "rb") on all Unixes anyway.

But fopen(..., "r") is not equivalent to fopen(..., "rb") on Cygwin.

Wouldn't you want to add the "b" there to be assured of a binary open?

cgf

^ permalink raw reply

* Re: [PATCH] new environment variable GIT_TEMPLATE_DIR to override default template
From: Junio C Hamano @ 2006-05-28 17:33 UTC (permalink / raw)
  To: Matthias Lederhofer; +Cc: git
In-Reply-To: <E1Fk3yR-0006Gd-36@moooo.ath.cx>

Matthias Lederhofer <matled@gmx.net> writes:

> directory and --template=<template_directory> option for to git-clone
>
> ---
>> Please document such changes, in the spirit of
>
> That's right, here are both patches in one because the second patch
> would also change the documentation of the first one.

Thanks.

 * Please don't put the beginning of one sentence on Subject
   line and start the body of the message with the rest of that
   sentence.  Instead, come up with a short (meaning "fits on
   the Subject line without wrapping with 80-column terminal")
   title that describes what the patch does -- it is a good
   sanity check to make sure your patch is doing one thing and
   one thing only, instead of mixing unrelated mess together.

 * Please sign-off your patch.

 * Please test your patch for existing usage, not just for the
   new usage you added, to avoid regressions.

I like the part to let git-clone pass --template down to git-init-db,
but once it is in place I doubt you would still need GIT_TEMPLATE_DIR.
I'd rather not to introduce new environment variables if we can
avoid them.

> diff --git a/git-clone.sh b/git-clone.sh
> index d96894d..1c7ae12 100755
> --- a/git-clone.sh
> +++ b/git-clone.sh
> @@ -102,6 +102,7 @@ quiet=
>  local=no
>  use_local=no
>  local_shared=no
> +template=
>  no_checkout=
>  upload_pack=
>  bare=
> @@ -120,6 +121,8 @@ while
>  	*,-l|*,--l|*,--lo|*,--loc|*,--loca|*,--local) use_local=yes ;;
>          *,-s|*,--s|*,--sh|*,--sha|*,--shar|*,--share|*,--shared) 
>            local_shared=yes; use_local=yes ;;
> +	*,--template=*)
> +	  template="$1" ;;
>  	*,-q|*,--quiet) quiet=-q ;;
>  	*,--use-separate-remote)
>  		use_separate_remote=t ;;

Here, $template is either empty string "", or "--template=dir"
after argument parsing.  But then it does this:

> @@ -203,7 +206,7 @@ trap 'err=$?; cd ..; rm -r "$D"; exit $e
>  case "$bare" in
>  yes) GIT_DIR="$D" ;;
>  *) GIT_DIR="$D/.git" ;;
> -esac && export GIT_DIR && git-init-db || usage
> +esac && export GIT_DIR && git-init-db "$template" || usage

which I suspect would make git-init-db barf if you did not pass
any --template=foo option to git-clone.  Did you test your patch?

So I'd do it like this instead.

-- >8 --
[PATCH] Let git-clone to pass --template=dir option to git-init-db.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---
 Documentation/git-clone.txt |    9 +++++++--
 git-clone.sh                |   10 ++++++++--
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index b333f51..94d9393 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -9,8 +9,8 @@ git-clone - Clones a repository
 SYNOPSIS
 --------
 [verse]
-'git-clone' [-l [-s]] [-q] [-n] [--bare] [-o <name>] [-u <upload-pack>]
-	  [--reference <repository>]
+'git-clone' [--template=<template_directory>] [-l [-s]] [-q] [-n] [--bare]
+	  [-o <name>] [-u <upload-pack>] [--reference <repository>]
 	  <repository> [<directory>]
 
 DESCRIPTION
@@ -89,6 +89,11 @@ OPTIONS
 	the command to specify non-default path for the command
 	run on the other end.
 
+--template=<template_directory>::
+	Specify the directory from which templates will be used;
+	if unset the templates are taken from the installation
+	defined default, typically `/usr/share/git-core/templates`.
+
 <repository>::
 	The (possibly remote) repository to clone from.  It can
 	be any URL git-fetch supports.
diff --git a/git-clone.sh b/git-clone.sh
index d96894d..de59904 100755
--- a/git-clone.sh
+++ b/git-clone.sh
@@ -9,7 +9,7 @@ # See git-sh-setup why.
 unset CDPATH
 
 usage() {
-	echo >&2 "Usage: $0 [--use-separate-remote] [--reference <reference-repo>] [--bare] [-l [-s]] [-q] [-u <upload-pack>] [--origin <name>] [-n] <repo> [<dir>]"
+	echo >&2 "Usage: $0 [--template=<template_directory>] [--use-separate-remote] [--reference <reference-repo>] [--bare] [-l [-s]] [-q] [-u <upload-pack>] [--origin <name>] [-n] <repo> [<dir>]"
 	exit 1
 }
 
@@ -102,6 +102,7 @@ quiet=
 local=no
 use_local=no
 local_shared=no
+unset template
 no_checkout=
 upload_pack=
 bare=
@@ -120,6 +121,11 @@ while
 	*,-l|*,--l|*,--lo|*,--loc|*,--loca|*,--local) use_local=yes ;;
         *,-s|*,--s|*,--sh|*,--sha|*,--shar|*,--share|*,--shared) 
           local_shared=yes; use_local=yes ;;
+	1,--template) usage ;;
+	*,--template)
+		shift; template="--template=$1" ;;
+	*,--template=*)
+	  template="$1" ;;
 	*,-q|*,--quiet) quiet=-q ;;
 	*,--use-separate-remote)
 		use_separate_remote=t ;;
@@ -203,7 +209,7 @@ trap 'err=$?; cd ..; rm -r "$D"; exit $e
 case "$bare" in
 yes) GIT_DIR="$D" ;;
 *) GIT_DIR="$D/.git" ;;
-esac && export GIT_DIR && git-init-db || usage
+esac && export GIT_DIR && git-init-db ${template+"$template"} || usage
 case "$bare" in
 yes)
 	GIT_DIR="$D" ;;
-- 
1.3.3.g2a0a

^ permalink raw reply related

* Re: Remote git-cat-file?
From: Junio C Hamano @ 2006-05-28 17:38 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <e5c3c5$i47$1@sea.gmane.org>

Jakub Narebski <jnareb@gmail.com> writes:

> It would be nice I think to be able to have remote alternatives,...

Yup, I think I've mentioned that one as one of "the mostly
unimplementable but would be very nice to have crazy wishlist
items" some time ago.  What people would want is not a "shallow"
clone, but a "lazy" clone, and in the ideal world that would
obviously be a nice thing to have.

^ permalink raw reply

* [PATCH 0/1] Tried to fix git-svn's handling of filenames with embedded '@'.
From: Seth Falcon @ 2006-05-28 18:15 UTC (permalink / raw)
  To: git

Hi Eric, all,

I decided to give git-svn a try for a large svn project and during my
first git-svn fetch operation, I'm seeing a failure that seems related
to recent changes in the handling of svn keywords.

Here is the traceback:

svn: Syntax error parsing revision '.R'
256 at /home/sfalcon/util/scm/bin/git-svn line 1124
        main::safe_qx('svn', 'propget', 'svn:keywords', 'Biobase/inst/Code/R/get@PKGNAME@.R') called at /home/sfalcon/util/scm/bin/git-svn line 900
        main::do_update_index('ARRAY(0x8395840)', 'add', 'undef')
        called at /home/sfalcon/util/scm/bin/git-svn line 926

Unfortunately, my project has a file named "get@PKGNAME@.R" and svn
thinks the '@.R' part is specifying a revision.  Here comes a patch
that got me going again.  Not sure it is the right fix, nor whether it
covers all places where some action will be needed.

Best,

+ seth

^ permalink raw reply

* Re: [PATCH] new environment variable GIT_TEMPLATE_DIR to override default template
From: Matthias Lederhofer @ 2006-05-28 18:15 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7v4pzadpfr.fsf@assigned-by-dhcp.cox.net>

> I like the part to let git-clone pass --template down to git-init-db,
> but once it is in place I doubt you would still need GIT_TEMPLATE_DIR.
> I'd rather not to introduce new environment variables if we can
> avoid them.

I like the variable because it makes it very easy to change the
default template directory (so I don't have to remember passing
--template every time I clone or create a new repository). But
aliases/default options (~/.git/config thread) this would make this
possible too.

> Here, $template is either empty string "", or "--template=dir"
> after argument parsing.  But then it does this:
> 
> > @@ -203,7 +206,7 @@ trap 'err=$?; cd ..; rm -r "$D"; exit $e
> >  case "$bare" in
> >  yes) GIT_DIR="$D" ;;
> >  *) GIT_DIR="$D/.git" ;;
> > -esac && export GIT_DIR && git-init-db || usage
> > +esac && export GIT_DIR && git-init-db "$template" || usage
> 
> which I suspect would make git-init-db barf if you did not pass
> any --template=foo option to git-clone.  Did you test your patch?

Sorry, I did not run make test and did not test it without the option.
Shall I send a new patch?

^ permalink raw reply

* [PATCH 1/1] Tried to fix git-svn's handling of filenames with embedded '@'.
From: Seth Falcon @ 2006-05-28 18:15 UTC (permalink / raw)
  To: git
In-Reply-To: <m21wuem2xj.fsf@ziti.fhcrc.org>

svn has trouble parsing files with embedded '@' characters.  For
example,

  svn propget svn:keywords foo@bar.c
  svn: Syntax error parsing revision 'bar.c'

I asked about this on #svn and the workaround suggested was to append
an explicit revision specifier:

  svn propget svn:keywords foo@bar.c@BASE

This patch appends '@BASE' to the filename in all calls to 'svn
propget'.
---
 contrib/git-svn/git-svn.perl |    7 ++++---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl
index b3e0684..498ffe0 100755
--- a/contrib/git-svn/git-svn.perl
+++ b/contrib/git-svn/git-svn.perl
@@ -336,7 +336,7 @@ sub show_ignore {
 	my %ign;
 	File::Find::find({wanted=>sub{if(lstat $_ && -d _ && -d "$_/.svn"){
 		s#^\./##;
-		@{$ign{$_}} = safe_qx(qw(svn propget svn:ignore),$_);
+		@{$ign{$_}} = safe_qx(qw(svn propget svn:ignore),$_ . "\@BASE");
 		}}, no_chdir=>1},'.');
 
 	print "\n# /\n";
@@ -860,7 +860,7 @@ sub sys { system(@_) == 0 or croak $? }
 
 sub eol_cp {
 	my ($from, $to) = @_;
-	my $es = safe_qx(qw/svn propget svn:eol-style/, $to);
+	my $es = safe_qx(qw/svn propget svn:eol-style/, $to . "\@BASE");
 	open my $rfd, '<', $from or croak $!;
 	binmode $rfd or croak $!;
 	open my $wfd, '>', $to or croak $!;
@@ -898,7 +898,8 @@ sub do_update_index {
 	while (my $x = <$p>) {
 		chomp $x;
 		if (!$no_text_base && lstat $x && ! -l _ &&
-				safe_qx(qw/svn propget svn:keywords/,$x)) {
+				safe_qx(qw/svn propget svn:keywords/,
+                                        $x . "\@BASE")) {
 			my $mode = -x _ ? 0755 : 0644;
 			my ($v,$d,$f) = File::Spec->splitpath($x);
 			my $tb = File::Spec->catfile($d, '.svn', 'tmp',
-- 
1.3.3.gb931

^ permalink raw reply related

* Re: Remote git-cat-file?
From: Jakub Narebski @ 2006-05-28 18:34 UTC (permalink / raw)
  To: git
In-Reply-To: <7vu07acanv.fsf@assigned-by-dhcp.cox.net>

Junio C Hamano wrote:

> Jakub Narebski <jnareb@gmail.com> writes:
> 
>> It would be nice I think to be able to have remote alternatives,...
> 
> Yup, I think I've mentioned that one as one of "the mostly
> unimplementable but would be very nice to have crazy wishlist
> items" some time ago.  What people would want is not a "shallow"
> clone, but a "lazy" clone, and in the ideal world that would
> obviously be a nice thing to have.

I think that it should be only "commit-lazy", i.e. downloading whole trees,
subtrees, and objects pointed by tags, only not following the parent links
of commits; perhaps also other links to commits (branches, tags, tag
objects).

-- 
Jakub Narebski
Warsaw, Poland

^ permalink raw reply

* Fix memory leak in "git rev-list --objects"
From: Linus Torvalds @ 2006-05-28 18:37 UTC (permalink / raw)
  To: Junio C Hamano, Git Mailing List; +Cc: Martin Langhoff


Martin Langhoff points out that "git repack -a" ends up using up a lot of 
memory for big archives, and that git cvsimport probably should do only 
incremental repacks in order to avoid having repacking flush all the 
caches.

The big majority of the memory usage of repacking is from git rev-list 
tracking all objects, and this patch should go a long way in avoiding the 
excessive memory usage: the bulk of it was due to the object names being 
leaked from the tree parser.

For the historic Linux kernel archive, this simple patch does:

Before:
	/usr/bin/time git-rev-list --all --objects > /dev/null 

	72.45user 0.82system 1:13.55elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
	0inputs+0outputs (0major+125376minor)pagefaults 0swaps

After:
	/usr/bin/time git-rev-list --all --objects > /dev/null 

	75.22user 0.48system 1:16.34elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
	0inputs+0outputs (0major+43921minor)pagefaults 0swaps

where we do end up wasting a bit of time on some extra strdup()s (which 
could be avoided, but that would require tracking where the pathnames came 
from), but we avoid a lot of memory usage.

Minor page faults track maximum RSS very closely (each page fault maps in 
one page into memory), so the reduction from 125376 page faults to 43921 
means a rough reduction of VM footprint from almost half a gigabyte to 
about a third of that. Those numbers were also double-checked by looking 
at "top" while the process was running.

(Side note: at least part of the remaining VM footprint is the mapping of 
the 177MB pack-file, so the remaining memory use is at least partly "well 
behaved" from a project caching perspective).

For the current git archive itself, the memory usage for a "--all 
--objects" rev-list invocation dropped from 7128 pages to 2318 (27MB to 
9MB), so the reduction seems to hold for much smaller projects too.

For regular "git-rev-list" usage (ie without the "--objects" flag) this 
patch has no impact.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index f11dbd6..5277d3c 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -103,6 +103,7 @@ static struct object_list **process_blob
 	if (obj->flags & (UNINTERESTING | SEEN))
 		return p;
 	obj->flags |= SEEN;
+	name = strdup(name);
 	return add_object(obj, p, path, name);
 }
 
@@ -122,6 +123,7 @@ static struct object_list **process_tree
 	if (parse_tree(tree) < 0)
 		die("bad tree object %s", sha1_to_hex(obj->sha1));
 	obj->flags |= SEEN;
+	name = strdup(name);
 	p = add_object(obj, p, path, name);
 	me.up = path;
 	me.elem = name;
@@ -134,6 +136,7 @@ static struct object_list **process_tree
 			p = process_tree(entry->item.tree, p, &me, entry->name);
 		else
 			p = process_blob(entry->item.blob, p, &me, entry->name);
+		free(entry->name);
 		free(entry);
 		entry = next;
 	}

^ permalink raw reply related

* [PATCH] git-write-tree writes garbage on sparc64
From: Dennis Stosberg @ 2006-05-28 19:08 UTC (permalink / raw)
  To: git

In the "next" branch, write_index_ext_header() writes garbage on a
64-bit big-endian machine; the written index file will be unreadable.
I noticed this on NetBSD/sparc64. Reproducible with:

$ git init-db
$ :>file
$ git-update-index --add file
$ git-write-tree
$ git-update-index
error: index uses  extension, which we do not understand
fatal: index file corrupt

Signed-off-by: Dennis Stosberg <dennis@stosberg.net>
---
 read-cache.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/read-cache.c b/read-cache.c
index 36bd4ea..c499c51 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -826,7 +826,7 @@ static int ce_write(SHA_CTX *context, in
 }
 
 static int write_index_ext_header(SHA_CTX *context, int fd,
-				  unsigned long ext, unsigned long sz)
+				  unsigned int ext, unsigned int sz)
 {
 	ext = htonl(ext);
 	sz = htonl(sz);
-- 
1.3.3.g3c38f

^ permalink raw reply related

* git-format-patch question
From: Seth Falcon @ 2006-05-28 19:31 UTC (permalink / raw)
  To: git

Hi,

A few questions about git-format-patch:

1. When is one supposed to use --signoff?  I gather the answer is
   project specific, but a statement of what's expected for git
   itself would probably help clarify things for me.

2. How should I add extra notes to an email generated using
   git-format-patch?  Is this in the docs somewhere that I missed?  Is
   there a recommended way to do this?

3. Is signoff broken? I get:

    $ git-format-patch --stdout --signoff master
    fatal: unrecognized argument: --signoff  

   When I pass -s instead of --signoff, I get output, but no patch and
   no signoff looking thing.  Without --signoff and without -s, I get
   reasonable looking output.

Thanks,

+ seth

^ permalink raw reply

* Re: git-format-patch question
From: Junio C Hamano @ 2006-05-28 20:35 UTC (permalink / raw)
  To: Seth Falcon; +Cc: git
In-Reply-To: <m2odxikktm.fsf@ziti.fhcrc.org>

Seth Falcon <sethfalcon@gmail.com> writes:

> 1. When is one supposed to use --signoff?  I gather the answer is
>    project specific, but a statement of what's expected for git
>    itself would probably help clarify things for me.

You shouldn't ;-).  Rather, you should sign-off when you make a
commit, or if you are forwarding somebody else's patch, before
you send the e-mail off.  

> 2. How should I add extra notes to an email generated using
>    git-format-patch?  Is this in the docs somewhere that I missed?  Is
>    there a recommended way to do this?

Read the format-patch output in your e-mail buffer and edit just
like you edit any text you write in your e-mail.

^ permalink raw reply

* Re: [PATCH 1/1] Tried to fix git-svn's handling of filenames with embedded '@'.
From: Junio C Hamano @ 2006-05-28 20:42 UTC (permalink / raw)
  To: Eric Wong; +Cc: git, Seth Falcon
In-Reply-To: <m2verqkobr.fsf@ziti.fhcrc.org>

Seth Falcon <sethfalcon@gmail.com> writes:

> svn has trouble parsing files with embedded '@' characters.  For
> example,
>
>   svn propget svn:keywords foo@bar.c
>   svn: Syntax error parsing revision 'bar.c'
>
> I asked about this on #svn and the workaround suggested was to append
> an explicit revision specifier:
>
>   svn propget svn:keywords foo@bar.c@BASE
>
> This patch appends '@BASE' to the filename in all calls to 'svn
> propget'.

Eric, this sounds sane to me.  Ack?

^ permalink raw reply

* [PATCH] git-fetch: Shell syntax fix for NetBSD
From: Dennis Stosberg @ 2006-05-28 20:45 UTC (permalink / raw)
  To: git

NetBSD's default shell does not accept an opening parenthesis in
a case switch.

$ ./git-fetch
./git-fetch: 219: Syntax error: word unexpected (expecting ")")

---
With this change applied to the next branch, all tests complete
successfully on NetBSD 3.0 without having bash installed.

 git-fetch.sh |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/git-fetch.sh b/git-fetch.sh
index 280f62e..b8092a6 100755
--- a/git-fetch.sh
+++ b/git-fetch.sh
@@ -216,7 +216,7 @@ then
 	          while read sha1 name
 		  do
 			case "$name" in
-			(*^*) continue ;;
+			*^*) continue ;;
 			esac
 		  	if git-check-ref-format "$name"
 			then
-- 
1.3.3.g3c38f

^ permalink raw reply related

* Re: [PATCH] git-fetch: Shell syntax fix for NetBSD
From: Junio C Hamano @ 2006-05-28 21:04 UTC (permalink / raw)
  To: Dennis Stosberg; +Cc: git
In-Reply-To: <20060528204510.G51ab1cf8@leonov.stosberg.net>

Dennis Stosberg <dennis@stosberg.net> writes:

> NetBSD's default shell does not accept an opening parenthesis in
> a case switch.
>
> $ ./git-fetch
> ./git-fetch: 219: Syntax error: word unexpected (expecting ")")
>
> ---
> With this change applied to the next branch, all tests complete
> successfully on NetBSD 3.0 without having bash installed.

Funny.  Without the posixy open parenthesis, bash barfs ;-).

        git-fetch: line 219: syntax error near unexpected token `;;'
        git-fetch: line 219: `                 *^*) continue ;;'

So how about doing this instead?  Does NetBSD default shell
still work with it?

diff --git a/git-fetch.sh b/git-fetch.sh
index 280f62e..69bd810 100755
--- a/git-fetch.sh
+++ b/git-fetch.sh
@@ -211,12 +211,12 @@ # Otherwise we do what we always did.
 reflist=$(get_remote_refs_for_fetch "$@")
 if test "$tags"
 then
-	taglist=$(IFS="	" &&
+	taglist=`IFS="	" &&
 		  git-ls-remote $upload_pack --tags "$remote" |
 	          while read sha1 name
 		  do
 			case "$name" in
-			(*^*) continue ;;
+			*^*) continue ;;
 			esac
 		  	if git-check-ref-format "$name"
 			then
@@ -224,7 +224,7 @@ then
 			else
 			    echo >&2 "warning: tag ${name} ignored"
 			fi
-		  done)
+		  done`
 	if test "$#" -gt 1
 	then
 		# remote URL plus explicit refspecs; we need to merge them.

^ permalink raw reply related

* [PATCH] Classify commands in stg --help output.
From: Yann Dirson @ 2006-05-28 21:25 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: git


Commands will be much easier to find out that way.
Inspiration mostly comes from pg-help.

Signed-off-by: Yann Dirson <ydirson@altern.org>
---

 stgit/main.py |   74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 70 insertions(+), 4 deletions(-)

diff --git a/stgit/main.py b/stgit/main.py
index df4e1f5..83bffb4 100644
--- a/stgit/main.py
+++ b/stgit/main.py
@@ -100,19 +100,85 @@ commands = {
     'uncommit': stgit.commands.uncommit,
     }
 
+# classification: repository, stack, patch, working copy
+repocommands = (
+    'branch',
+    'clone',
+    'id'
+    )
+stackcommands = (
+    'applied',
+    'clean',
+    'commit',
+    'goto',
+    'init',
+    'pop',
+    'pull',
+    'push',
+    'series',
+    'top',
+    'unapplied',
+    'uncommit'
+    )
+patchcommands = (
+    'delete',
+    'export',
+    'files',
+    'fold',
+    'import',
+    'mail',
+    'new',
+    'pick',
+    'refresh',
+    'rename',
+    'show'
+    )
+wccommands = (
+    'add',
+    'diff',
+    'patches',
+    'resolved',
+    'rm',
+    'status'
+    )
+
+def _print_helpstring(cmd):
+    print '  ' + cmd + ' ' * (12 - len(cmd)) + commands[cmd].help
+    
 def print_help():
     print 'usage: %s <command> [options]' % os.path.basename(sys.argv[0])
     print
-    print 'commands:'
+    print 'Generic commands:'
     print '  help        print the detailed command usage'
     print '  version     display version information'
     print '  copyright   display copyright information'
-    print
-
+    # unclassified commands if any
     cmds = commands.keys()
     cmds.sort()
     for cmd in cmds:
-        print '  ' + cmd + ' ' * (12 - len(cmd)) + commands[cmd].help
+        if not cmd in repocommands and not cmd in stackcommands \
+               and not cmd in patchcommands and not cmd in wccommands:
+            _print_helpstring(cmd)
+    print
+
+    print 'Repository commands:'
+    for cmd in repocommands:
+        _print_helpstring(cmd)
+    print
+    
+    print 'Stack commands:'
+    for cmd in stackcommands:
+        _print_helpstring(cmd)
+    print
+
+    print 'Patch commands:'
+    for cmd in patchcommands:
+        _print_helpstring(cmd)
+    print
+
+    print 'Working-copy commands:'
+    for cmd in wccommands:
+        _print_helpstring(cmd)
 
 #
 # The main function (command dispatcher)

^ permalink raw reply related

* Re: [PATCH] git-fetch: Shell syntax fix for NetBSD
From: Dennis Stosberg @ 2006-05-28 21:28 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vbqthdfpa.fsf@assigned-by-dhcp.cox.net>

Junio C Hamano wrote:

> Funny.  Without the posixy open parenthesis, bash barfs ;-).
> 
>         git-fetch: line 219: syntax error near unexpected token `;;'
>         git-fetch: line 219: `                 *^*) continue ;;'
> 
> So how about doing this instead?  Does NetBSD default shell
> still work with it?

This looked so simple that I didn't notice the command
substitution...

Yes, your version works correctly here.

Regards,
Dennis

^ permalink raw reply

* [PATCH] git-receive-pack needs to set umask(2)
From: Michael Richardson @ 2006-05-28 21:31 UTC (permalink / raw)
  To: git

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


If there is another way to solve this, please let me know.
Wrapping git-receive-pack with a shell script to call umask seemed like too
global a change.
(also http://git.openswan.org/git#umask_hack)

When working with a common git repository, not all users are always clueful
enough to set their umask properly --- nor should the default for the user
always be so permissive.

This change adds $GIT_DIR/umask to contain a single line, an integer
which will be fed to umask(). This should also work for the git daemon,
which I personally do not use, so this may be inappropriate.

Signed-off-by: Michael Richardson <mcr@xelerance.com>

---

8698daf8fedc8618593ec44574df1efb9f31db84
 Documentation/git-receive-pack.txt |    3 +++
 cache.h                            |    1 +
 path.c                             |    2 ++
 setup.c                            |   19 +++++++++++++++++++
 4 files changed, 25 insertions(+), 0 deletions(-)

8698daf8fedc8618593ec44574df1efb9f31db84
diff --git a/Documentation/git-receive-pack.txt b/Documentation/git-receive-pack.txt
index 60debca..d3a8c11 100644
--- a/Documentation/git-receive-pack.txt
+++ b/Documentation/git-receive-pack.txt
@@ -74,6 +74,9 @@ packed and is served via a dumb transpor
 There are other real-world examples of using update and
 post-update hooks found in the Documentation/howto directory.
 
+The file $GIT_DIR/umask, if it exists will be opened, and the integer found
+in it will be used to initialize the umask(2) for subsequent file creation
+operations. 
 
 OPTIONS
 -------
diff --git a/cache.h b/cache.h
index 3a46fb9..65d5124 100644
--- a/cache.h
+++ b/cache.h
@@ -355,6 +355,7 @@ extern int git_config_bool(const char *,
 extern int git_config_set(const char *, const char *);
 extern int git_config_set_multivar(const char *, const char *, const char *, int);
 extern int check_repository_format_version(const char *var, const char *value);
+extern void setup_umask();
 
 #define MAX_GITNAME (1000)
 extern char git_default_email[MAX_GITNAME];
diff --git a/path.c b/path.c
index 334b2bd..571ff01 100644
--- a/path.c
+++ b/path.c
@@ -244,6 +244,8 @@ char *enter_repo(char *path, int strict)
 	if (access("objects", X_OK) == 0 && access("refs", X_OK) == 0 &&
 	    validate_symref("HEAD") == 0) {
 		putenv("GIT_DIR=.");
+
+		setup_umask();
 		check_repository_format();
 		return path;
 	}
diff --git a/setup.c b/setup.c
index fe7f884..2129125 100644
--- a/setup.c
+++ b/setup.c
@@ -228,6 +228,25 @@ int check_repository_format_version(cons
        return 0;
 }
 
+void setup_umask(void)
+{
+	FILE *f;
+
+	f = fopen(git_path("umask"), "r");
+	if(f != NULL) {
+		char maskstr[32];
+		if(fgets(maskstr, sizeof(maskstr), f) != NULL) {
+			char *foo;
+			unsigned int mask = strtoul(maskstr, &foo, 0);
+			
+			if(foo != maskstr) {
+				umask(mask);
+			}
+		}
+		fclose(f);
+	}
+}
+
 int check_repository_format(void)
 {
 	git_config(check_repository_format_version);
-- 
1.3.GIT





-- 
]       ON HUMILITY: to err is human. To moo, bovine.           |  firewalls  [
]   Michael Richardson,    Xelerance Corporation, Ottawa, ON    |net architect[
] mcr@xelerance.com      http://www.sandelman.ottawa.on.ca/mcr/ |device driver[
] panic("Just another Debian GNU/Linux using, kernel hacking, security guy"); [

    "The Microsoft _Get the Facts CD_ does not work on Linux." - orospakr


[-- Attachment #2: Type: application/pgp-signature, Size: 482 bytes --]

^ permalink raw reply related

* [PATCH] Support for configurable git command aliases
From: Petr Baudis @ 2006-05-28 21:59 UTC (permalink / raw)
  To: Horst von Brand
  Cc: Linus Torvalds, Pavel Roskin, Timo Hirvonen, Anand Kumria, git
In-Reply-To: <200605271252.k4RCqZhR003192@laptop11.inf.utfsm.cl>

Dear diary, on Sat, May 27, 2006 at 02:52:35PM CEST, I got a letter
where Horst von Brand <vonbrand@inf.utfsm.cl> said that...
> > So they would do "alias cvs git" in a desperate attempt to save themselves 
> > from CVS, and then add
> > 
> > 	[alias "co"]
> > 		cmd = commit -a
> 
> I don't like this syntax. What other stuff (beside "cmd") would be under
> "[alias "co"]? Why not simply:
> 
>         [alias]
> 		co = commit -a
> 		publish = push public.site.com:/pub/scm/my-public-repo

Nice, I like this.

Well, the following isn't exactly the nicest code I have ever written...
But it seems to work. ;-)

---

This patch adds support for configurable aliases for git commands -
"alias.WHATEVER = which ever" will kick in when you do "git WHATEVER"
and substitute WHATEVER with "which ever" (splitted to arguments at
whitespaces).

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

 Documentation/config.txt |    5 ++++
 Documentation/git.txt    |    3 +++
 git.c                    |   52 ++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index d1a4bec..ce616e3 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -83,6 +83,11 @@ core.warnAmbiguousRefs::
 	If true, git will warn you if the ref name you passed it is ambiguous
 	and might match multiple refs in the .git/refs/ tree. True by default.
 
+alias.*::
+	Command aliases for the gitlink:git[1] command wrapper - e.g.
+	after defining "alias.last = cat-file commit HEAD", the invocation
+	"git last" is equivalent to "git cat-file commit HEAD".
+
 apply.whitespace::
 	Tells `git-apply` how to handle whitespaces, in the same way
 	as the '--whitespace' option. See gitlink:git-apply[1].
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 24ca55d..e474bdf 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -21,6 +21,9 @@ link:everyday.html[Everyday Git] for a u
 "man git-commandname" for documentation of each command.  CVS users may
 also want to read link:cvs-migration.html[CVS migration].
 
+The COMMAND is either a name of a Git command (see below) or an alias
+as defined in the configuration file (see gitlink:git-repo-config[1]).
+
 OPTIONS
 -------
 --version::
diff --git a/git.c b/git.c
index 10ea934..0d9cd0e 100644
--- a/git.c
+++ b/git.c
@@ -10,6 +10,7 @@ #include <limits.h>
 #include <stdarg.h>
 #include "git-compat-util.h"
 #include "exec_cmd.h"
+#include "cache.h" /* setup_git_directory_gently() */
 
 #include "builtin.h"
 
@@ -87,13 +88,27 @@ static void handle_internal_command(int 
 	}
 }
 
+static const char *cmd;
+static char *cmdalias;
+
+int git_alias_config(const char *var, const char *value)
+{
+	if (strncmp(var, "alias.", 6))
+		return 0;
+	var += /* strlen("alias.") */ 6;
+	if (!strcmp(var, cmd))
+		cmdalias = strdup(value);
+	return 0;
+}
+
 int main(int argc, const char **argv, char **envp)
 {
-	const char *cmd = argv[0];
-	char *slash = strrchr(cmd, '/');
+	char *slash = strrchr(argv[0], '/');
 	char git_command[PATH_MAX + 1];
 	const char *exec_path = NULL;
 
+	cmd = argv[0];
+
 	/*
 	 * Take the basename of argv[0] as the command
 	 * name, and the dirname as the default exec_path
@@ -165,6 +180,39 @@ int main(int argc, const char **argv, ch
 	}
 	argv[0] = cmd;
 
+	/* Is this an alias? */
+	{
+		/* XXX: We do a redundant git directory detection. */
+		int nongit = 0;
+		const char *subdir = setup_git_directory_gently(&nongit);
+
+		if (!nongit) {
+			git_config(git_alias_config);
+			if (cmdalias) {
+				/* More than the worst case: */
+				const char **argv2 = malloc((strlen(cmdalias) + argc) * sizeof(char*));
+				int argc2 = 0, i = 1;
+
+				while (cmdalias && *cmdalias) {
+					argv2[argc2++] = strsep(&cmdalias, " \t");
+					if (cmdalias)
+						while (*cmdalias == ' ' || *cmdalias == '\t')
+							cmdalias++;
+				}
+				while (i < argc) {
+					argv2[argc2++] = argv[i++];
+				}
+				argv2[argc2] = NULL;
+				argv = argv2;
+				argc = argc2;
+			}
+		}
+
+		/* Go back so that the commands start with clean table */
+		if (subdir)
+			chdir(subdir);
+	}
+
 	/*
 	 * We search for git commands in the following order:
 	 *  - git_exec_path()


-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
A person is just about as big as the things that make them angry.

^ permalink raw reply related

* Re: [PATCH] git-receive-pack needs to set umask(2)
From: Jakub Narebski @ 2006-05-28 22:00 UTC (permalink / raw)
  To: git
In-Reply-To: <v0irnpn8ea.fsf@marajade.sandelman.ca>

Michael Richardson wrote:

> This change adds $GIT_DIR/umask to contain a single line, an integer
> which will be fed to umask(). This should also work for the git daemon,
> which I personally do not use, so this may be inappropriate.

Shouldn't it be done rather via $GIT_DIR/config file, and 
git-repo-config? I.e. instead of adding new file to repository layout,
$GIT_DIR/umask, add core.umask to git configuration?

-- 
Jakub Narebski
Warsaw, Poland

^ permalink raw reply

* [PATCH 0/4] Start migrating away from the "struct tree_entry" list
From: Linus Torvalds @ 2006-05-28 22:03 UTC (permalink / raw)
  To: Junio C Hamano, Git Mailing List


The old "tree.h" parsing logic (before I did the "tree-walk" tree buffer 
parser) would generate a list of "struct tree_entry" objects, which was 
basically a simpler-to-walk version of the raw tree buffer.

Now, the problem with that simpler-to-walk version is that it's a lot less 
efficient than just walking the raw tree buffer in-place, and a lot of the 
core git tree walkers already use the much more efficient in-place 
tree-walker interfaces. Which means that we have _two_ independent ways of 
walking the tree. Very annoying.

This series of four patches (on top of my trivial memory leak fix for git 
rev-list) gets rid of the tree-entry list from tree parsing, and converts 
most users over to use the tree-walker, and has a small compatibility 
helper function to keep some users that are hard to convert using what is 
now obviously just a temporary list.

Apart from being one more step in the direction of cleaning up tree 
walking, it also makes things more efficient, by not needlessly creating 
that silly list that most users don't actually want. I used the same test 
vector as I did for the git rev-list leaker: doing a

	git-rev-list --all --objects

on the historical kernel archive (that one has 566k objects and is more 
than twice the size of the current kernel git tree). The series brings 
that down from

	74.67user 0.45system 1:15.43elapsed

to

	62.50user 0.41system 1:02.93elapsed

for me.

NOTE! I think the git-rev-list leak fix can go into the main tree 
immediately, but this series should probably be kept in "next" for a 
while, just to verify that it all is good..

		Linus

^ permalink raw reply

* Re: [PATCH] git-receive-pack needs to set umask(2)
From: Petr Baudis @ 2006-05-28 22:06 UTC (permalink / raw)
  To: Michael Richardson; +Cc: git
In-Reply-To: <v0irnpn8ea.fsf@marajade.sandelman.ca>

Dear diary, on Sun, May 28, 2006 at 11:31:41PM CEST, I got a letter
where Michael Richardson <mcr@sandelman.ottawa.on.ca> said that...
> If there is another way to solve this, please let me know.

Well, you didn't write what do you actually want to solve. Why do you
need to fiddle with the umask at all?

The object database is considered "append-only" unless you do git-prune
(and you should better not let anyone do that), thus it's enough if you
set all directories group-writable. Other than access the object
database, the users probably only want to update the refs - the solution
is to make refs/heads/ and refs/tags/ group-writable and setgid. This is
also what git-init-db --shared (or tools like cg-admin-setuprepo) should
already set up for you.

So, what did break?

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
A person is just about as big as the things that make them angry.

^ permalink raw reply

* [PATCH 1/4] Add raw tree buffer info to "struct tree"
From: Linus Torvalds @ 2006-05-28 22:07 UTC (permalink / raw)
  To: Junio C Hamano, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0605281453460.5623@g5.osdl.org>


This allows us to avoid allocating information for names etc, because
we can just use the information from the tree buffer directly.

We still keep the old "tree_entry_list" in struct tree as well, so old 
users aren't affected, apart from the fact that the allocations are 
different (if you free a tree entry, you should no longer free the name 
allocation for it, since it's allocated as part of "tree->buffer")

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

diff --git a/builtin-read-tree.c b/builtin-read-tree.c
index ec40d01..740a8c7 100644
--- a/builtin-read-tree.c
+++ b/builtin-read-tree.c
@@ -38,7 +38,7 @@ static struct tree_entry_list df_conflic
 
 typedef int (*merge_fn_t)(struct cache_entry **src);
 
-static int entcmp(char *name1, int dir1, char *name2, int dir2)
+static int entcmp(const char *name1, int dir1, const char *name2, int dir2)
 {
 	int len1 = strlen(name1);
 	int len2 = strlen(name2);
@@ -66,7 +66,7 @@ static int unpack_trees_rec(struct tree_
 	int src_size = len + 1;
 	do {
 		int i;
-		char *first;
+		const char *first;
 		int firstdir = 0;
 		int pathlen;
 		unsigned ce_size;
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 5277d3c..72c1549 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -136,10 +136,11 @@ static struct object_list **process_tree
 			p = process_tree(entry->item.tree, p, &me, entry->name);
 		else
 			p = process_blob(entry->item.blob, p, &me, entry->name);
-		free(entry->name);
 		free(entry);
 		entry = next;
 	}
+	free(tree->buffer);
+	tree->buffer = NULL;
 	return p;
 }
 
diff --git a/fsck-objects.c b/fsck-objects.c
index 59b2590..a0290b0 100644
--- a/fsck-objects.c
+++ b/fsck-objects.c
@@ -197,17 +197,16 @@ static int fsck_tree(struct tree *item)
 			default:
 				break;
 			}
-			free(last->name);
 			free(last);
 		}
 
 		last = entry;
 	}
-	if (last) {
-		free(last->name);
+	if (last)
 		free(last);
-	}
 	item->entries = NULL;
+	free(item->buffer);
+	item->buffer = NULL;
 
 	retval = 0;
 	if (has_full_path) {
diff --git a/object.c b/object.c
index 4d46e0d..1a7823c 100644
--- a/object.c
+++ b/object.c
@@ -200,8 +200,11 @@ struct object *parse_object(const unsign
 			obj = &blob->object;
 		} else if (!strcmp(type, tree_type)) {
 			struct tree *tree = lookup_tree(sha1);
-			parse_tree_buffer(tree, buffer, size);
 			obj = &tree->object;
+			if (!tree->object.parsed) {
+				parse_tree_buffer(tree, buffer, size);
+				buffer = NULL;
+			}
 		} else if (!strcmp(type, commit_type)) {
 			struct commit *commit = lookup_commit(sha1);
 			parse_commit_buffer(commit, buffer, size);
diff --git a/tree.c b/tree.c
index d599fb5..1e76d9c 100644
--- a/tree.c
+++ b/tree.c
@@ -3,6 +3,7 @@ #include "tree.h"
 #include "blob.h"
 #include "commit.h"
 #include "tag.h"
+#include "tree-walk.h"
 #include <stdlib.h>
 
 const char *tree_type = "tree";
@@ -145,46 +146,45 @@ struct tree *lookup_tree(const unsigned 
 
 int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size)
 {
-	void *bufptr = buffer;
+	struct tree_desc desc;
 	struct tree_entry_list **list_p;
 	int n_refs = 0;
 
 	if (item->object.parsed)
 		return 0;
 	item->object.parsed = 1;
+	item->buffer = buffer;
+	item->size = size;
+
+	desc.buf = buffer;
+	desc.size = size;
+
 	list_p = &item->entries;
-	while (size) {
-		struct object *obj;
+	while (desc.size) {
+		unsigned mode;
+		const char *path;
+		const unsigned char *sha1;
 		struct tree_entry_list *entry;
-		int len = 1+strlen(bufptr);
-		unsigned char *file_sha1 = bufptr + len;
-		char *path = strchr(bufptr, ' ');
-		unsigned int mode;
-		if (size < len + 20 || !path || 
-		    sscanf(bufptr, "%o", &mode) != 1)
-			return -1;
+
+		sha1 = tree_entry_extract(&desc, &path, &mode);
 
 		entry = xmalloc(sizeof(struct tree_entry_list));
-		entry->name = strdup(path + 1);
+		entry->name = path;
+		entry->mode = mode;
 		entry->directory = S_ISDIR(mode) != 0;
 		entry->executable = (mode & S_IXUSR) != 0;
 		entry->symlink = S_ISLNK(mode) != 0;
-		entry->zeropad = *(char *)bufptr == '0';
-		entry->mode = mode;
+		entry->zeropad = *(const char *)(desc.buf) == '0';
 		entry->next = NULL;
 
-		bufptr += len + 20;
-		size -= len + 20;
+		update_tree_entry(&desc);
 
 		if (entry->directory) {
-			entry->item.tree = lookup_tree(file_sha1);
-			obj = &entry->item.tree->object;
+			entry->item.tree = lookup_tree(sha1);
 		} else {
-			entry->item.blob = lookup_blob(file_sha1);
-			obj = &entry->item.blob->object;
+			entry->item.blob = lookup_blob(sha1);
 		}
-		if (obj)
-			n_refs++;
+		n_refs++;
 		*list_p = entry;
 		list_p = &entry->next;
 	}
@@ -206,7 +206,6 @@ int parse_tree(struct tree *item)
 	 char type[20];
 	 void *buffer;
 	 unsigned long size;
-	 int ret;
 
 	if (item->object.parsed)
 		return 0;
@@ -219,9 +218,7 @@ int parse_tree(struct tree *item)
 		return error("Object %s not a tree",
 			     sha1_to_hex(item->object.sha1));
 	}
-	ret = parse_tree_buffer(item, buffer, size);
-	free(buffer);
-	return ret;
+	return parse_tree_buffer(item, buffer, size);
 }
 
 struct tree *parse_tree_indirect(const unsigned char *sha1)
diff --git a/tree.h b/tree.h
index 330ab64..066ac5d 100644
--- a/tree.h
+++ b/tree.h
@@ -12,7 +12,7 @@ struct tree_entry_list {
 	unsigned symlink : 1;
 	unsigned zeropad : 1;
 	unsigned int mode;
-	char *name;
+	const char *name;
 	union {
 		struct object *any;
 		struct tree *tree;
@@ -22,6 +22,8 @@ struct tree_entry_list {
 
 struct tree {
 	struct object object;
+	void *buffer;
+	unsigned long size;
 	struct tree_entry_list *entries;
 };
 

^ permalink raw reply related

* [PATCH 2/4] Make "tree_entry" have a SHA1 instead of a union of object pointers
From: Linus Torvalds @ 2006-05-28 22:10 UTC (permalink / raw)
  To: Junio C Hamano, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0605281453460.5623@g5.osdl.org>


This is preparatory work for further cleanups, where we try to make
tree_entry look more like the more efficient tree-walk descriptor.

Instead of having a union of pointers to blob/tree/objects, this just 
makes "struct tree_entry" have the raw SHA1, and makes all the users use 
that instead (often that implies adding a "lookup_tree(..)" on the sha1, 
but sometimes the user just wanted the SHA1 in the first place, and it 
just avoids an unnecessary indirection).

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

---
 blame.c             |    4 ++--
 builtin-read-tree.c |    7 ++++---
 builtin-rev-list.c  |    4 ++--
 fsck-objects.c      |    1 +
 http-push.c         |    4 ++--
 object.c            |    2 +-
 revision.c          |    4 ++--
 tree.c              |   25 ++++++++++++++-----------
 tree.h              |    8 ++------
 9 files changed, 30 insertions(+), 29 deletions(-)

diff --git a/blame.c b/blame.c
index 99ceea8..88bfec2 100644
--- a/blame.c
+++ b/blame.c
@@ -149,7 +149,7 @@ static void free_patch(struct patch *p)
 	free(p);
 }
 
-static int get_blob_sha1_internal(unsigned char *sha1, const char *base,
+static int get_blob_sha1_internal(const unsigned char *sha1, const char *base,
 				  int baselen, const char *pathname,
 				  unsigned mode, int stage);
 
@@ -178,7 +178,7 @@ static int get_blob_sha1(struct tree *t,
 	return 0;
 }
 
-static int get_blob_sha1_internal(unsigned char *sha1, const char *base,
+static int get_blob_sha1_internal(const unsigned char *sha1, const char *base,
 				  int baselen, const char *pathname,
 				  unsigned mode, int stage)
 {
diff --git a/builtin-read-tree.c b/builtin-read-tree.c
index 740a8c7..f0b8dad 100644
--- a/builtin-read-tree.c
+++ b/builtin-read-tree.c
@@ -160,9 +160,10 @@ #endif
 			}
 
 			if (posns[i]->directory) {
+				struct tree *tree = lookup_tree(posns[i]->sha1);
 				any_dirs = 1;
-				parse_tree(posns[i]->item.tree);
-				subposns[i] = posns[i]->item.tree->entries;
+				parse_tree(tree);
+				subposns[i] = tree->entries;
 				posns[i] = posns[i]->next;
 				src[i + merge] = &df_conflict_entry;
 				continue;
@@ -186,7 +187,7 @@ #endif
 
 			any_files = 1;
 
-			memcpy(ce->sha1, posns[i]->item.any->sha1, 20);
+			memcpy(ce->sha1, posns[i]->sha1, 20);
 			src[i + merge] = ce;
 			subposns[i] = &df_conflict_list;
 			posns[i] = posns[i]->next;
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 72c1549..94f520b 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -133,9 +133,9 @@ static struct object_list **process_tree
 	while (entry) {
 		struct tree_entry_list *next = entry->next;
 		if (entry->directory)
-			p = process_tree(entry->item.tree, p, &me, entry->name);
+			p = process_tree(lookup_tree(entry->sha1), p, &me, entry->name);
 		else
-			p = process_blob(entry->item.blob, p, &me, entry->name);
+			p = process_blob(lookup_blob(entry->sha1), p, &me, entry->name);
 		free(entry);
 		entry = next;
 	}
diff --git a/fsck-objects.c b/fsck-objects.c
index a0290b0..44b6465 100644
--- a/fsck-objects.c
+++ b/fsck-objects.c
@@ -441,6 +441,7 @@ int main(int argc, char **argv)
 {
 	int i, heads;
 
+	track_object_refs = 1;
 	setup_git_directory();
 
 	for (i = 1; i < argc; i++) {
diff --git a/http-push.c b/http-push.c
index b4327d9..f492a5d 100644
--- a/http-push.c
+++ b/http-push.c
@@ -1733,9 +1733,9 @@ static struct object_list **process_tree
 	while (entry) {
 		struct tree_entry_list *next = entry->next;
 		if (entry->directory)
-			p = process_tree(entry->item.tree, p, &me, entry->name);
+			p = process_tree(lookup_tree(entry->sha1), p, &me, entry->name);
 		else
-			p = process_blob(entry->item.blob, p, &me, entry->name);
+			p = process_blob(lookup_blob(entry->sha1), p, &me, entry->name);
 		free(entry);
 		entry = next;
 	}
diff --git a/object.c b/object.c
index 1a7823c..9adc874 100644
--- a/object.c
+++ b/object.c
@@ -9,7 +9,7 @@ struct object **objs;
 static int nr_objs;
 int obj_allocs;
 
-int track_object_refs = 1;
+int track_object_refs = 0;
 
 static int hashtable_index(const unsigned char *sha1)
 {
diff --git a/revision.c b/revision.c
index 2294b16..35f8e3b 100644
--- a/revision.c
+++ b/revision.c
@@ -68,9 +68,9 @@ void mark_tree_uninteresting(struct tree
 	while (entry) {
 		struct tree_entry_list *next = entry->next;
 		if (entry->directory)
-			mark_tree_uninteresting(entry->item.tree);
+			mark_tree_uninteresting(lookup_tree(entry->sha1));
 		else
-			mark_blob_uninteresting(entry->item.blob);
+			mark_blob_uninteresting(lookup_blob(entry->sha1));
 		free(entry);
 		entry = next;
 	}
diff --git a/tree.c b/tree.c
index 1e76d9c..ba8742c 100644
--- a/tree.c
+++ b/tree.c
@@ -8,7 +8,7 @@ #include <stdlib.h>
 
 const char *tree_type = "tree";
 
-static int read_one_entry(unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage)
+static int read_one_entry(const unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage)
 {
 	int len;
 	unsigned int size;
@@ -89,7 +89,7 @@ int read_tree_recursive(struct tree *tre
 				      current->mode, match))
 			continue;
 
-		switch (fn(current->item.any->sha1, base, baselen,
+		switch (fn(current->sha1, base, baselen,
 			   current->name, current->mode, stage)) {
 		case 0:
 			continue;
@@ -107,7 +107,7 @@ int read_tree_recursive(struct tree *tre
 			memcpy(newbase, base, baselen);
 			memcpy(newbase + baselen, current->name, pathlen);
 			newbase[baselen + pathlen] = '/';
-			retval = read_tree_recursive(current->item.tree,
+			retval = read_tree_recursive(lookup_tree(current->sha1),
 						     newbase,
 						     baselen + pathlen + 1,
 						     stage, match, fn);
@@ -170,6 +170,7 @@ int parse_tree_buffer(struct tree *item,
 
 		entry = xmalloc(sizeof(struct tree_entry_list));
 		entry->name = path;
+		entry->sha1 = sha1;
 		entry->mode = mode;
 		entry->directory = S_ISDIR(mode) != 0;
 		entry->executable = (mode & S_IXUSR) != 0;
@@ -178,12 +179,6 @@ int parse_tree_buffer(struct tree *item,
 		entry->next = NULL;
 
 		update_tree_entry(&desc);
-
-		if (entry->directory) {
-			entry->item.tree = lookup_tree(sha1);
-		} else {
-			entry->item.blob = lookup_blob(sha1);
-		}
 		n_refs++;
 		*list_p = entry;
 		list_p = &entry->next;
@@ -193,8 +188,16 @@ int parse_tree_buffer(struct tree *item,
 		struct tree_entry_list *entry;
 		unsigned i = 0;
 		struct object_refs *refs = alloc_object_refs(n_refs);
-		for (entry = item->entries; entry; entry = entry->next)
-			refs->ref[i++] = entry->item.any;
+		for (entry = item->entries; entry; entry = entry->next) {
+			struct object *obj;
+
+			if (entry->directory)
+				obj = &lookup_tree(entry->sha1)->object;
+			else
+				obj = &lookup_blob(entry->sha1)->object;
+			refs->ref[i++] = obj;
+		}
+				
 		set_object_refs(&item->object, refs);
 	}
 
diff --git a/tree.h b/tree.h
index 066ac5d..a27bae4 100644
--- a/tree.h
+++ b/tree.h
@@ -13,11 +13,7 @@ struct tree_entry_list {
 	unsigned zeropad : 1;
 	unsigned int mode;
 	const char *name;
-	union {
-		struct object *any;
-		struct tree *tree;
-		struct blob *blob;
-	} item;
+	const unsigned char *sha1;
 };
 
 struct tree {
@@ -37,7 +33,7 @@ int parse_tree(struct tree *tree);
 struct tree *parse_tree_indirect(const unsigned char *sha1);
 
 #define READ_TREE_RECURSIVE 1
-typedef int (*read_tree_fn_t)(unsigned char *, const char *, int, const char *, unsigned int, int);
+typedef int (*read_tree_fn_t)(const unsigned char *, const char *, int, const char *, unsigned int, int);
 
 extern int read_tree_recursive(struct tree *tree,
 			       const char *base, int baselen,

^ permalink raw reply related

* [PATCH 3/4] Switch "read_tree_recursive()" over to tree-walk functionality
From: Linus Torvalds @ 2006-05-28 22:11 UTC (permalink / raw)
  To: Junio C Hamano, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0605281453460.5623@g5.osdl.org>


Don't use the tree_entry list, it really had no major reason not to just
walk the raw tree instead.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---
 tree.c |   33 ++++++++++++++++++++-------------
 1 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/tree.c b/tree.c
index ba8742c..8a7fdd4 100644
--- a/tree.c
+++ b/tree.c
@@ -78,19 +78,26 @@ int read_tree_recursive(struct tree *tre
 			int stage, const char **match,
 			read_tree_fn_t fn)
 {
-	struct tree_entry_list *list;
+	struct tree_desc desc;
+
 	if (parse_tree(tree))
 		return -1;
-	list = tree->entries;
-	while (list) {
-		struct tree_entry_list *current = list;
-		list = list->next;
-		if (!match_tree_entry(base, baselen, current->name,
-				      current->mode, match))
+
+	desc.buf = tree->buffer;
+	desc.size = tree->size;
+
+	while (desc.size) {
+		unsigned mode;
+		const char *name;
+		const unsigned char *sha1;
+
+		sha1 = tree_entry_extract(&desc, &name, &mode);
+		update_tree_entry(&desc);
+
+		if (!match_tree_entry(base, baselen, name, mode, match))
 			continue;
 
-		switch (fn(current->sha1, base, baselen,
-			   current->name, current->mode, stage)) {
+		switch (fn(sha1, base, baselen, name, mode, stage)) {
 		case 0:
 			continue;
 		case READ_TREE_RECURSIVE:
@@ -98,16 +105,16 @@ int read_tree_recursive(struct tree *tre
 		default:
 			return -1;
 		}
-		if (current->directory) {
+		if (S_ISDIR(mode)) {
 			int retval;
-			int pathlen = strlen(current->name);
+			int pathlen = strlen(name);
 			char *newbase;
 
 			newbase = xmalloc(baselen + 1 + pathlen);
 			memcpy(newbase, base, baselen);
-			memcpy(newbase + baselen, current->name, pathlen);
+			memcpy(newbase + baselen, name, pathlen);
 			newbase[baselen + pathlen] = '/';
-			retval = read_tree_recursive(lookup_tree(current->sha1),
+			retval = read_tree_recursive(lookup_tree(sha1),
 						     newbase,
 						     baselen + pathlen + 1,
 						     stage, match, fn);

^ 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