* Re: [PATCH 3/4] t5500-fetch-pack: remove local (bashism) usage.
From: Eric Wong @ 2006-05-29 5:28 UTC (permalink / raw)
To: Herbert Xu; +Cc: Junio C Hamano, git
In-Reply-To: <20060526122317.GC5372@gondor.apana.org.au>
Herbert Xu <herbert@gondor.apana.org.au> wrote:
> On Thu, May 25, 2006 at 07:06:17PM -0700, Eric Wong wrote:
> > None of the variables seem to conflict, so local was unnecessary.
>
> BTW, dash supports (and has always supported) local which is a quite
> useful feature.
Cool. Hmm... pdksh seems to support it here (Debian sid). I'm pretty
sure local is not part of the POSIX spec, though; and I have seen
/bin/sh that don't support it.
--
Eric Wong
^ permalink raw reply
* Re: [PATCH 1/1] Tried to fix git-svn's handling of filenames with embedded '@'.
From: Eric Wong @ 2006-05-29 5:25 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Seth Falcon
In-Reply-To: <7vlksldgp2.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano <junkio@cox.net> wrote:
> 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?
Doesn't work with svn 1.1 (a requirement of mine, unfortunately). I'll
have a fix for that in a bit.
--
Eric Wong
^ permalink raw reply
* Re: [PATCH] Support for configurable git command aliases
From: Jeff King @ 2006-05-29 3:58 UTC (permalink / raw)
To: git
In-Reply-To: <e5d9sm$5d4$1@sea.gmane.org>
On Mon, May 29, 2006 at 12:57:26AM +0200, Jakub Narebski wrote:
> Well, if [alias] would be used also for giving default options for git
> commands, e.g.
>
> [alias]
> log = log --pretty
A funny side effect of that would be that "git log" and "git-log" would
now have completely different defaults (unless the alias mechanism
starts intercepting direct calls to git-*, which seems invasive). I
wonder if it might be simpler to just add
core.defaults.log = "--pretty"
or similar.
-Peff
^ permalink raw reply
* [PATCH] git-send-email.perl extract_valid_address issue
From: Nicolas Troncoso Carrere @ 2006-05-29 4:00 UTC (permalink / raw)
To: git
The third fallback was returning if the match was done or not instead of
returning the actual email address that was matched. This prevented sending
the mail to the people included in the CC. This bug only affect those that
dont have Email::Valid.
I initialized $valid_email as undef so it would mimic the behavior of
Email::Verify->address(), which returns undef if no valid address was found.
Signed-off-by: Nicolas <ntroncos@inf.utfsm.cl>
---
git-send-email.perl | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
84853ca89c15de7a24e9eb9fd422654b86c63be9
diff --git a/git-send-email.perl b/git-send-email.perl
index 312a4ea..dfff3e6 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -316,7 +316,9 @@ sub extract_valid_address {
} else {
# less robust/correct than the monster regexp in Email::Valid,
# but still does a 99% job, and one less dependency
- return ($address =~ /([^\"<>\s]+@[^<>\s]+)/);
+ my $valid_email=undef;
+ ($valid_email ) = ($address =~ /([^\"<>\s]+@[^<>\s]+)/);
+ return ($valid_email);
}
}
--
Nicolás Troncoso Carrère User #272312 counter.li.org
Estudiante Magíster en Ciencias de la Informática
Universidad Técnica Federico Santa María
http://www.alumnos.inf.utfsm.cl/~ntroncos
^ permalink raw reply related
* Re: [PATCH] Support for configurable git command aliases
From: Junio C Hamano @ 2006-05-29 2:01 UTC (permalink / raw)
To: Petr Baudis; +Cc: git
In-Reply-To: <20060528215945.GD10488@pasky.or.cz>
Petr Baudis <pasky@ucw.cz> writes:
>> 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.
Sorry, I don't. The left hand side of '=' does not allow
anything but alnum and squashes the case. Please stick to
[alias "co"] syntax.
^ permalink raw reply
* Re: git-format-patch question
From: Seth Falcon @ 2006-05-29 1:01 UTC (permalink / raw)
To: git
In-Reply-To: <7vpshxdh0s.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano <junkio@cox.net> writes:
> 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.
Thanks for the quick answers. I guess I was imagining things to be
more complicated than they are :-)
^ permalink raw reply
* [PATCH] Fix section slicing so help options are not misplaced in cg-commit(1)
From: Jonas Fonseca @ 2006-05-29 0:13 UTC (permalink / raw)
To: Petr Baudis, git
Signed-off-by: Jonas Fonseca <fonseca@diku.dk>
---
95724a5a97ca466e6eaccc7f46833a015dde2f24
Documentation/make-cg-asciidoc | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
95724a5a97ca466e6eaccc7f46833a015dde2f24
diff --git a/Documentation/make-cg-asciidoc b/Documentation/make-cg-asciidoc
index 45fc981..3873618 100755
--- a/Documentation/make-cg-asciidoc
+++ b/Documentation/make-cg-asciidoc
@@ -48,7 +48,7 @@ DESCRIPTION=
OPTIONS=
MISC=
-section=$(echo "$BODY" | sed -n '1,/^[-~][-~]*[-~]$/p')
+section=$(echo "$BODY" | sed -n '1,/^[-][-]*[-]$/p')
section_lines=$(echo "$section" | wc -l)
lines=$(echo "$BODY" | wc -l)
--
1.3.3.gd882-dirty
--
Jonas Fonseca
^ permalink raw reply related
* [PATCH] Minor doc fixes
From: Jonas Fonseca @ 2006-05-29 0:12 UTC (permalink / raw)
To: Petr Baudis, git
Signed-off-by: Jonas Fonseca <fonseca@diku.dk>
---
1e376c11029a33deb811b77565fb558b6c192766
README | 2 +-
README.osx | 7 ++++---
cogito.spec.in | 2 +-
3 files changed, 6 insertions(+), 5 deletions(-)
1e376c11029a33deb811b77565fb558b6c192766
diff --git a/README b/README
index a53b466..e6e1119 100644
--- a/README
+++ b/README
@@ -60,7 +60,7 @@ The following tools are optional but rec
Tool Description
-------------------------------------------------------------------------------
rsync For fetching files with the rsync backend.
-gnu coreutils The gnu versions of stat, date and cp \
+GNU coreutils The GNU versions of stat, date and cp \
are preferred over the BSD variants.
asciidoc (>= 7.0), xmlto For building documentation.
-------------------------------------------------------------------------------
diff --git a/README.osx b/README.osx
index d8df872..912d9fe 100644
--- a/README.osx
+++ b/README.osx
@@ -2,8 +2,9 @@ This version of Cogito should work on OS
To install on OS X:
-1) Install darwinports (http://darwinports.opendarwin.org/) 2) type
-"make Portfile" 3) type "sudo port install"
+ 1. Install darwinports (http://darwinports.opendarwin.org/)
+ 2. type "make Portfile"
+ 3. type "sudo port install"
You may have to deal with md5 mismatches. Either adjust the md5sum in
your new Portfile or place the new tarball in
@@ -11,7 +12,7 @@ your new Portfile or place the new tarba
Recommendations:
-The gnu versions of "stat" and "date" are preferred over their BSD
+The GNU versions of "stat" and "date" are preferred over their BSD
variants.
"patch", "diff", "merge", "curl" and "rsync" are required. OS X.4
diff --git a/cogito.spec.in b/cogito.spec.in
index 5509d77..70274c1 100644
--- a/cogito.spec.in
+++ b/cogito.spec.in
@@ -70,7 +70,7 @@ rm -rf $RPM_BUILD_ROOT
- Update summary and description
- Make architecture-independent
-* Wed Jul 6 2005 Chris Wright <chris@osdl.org> 0.12-1
+* Wed Jul 6 2005 Chris Wright <chrisw@osdl.org> 0.12-1
- update spec file
* Thu Jun 9 2005 Chris Wright <chrisw@osdl.org> 0.11.3-1
--
1.3.3.gd882-dirty
--
Jonas Fonseca
^ permalink raw reply related
* [PATCH] Portfile: bring it up to date; use description from cogito.spec.in
From: Jonas Fonseca @ 2006-05-29 0:11 UTC (permalink / raw)
To: Petr Baudis, git
---
9460c53c76fc00e3b7c45e58813cefde78cb99f5
Portfile.in | 14 +++++++-------
1 files changed, 7 insertions(+), 7 deletions(-)
9460c53c76fc00e3b7c45e58813cefde78cb99f5
diff --git a/Portfile.in b/Portfile.in
index 9e380ad..297fd8a 100644
--- a/Portfile.in
+++ b/Portfile.in
@@ -4,13 +4,13 @@ name cogito
version @@VERSION@@
categories devel
maintainers bryan.larsen@gmail.com
-description Git core + cogito tools to provide a full distributed SCM.
-long_description The git core, developed by Linus Torvalds provides \
- an extremely fast and flexible filesystem-based \
- database designed to store directory trees with \
- regard to their history. The cogito tools, \
- developed by Petr Baudis, provide full distributed \
- SCM (software change management) functionality.
+description The Cogito Version Control System
+long_description Cogito is a version control system layered on top \
+ of the git tree history storage system. It aims at \
+ seamless user interface and ease of use, providing \
+ generally smoother user experience than the "raw" \
+ Core GIT itself and indeed many other version \
+ control systems.
homepage http://kernel.org/pub/software/scm/cogito/
master_sites http://kernel.org/pub/software/scm/cogito/
configure {}
--
1.3.3.gd882-dirty
--
Jonas Fonseca
^ permalink raw reply related
* [PATCH] ciabot: fix post-update hook description
From: Jonas Fonseca @ 2006-05-29 0:09 UTC (permalink / raw)
To: Petr Baudis, git
Also, improve on a few lost sentences
Signed-off-by: Jonas Fonseca <fonseca@diku.dk>
---
b2d8b2c5258b6585102c94f37c63dc2360092d87
contrib/ciabot.pl | 30 +++++++++++++++---------------
1 files changed, 15 insertions(+), 15 deletions(-)
b2d8b2c5258b6585102c94f37c63dc2360092d87
diff --git a/contrib/ciabot.pl b/contrib/ciabot.pl
index 83a0d80..e23f5f1 100755
--- a/contrib/ciabot.pl
+++ b/contrib/ciabot.pl
@@ -14,15 +14,15 @@ #
# The master location of this file is in the Cogito repository
# (see http://www.kernel.org/git/).
#
-# This program is designed to run as the .git/commit-post-hook script. It takes
-# the commit information, massaging it and mailing it to the address given below.
+# This program is designed to run as the .git/hooks/post-commit hook. It takes
+# the commit information, massages it and mails it to the address given below.
#
-# The calling convention of the commit-post-hook script is:
+# The calling convention of the post-commit hook is:
#
-# commit-post-hook $commit_sha1 $branch_name
+# .git/hooks/post-commit $commit_sha1 $branch_name
#
# If it does not work, try to disable $xml_rpc in the configuration section
-# below.
+# below. Also, remember to make the hook file executable.
#
#
# Note that you can (and it might be actually more desirable) also use this
@@ -36,9 +36,9 @@ # for merged in $(git-rev-list $newhead
# /path/to/ciabot.pl $merged $refname
# done
#
-# This is useful when you use a remote repository without working copy, where
-# you only push to - the update hook will be trigerred each time you push into
-# that repository, and the pushed commits will be reported through CIA.
+# This is useful when you use a remote repository that you only push to. The
+# update hook will be triggered each time you push into that repository, and
+# the pushed commits will be reported through CIA.
use strict;
use vars qw ($project $from_email $dest_email $noisy $rpc_uri $sendmail
@@ -78,19 +78,19 @@ # not deliver the event at all if CIA se
# unfortunately not an uncommon condition.
$xml_rpc = 0;
-# You can make this bot to totally ignore events concerning the objects
-# specified below. Each object is composed of <path>/<filename>,
+# This variable should contain a regexp, against which each file will be
+# checked, and if the regexp is matched, the file is ignored. This can be
+# useful if you do not want auto-updated files, such as e.g. ChangeLog, to
+# appear via CIA.
#
-# This variable should contain regexp, against which will each object be
-# checked, and if the regexp is matched, the file is ignored. Therefore ie. to
-# ignore all changes in the two files above and everything concerning module
-# 'admin', use:
+# The following example will make the script ignore all changes in two specific
+# files in two different modules, and everything concerning module 'admin':
#
# $ignore_regexp = "^(gentoo/Manifest|elinks/src/bfu/inphist.c|admin/)";
$ignore_regexp = "";
# It can be useful to also grab the generated XML message by some other
-# programs and ie. autogenerate some content based on it. Here you can specify
+# programs and e.g. autogenerate some content based on it. Here you can specify
# a file to which it will be appended.
$alt_local_message_target = "";
--
1.3.3.gd882-dirty
--
Jonas Fonseca
^ permalink raw reply related
* Don't use "sscanf()" for tree mode scanning
From: Linus Torvalds @ 2006-05-28 23:16 UTC (permalink / raw)
To: Junio C Hamano, Git Mailing List
Doing an oprofile run on the result of my git rev-list memory leak fixes
and tree parsing cleanups, I was surprised by the third-highest entry
being
samples % image name app name symbol name
179751 2.7163 libc-2.4.so libc-2.4.so _IO_vfscanf@@GLIBC_2.4
where that 2.7% is actually more than 5% of one CPU, because this was run
on a dual CPU setup with the other CPU just being idle.
That seems to all be from the use of 'sscanf(tree, "%o", &mode)' for the
tree buffer parsing.
So do the trivial octal parsing by hand, which also gives us where the
first space in the string is (and thus where the pathname starts) so we
can get rid of the "strchr(tree, ' ')" call too.
This brings the "git rev-list --all --objects" time down from 63 seconds
to 55 seconds on the historical kernel archive for me, so it's quite
noticeable - tree parsing is a lot of what we end up doing when following
all the objects.
[ I also see a 5% speedup on a full "git fsck-objects" on the current
kernel archive, so that sscanf() really does seem to have hurt our
performance by a surprising amount ]
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---
tree-walk.c | 21 ++++++++++++++++++---
1 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/tree-walk.c b/tree-walk.c
index 9f7abb7..3922058 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -47,18 +47,33 @@ void update_tree_entry(struct tree_desc
desc->size = size - len;
}
+static const char *get_mode(const char *str, unsigned int *modep)
+{
+ unsigned char c;
+ unsigned int mode = 0;
+
+ while ((c = *str++) != ' ') {
+ if (c < '0' || c > '7')
+ return NULL;
+ mode = (mode << 3) + (c - '0');
+ }
+ *modep = mode;
+ return str;
+}
+
const unsigned char *tree_entry_extract(struct tree_desc *desc, const char **pathp, unsigned int *modep)
{
void *tree = desc->buf;
unsigned long size = desc->size;
int len = strlen(tree)+1;
const unsigned char *sha1 = tree + len;
- const char *path = strchr(tree, ' ');
+ const char *path;
unsigned int mode;
- if (!path || size < len + 20 || sscanf(tree, "%o", &mode) != 1)
+ path = get_mode(tree, &mode);
+ if (!path || size < len + 20)
die("corrupt tree file");
- *pathp = path+1;
+ *pathp = path;
*modep = canon_mode(mode);
return sha1;
}
^ permalink raw reply related
* Re: [PATCH] Support for configurable git command aliases
From: Jakub Narebski @ 2006-05-28 22:57 UTC (permalink / raw)
To: git
In-Reply-To: <20060528215945.GD10488@pasky.or.cz>
Petr Baudis wrote:
> 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...
>>
>> 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. ;-)
Well, if [alias] would be used also for giving default options for git
commands, e.g.
[alias]
log = log --pretty
(from what Petr "Pasky" Baudis said on IRC, currently on the right side
there should be only true git commands, which eliminates nicely problems
with recursion ;-), it would be better to ensure that aliases are checked
*only* for interactive sessions - otherwise using aliases for default
arguments would/could mess the scripts.
--
Jakub Narebski
Warsaw, Poland
^ permalink raw reply
* [PATCH] Read configuration also from ~/.gitrc
From: Petr Baudis @ 2006-05-28 22:26 UTC (permalink / raw)
To: Anand Kumria; +Cc: git
In-Reply-To: <20060526152837.GQ23852@progsoc.uts.edu.au>
Hi,
Dear diary, on Fri, May 26, 2006 at 05:28:37PM CEST, I got a letter
where Anand Kumria <wildfire@progsoc.uts.edu.au> said that...
> git is unable to construct a reasonable default email address in my
> current environment. So, I use GIT_AUTHOR_EMAIL and GIT_COMMITTER_EMAIL
> to override things.
>
> This has worked well but, now, I need to vary the email address for some
> repositories. Unfortunately the environment variables override
> .git/config.
>
> It would be good if things were like:
> - try to construct one automagically
> - use ~/.git/config (if available)
> - use .git/config
> - use environment variables
>
> That way I could set my default email address in ~/.git/config and
> override it as required for those repositories that need it.
hmm, might it be as simple as this?
---
This command makes Git read configuration from ~/.gitrc in addition
to the per-repository .git/config configuration file, and updates
the documentation accordingly (and also expands it a little).
Idea by Anand Kumria.
Signed-off-by: Petr Baudis <pasky@suse.cz>
---
Documentation/git-commit-tree.txt | 9 +++++----
Documentation/git-repo-config.txt | 6 +++---
Documentation/git-var.txt | 5 +++--
Documentation/git.txt | 15 +++++++++++----
config.c | 6 +++++-
5 files changed, 27 insertions(+), 14 deletions(-)
diff --git a/Documentation/git-commit-tree.txt b/Documentation/git-commit-tree.txt
index 41d1a1c..1b0d102 100644
--- a/Documentation/git-commit-tree.txt
+++ b/Documentation/git-commit-tree.txt
@@ -49,8 +49,9 @@ A commit encapsulates:
- committer name and email and the commit time.
If not provided, "git-commit-tree" uses your name, hostname and domain to
-provide author and committer info. This can be overridden by
-either `.git/config` file, or using the following environment variables.
+provide author and committer info. This can be overridden by either the
+`~/.gitrc` file, the `.git/config` file, or using the following
+environment variables.
GIT_AUTHOR_NAME
GIT_AUTHOR_EMAIL
@@ -60,8 +61,8 @@ either `.git/config` file, or using the
(nb "<", ">" and "\n"s are stripped)
-In `.git/config` file, the following items are used for GIT_AUTHOR_NAME and
-GIT_AUTHOR_EMAIL:
+In the configuration file, the following items are used for GIT_AUTHOR_NAME
+and GIT_AUTHOR_EMAIL:
[user]
name = "Your Name"
diff --git a/Documentation/git-repo-config.txt b/Documentation/git-repo-config.txt
index 660c18f..bb7f81f 100644
--- a/Documentation/git-repo-config.txt
+++ b/Documentation/git-repo-config.txt
@@ -3,7 +3,7 @@ git-repo-config(1)
NAME
----
-git-repo-config - Get and set options in .git/config
+git-repo-config - Get and set git runtime configuration options
SYNOPSIS
@@ -37,7 +37,7 @@ no checks or transformations are perform
This command will fail if:
-. The .git/config file is invalid,
+. The configuration file is invalid,
. Can not write to .git/config,
. no section was provided,
. the section or key is invalid,
@@ -70,7 +70,7 @@ OPTIONS
Remove all matching lines from .git/config.
-l, --list::
- List all variables set in .git/config.
+ List all variables set in ~/.gitrc or .git/config.
EXAMPLE
diff --git a/Documentation/git-var.txt b/Documentation/git-var.txt
index a5b1a0d..4679aef 100644
--- a/Documentation/git-var.txt
+++ b/Documentation/git-var.txt
@@ -18,8 +18,9 @@ OPTIONS
-------
-l::
Cause the logical variables to be listed. In addition, all the
- variables of the git configuration file .git/config are listed
- as well. (However, the configuration variables listing functionality
+ variables of the git configuration files `~/.gitrc` and `.git/config`
+ are listed as well.
+ (However, the configuration variables listing functionality
is deprecated in favor of `git-repo-config -l`.)
EXAMPLE
diff --git a/Documentation/git.txt b/Documentation/git.txt
index e474bdf..f4e5df5 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -116,7 +116,7 @@ gitlink:git-read-tree[1]::
Reads tree information into the index.
gitlink:git-repo-config[1]::
- Get and set options in .git/config.
+ Get and set git runtime configuration options.
gitlink:git-unpack-objects[1]::
Unpacks objects out of a packed archive.
@@ -473,8 +473,7 @@ gitlink:gitk[1]::
Configuration Mechanism
-----------------------
-Starting from 0.99.9 (actually mid 0.99.8.GIT), `.git/config` file
-is used to hold per-repository configuration options. It is a
+You can adjust the Git behaviour by a configuration file. It is a
simple text file modelled after `.ini` format familiar to some
people. Here is an example:
@@ -496,7 +495,15 @@ #
------------
Various commands read from the configuration file and adjust
-their operation accordingly.
+their operation accordingly. See gitlink:git-repo-config[1]
+for details and list of options.
+
+Git first reads the per-user global configuration from `~/.gitrc`
+and then per-repository configuration from the `.git/config` file.
+Either of these files may be missing; the per-repository configuration
+wins in case of a conflict. Some behaviour can be also tweaked using
+environment variables; in general, they take precedence over configuration
+options.
Identifier Terminology
diff --git a/config.c b/config.c
index 0248c6d..8a98865 100644
--- a/config.c
+++ b/config.c
@@ -312,7 +312,11 @@ int git_config_from_file(config_fn_t fn,
int git_config(config_fn_t fn)
{
- return git_config_from_file(fn, git_path("config"));
+ int ret = 0;
+ if (getenv("HOME"))
+ ret += git_config_from_file(fn, mkpath("%s/.gitrc", getenv("HOME")));
+ ret += git_config_from_file(fn, git_path("config"));
+ return ret;
}
/*
--
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
* [PATCH 4/4] Remove "tree->entries" tree-entry list from tree parser
From: Linus Torvalds @ 2006-05-28 22:13 UTC (permalink / raw)
To: Junio C Hamano, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0605281453460.5623@g5.osdl.org>
This finally removes the tree-entry list from "struct tree", since most of
the users can just use the tree-walk infrastructure to walk the raw tree
buffers instead of the tree-entry list.
The tree-entry list is inefficient, and generates tons of small
allocations for no good reason. The tree-walk infrastructure is generally
no harder to use than following a linked list, and allows us to do most
tree parsing in-place.
Some programs still use the old tree-entry lists, and are a bit painful to
convert without major surgery. For them we have a helper function that
creates a temporary tree-entry list on demand. We can convert those too
eventually, but with this they no longer affect any users who don't need
the explicit lists.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---
builtin-ls-tree.c | 2 +
builtin-read-tree.c | 4 +--
builtin-rev-list.c | 26 ++++++++++------
fetch.c | 16 +++++++---
fsck-objects.c | 7 +++-
http-push.c | 30 +++++++++++++------
revision.c | 3 +-
tree.c | 81 ++++++++++++++++++++++++++++++++++++---------------
tree.h | 4 ++-
9 files changed, 116 insertions(+), 57 deletions(-)
diff --git a/builtin-ls-tree.c b/builtin-ls-tree.c
index 48385d5..b8d0d88 100644
--- a/builtin-ls-tree.c
+++ b/builtin-ls-tree.c
@@ -53,7 +53,7 @@ static int show_recursive(const char *ba
}
}
-static int show_tree(unsigned char *sha1, const char *base, int baselen,
+static int show_tree(const unsigned char *sha1, const char *base, int baselen,
const char *pathname, unsigned mode, int stage)
{
int retval = 0;
diff --git a/builtin-read-tree.c b/builtin-read-tree.c
index f0b8dad..da0731c 100644
--- a/builtin-read-tree.c
+++ b/builtin-read-tree.c
@@ -163,7 +163,7 @@ #endif
struct tree *tree = lookup_tree(posns[i]->sha1);
any_dirs = 1;
parse_tree(tree);
- subposns[i] = tree->entries;
+ subposns[i] = create_tree_entry_list(tree);
posns[i] = posns[i]->next;
src[i + merge] = &df_conflict_entry;
continue;
@@ -368,7 +368,7 @@ static int unpack_trees(merge_fn_t fn)
if (len) {
posns = xmalloc(len * sizeof(struct tree_entry_list *));
for (i = 0; i < len; i++) {
- posns[i] = ((struct tree *) posn->item)->entries;
+ posns[i] = create_tree_entry_list((struct tree *) posn->item);
posn = posn->next;
}
if (unpack_trees_rec(posns, len, "", fn, &indpos))
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 94f520b..6e2b898 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -113,7 +113,7 @@ static struct object_list **process_tree
const char *name)
{
struct object *obj = &tree->object;
- struct tree_entry_list *entry;
+ struct tree_desc desc;
struct name_path me;
if (!revs.tree_objects)
@@ -128,16 +128,22 @@ static struct object_list **process_tree
me.up = path;
me.elem = name;
me.elem_len = strlen(name);
- entry = tree->entries;
- tree->entries = NULL;
- while (entry) {
- struct tree_entry_list *next = entry->next;
- if (entry->directory)
- p = process_tree(lookup_tree(entry->sha1), p, &me, entry->name);
+
+ 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 (S_ISDIR(mode))
+ p = process_tree(lookup_tree(sha1), p, &me, name);
else
- p = process_blob(lookup_blob(entry->sha1), p, &me, entry->name);
- free(entry);
- entry = next;
+ p = process_blob(lookup_blob(sha1), p, &me, name);
}
free(tree->buffer);
tree->buffer = NULL;
diff --git a/fetch.c b/fetch.c
index f7f8902..d9fe41f 100644
--- a/fetch.c
+++ b/fetch.c
@@ -41,16 +41,22 @@ static int process_tree(struct tree *tre
if (parse_tree(tree))
return -1;
- entry = tree->entries;
- tree->entries = NULL;
+ entry = create_tree_entry_list(tree);
while (entry) {
struct tree_entry_list *next = entry->next;
- if (process(entry->item.any))
- return -1;
- free(entry->name);
+
+ if (entry->directory) {
+ struct tree *tree = lookup_tree(entry->sha1);
+ process_tree(tree);
+ } else {
+ struct blob *blob = lookup_blob(entry->sha1);
+ process(&blob->object);
+ }
free(entry);
entry = next;
}
+ free(tree->buffer);
+ tree->buffer = NULL;
return 0;
}
diff --git a/fsck-objects.c b/fsck-objects.c
index 44b6465..ec99a7a 100644
--- a/fsck-objects.c
+++ b/fsck-objects.c
@@ -10,6 +10,7 @@ #include "refs.h"
#include "pack.h"
#define REACHABLE 0x0001
+#define SEEN 0x0002
static int show_root = 0;
static int show_tags = 0;
@@ -160,7 +161,7 @@ static int fsck_tree(struct tree *item)
struct tree_entry_list *entry, *last;
last = NULL;
- for (entry = item->entries; entry; entry = entry->next) {
+ for (entry = create_tree_entry_list(item); entry; entry = entry->next) {
if (strchr(entry->name, '/'))
has_full_path = 1;
has_zero_pad |= entry->zeropad;
@@ -204,7 +205,6 @@ static int fsck_tree(struct tree *item)
}
if (last)
free(last);
- item->entries = NULL;
free(item->buffer);
item->buffer = NULL;
@@ -276,6 +276,9 @@ static int fsck_sha1(unsigned char *sha1
struct object *obj = parse_object(sha1);
if (!obj)
return error("%s: object not found", sha1_to_hex(sha1));
+ if (obj->flags & SEEN)
+ return 0;
+ obj->flags |= SEEN;
if (obj->type == blob_type)
return 0;
if (obj->type == tree_type)
diff --git a/http-push.c b/http-push.c
index f492a5d..72ad89c 100644
--- a/http-push.c
+++ b/http-push.c
@@ -1704,6 +1704,7 @@ static struct object_list **process_blob
return p;
obj->flags |= SEEN;
+ name = strdup(name);
return add_object(obj, p, path, name);
}
@@ -1713,7 +1714,7 @@ static struct object_list **process_tree
const char *name)
{
struct object *obj = &tree->object;
- struct tree_entry_list *entry;
+ struct tree_desc desc;
struct name_path me;
obj->flags |= LOCAL;
@@ -1724,21 +1725,30 @@ static struct object_list **process_tree
die("bad tree object %s", sha1_to_hex(obj->sha1));
obj->flags |= SEEN;
+ name = strdup(name);
p = add_object(obj, p, NULL, name);
me.up = path;
me.elem = name;
me.elem_len = strlen(name);
- entry = tree->entries;
- tree->entries = NULL;
- while (entry) {
- struct tree_entry_list *next = entry->next;
- if (entry->directory)
- p = process_tree(lookup_tree(entry->sha1), p, &me, entry->name);
+
+ 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 (S_ISDIR(mode))
+ p = process_tree(lookup_tree(sha1), p, &me, name);
else
- p = process_blob(lookup_blob(entry->sha1), p, &me, entry->name);
- free(entry);
- entry = next;
+ p = process_blob(lookup_blob(sha1), p, &me, name);
}
+ free(tree->buffer);
+ tree->buffer = NULL;
return p;
}
diff --git a/revision.c b/revision.c
index 35f8e3b..c366178 100644
--- a/revision.c
+++ b/revision.c
@@ -63,8 +63,7 @@ void mark_tree_uninteresting(struct tree
return;
if (parse_tree(tree) < 0)
die("bad tree %s", sha1_to_hex(obj->sha1));
- entry = tree->entries;
- tree->entries = NULL;
+ entry = create_tree_entry_list(tree);
while (entry) {
struct tree_entry_list *next = entry->next;
if (entry->directory)
diff --git a/tree.c b/tree.c
index 8a7fdd4..db6e59f 100644
--- a/tree.c
+++ b/tree.c
@@ -151,22 +151,65 @@ struct tree *lookup_tree(const unsigned
return (struct tree *) obj;
}
-int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size)
+static int track_tree_refs(struct tree *item)
{
+ int n_refs = 0, i;
+ struct object_refs *refs;
struct tree_desc desc;
- struct tree_entry_list **list_p;
- int n_refs = 0;
+ /* Count how many entries there are.. */
+ desc.buf = item->buffer;
+ desc.size = item->size;
+ while (desc.size) {
+ n_refs++;
+ update_tree_entry(&desc);
+ }
+
+ /* Allocate object refs and walk it again.. */
+ i = 0;
+ refs = alloc_object_refs(n_refs);
+ desc.buf = item->buffer;
+ desc.size = item->size;
+ while (desc.size) {
+ unsigned mode;
+ const char *name;
+ const unsigned char *sha1;
+ struct object *obj;
+
+ sha1 = tree_entry_extract(&desc, &name, &mode);
+ update_tree_entry(&desc);
+ if (S_ISDIR(mode))
+ obj = &lookup_tree(sha1)->object;
+ else
+ obj = &lookup_blob(sha1)->object;
+ refs->ref[i++] = obj;
+ }
+ set_object_refs(&item->object, refs);
+ return 0;
+}
+
+int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size)
+{
if (item->object.parsed)
return 0;
item->object.parsed = 1;
item->buffer = buffer;
item->size = size;
- desc.buf = buffer;
- desc.size = size;
+ if (track_object_refs)
+ track_tree_refs(item);
+ return 0;
+}
+
+struct tree_entry_list *create_tree_entry_list(struct tree *tree)
+{
+ struct tree_desc desc;
+ struct tree_entry_list *ret = NULL;
+ struct tree_entry_list **list_p = &ret;
+
+ desc.buf = tree->buffer;
+ desc.size = tree->size;
- list_p = &item->entries;
while (desc.size) {
unsigned mode;
const char *path;
@@ -186,29 +229,19 @@ int parse_tree_buffer(struct tree *item,
entry->next = NULL;
update_tree_entry(&desc);
- n_refs++;
*list_p = entry;
list_p = &entry->next;
}
+ return ret;
+}
- if (track_object_refs) {
- 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) {
- 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);
+void free_tree_entry_list(struct tree_entry_list *list)
+{
+ while (list) {
+ struct tree_entry_list *next = list->next;
+ free(list);
+ list = next;
}
-
- return 0;
}
int parse_tree(struct tree *item)
diff --git a/tree.h b/tree.h
index a27bae4..c7b5248 100644
--- a/tree.h
+++ b/tree.h
@@ -20,9 +20,11 @@ struct tree {
struct object object;
void *buffer;
unsigned long size;
- struct tree_entry_list *entries;
};
+struct tree_entry_list *create_tree_entry_list(struct tree *);
+void free_tree_entry_list(struct tree_entry_list *);
+
struct tree *lookup_tree(const unsigned char *sha1);
int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size);
^ 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
* [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 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
* 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 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: 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] 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
* [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
* 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] 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: 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
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox