* Re: [PATCH] git-send-email.perl extract_valid_address issue
From: Ryan Anderson @ 2006-05-29 20:00 UTC (permalink / raw)
To: Nicolas Troncoso Carrere; +Cc: git
In-Reply-To: <200605290000.44463.ntroncos@alumnos.inf.utfsm.cl>
On Mon, May 29, 2006 at 12:00:44AM -0400, Nicolas Troncoso Carrere wrote:
>
> 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.
Odd, I noticed the same thing this weekend.
> Signed-off-by: Nicolas <ntroncos@inf.utfsm.cl>
Acked-by: Ryan Anderson <ryan@michonline.com>
(Or pick up my patch that fixes this in a slightly different way)
>
>
> ---
>
> 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
> -
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: [PATCH 6/10] fsck-objects: avoid unnecessary tree_entry_list usage
From: Linus Torvalds @ 2006-05-29 19:29 UTC (permalink / raw)
To: Junio C Hamano, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0605291218390.5623@g5.osdl.org>
On Mon, 29 May 2006, Linus Torvalds wrote:
> - has_zero_pad |= entry->zeropad;
> + has_zero_pad |= *(char *)desc.buf = '0';
Aieee.
I fixed that once in my tree already, and then broke it again when
re-doing the series with cherry-picking but didn't notice, because the
tests don't pick up the totally bogus warnings that it causes.
That "= '0'" should obviously be "== '0'"
Linus
^ permalink raw reply
* [PATCH 10/10] Remove last vestiges of generic tree_entry_list
From: Linus Torvalds @ 2006-05-29 19:21 UTC (permalink / raw)
To: Junio C Hamano, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0605291145360.5623@g5.osdl.org>
The old tree_entry_list is dead, long live the unified single tree
parser.
Yes, we now still have a compatibility function to create a bogus
tree_entry_list in builtin-read-tree.c, but that is now entirely local
to that very messy piece of code.
I'd love to clean read-tree.c up too, but I'm too scared right now, so
the best I can do is to just contain the damage, and try to make sure
that no new users of the tree_entry_list sprout up by not having it as
an exported interface any more.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---
builtin-read-tree.c | 43 +++++++++++++++++++++++++++++++++++++++++++
tree.c | 42 ------------------------------------------
tree.h | 13 -------------
3 files changed, 43 insertions(+), 55 deletions(-)
diff --git a/builtin-read-tree.c b/builtin-read-tree.c
index 480e6ed..b413e91 100644
--- a/builtin-read-tree.c
+++ b/builtin-read-tree.c
@@ -33,6 +33,16 @@ static struct object_list *trees = NULL;
static struct cache_entry df_conflict_entry = {
};
+struct tree_entry_list {
+ struct tree_entry_list *next;
+ unsigned directory : 1;
+ unsigned executable : 1;
+ unsigned symlink : 1;
+ unsigned int mode;
+ const char *name;
+ const unsigned char *sha1;
+};
+
static struct tree_entry_list df_conflict_list = {
.name = NULL,
.next = &df_conflict_list
@@ -40,6 +50,39 @@ static struct tree_entry_list df_conflic
typedef int (*merge_fn_t)(struct cache_entry **src);
+static 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;
+
+ while (desc.size) {
+ unsigned mode;
+ const char *path;
+ const unsigned char *sha1;
+ struct tree_entry_list *entry;
+
+ sha1 = tree_entry_extract(&desc, &path, &mode);
+ update_tree_entry(&desc);
+
+ 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;
+ entry->symlink = S_ISLNK(mode) != 0;
+ entry->next = NULL;
+
+ *list_p = entry;
+ list_p = &entry->next;
+ }
+ return ret;
+}
+
static int entcmp(const char *name1, int dir1, const char *name2, int dir2)
{
int len1 = strlen(name1);
diff --git a/tree.c b/tree.c
index 47318ef..fb18724 100644
--- a/tree.c
+++ b/tree.c
@@ -201,48 +201,6 @@ int parse_tree_buffer(struct tree *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;
-
- while (desc.size) {
- unsigned mode;
- const char *path;
- const unsigned char *sha1;
- struct tree_entry_list *entry;
-
- sha1 = tree_entry_extract(&desc, &path, &mode);
- update_tree_entry(&desc);
-
- 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;
- entry->symlink = S_ISLNK(mode) != 0;
- entry->next = NULL;
-
- *list_p = entry;
- list_p = &entry->next;
- }
- return ret;
-}
-
-void free_tree_entry_list(struct tree_entry_list *list)
-{
- while (list) {
- struct tree_entry_list *next = list->next;
- free(list);
- list = next;
- }
-}
-
int parse_tree(struct tree *item)
{
char type[20];
diff --git a/tree.h b/tree.h
index 6a87546..dd25c53 100644
--- a/tree.h
+++ b/tree.h
@@ -5,25 +5,12 @@ #include "object.h"
extern const char *tree_type;
-struct tree_entry_list {
- struct tree_entry_list *next;
- unsigned directory : 1;
- unsigned executable : 1;
- unsigned symlink : 1;
- unsigned int mode;
- const char *name;
- const unsigned char *sha1;
-};
-
struct tree {
struct object object;
void *buffer;
unsigned long size;
};
-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);
--
1.3.3.gcd01d
^ permalink raw reply related
* [PATCH 9/10] Convert fetch.c: process_tree() to raw tree walker
From: Linus Torvalds @ 2006-05-29 19:20 UTC (permalink / raw)
To: Junio C Hamano, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0605291145360.5623@g5.osdl.org>
This leaves only the horrid code in builtin-read-tree.c using the old
interface. Some day I will gather the strength to tackle that one too.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---
fetch.c | 24 +++++++++++++++---------
1 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/fetch.c b/fetch.c
index d9fe41f..976a5a4 100644
--- a/fetch.c
+++ b/fetch.c
@@ -3,6 +3,7 @@ #include "fetch.h"
#include "cache.h"
#include "commit.h"
#include "tree.h"
+#include "tree-walk.h"
#include "tag.h"
#include "blob.h"
#include "refs.h"
@@ -36,27 +37,32 @@ static int process(struct object *obj);
static int process_tree(struct tree *tree)
{
- struct tree_entry_list *entry;
+ struct tree_desc desc;
if (parse_tree(tree))
return -1;
- entry = create_tree_entry_list(tree);
- while (entry) {
- struct tree_entry_list *next = entry->next;
+ desc.buf = tree->buffer;
+ desc.size = tree->size;
+ while (desc.size) {
+ unsigned mode;
+ const char *name;
+ const unsigned char *sha1;
- if (entry->directory) {
- struct tree *tree = lookup_tree(entry->sha1);
+ sha1 = tree_entry_extract(&desc, &name, &mode);
+ update_tree_entry(&desc);
+
+ if (S_ISDIR(mode)) {
+ struct tree *tree = lookup_tree(sha1);
process_tree(tree);
} else {
- struct blob *blob = lookup_blob(entry->sha1);
+ struct blob *blob = lookup_blob(sha1);
process(&blob->object);
}
- free(entry);
- entry = next;
}
free(tree->buffer);
tree->buffer = NULL;
+ tree->size = 0;
return 0;
}
--
1.3.3.gcd01d
^ permalink raw reply related
* [PATCH 8/10] Convert "mark_tree_uninteresting()" to raw tree walker
From: Linus Torvalds @ 2006-05-29 19:20 UTC (permalink / raw)
To: Junio C Hamano, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0605291145360.5623@g5.osdl.org>
Not very many users to go..
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---
revision.c | 31 ++++++++++++++++++++++---------
1 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/revision.c b/revision.c
index c51ea83..8e93e40 100644
--- a/revision.c
+++ b/revision.c
@@ -53,8 +53,8 @@ static void mark_blob_uninteresting(stru
void mark_tree_uninteresting(struct tree *tree)
{
+ struct tree_desc desc;
struct object *obj = &tree->object;
- struct tree_entry_list *entry;
if (obj->flags & UNINTERESTING)
return;
@@ -63,16 +63,29 @@ void mark_tree_uninteresting(struct tree
return;
if (parse_tree(tree) < 0)
die("bad tree %s", sha1_to_hex(obj->sha1));
- entry = create_tree_entry_list(tree);
- while (entry) {
- struct tree_entry_list *next = entry->next;
- if (entry->directory)
- mark_tree_uninteresting(lookup_tree(entry->sha1));
+
+ 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))
+ mark_tree_uninteresting(lookup_tree(sha1));
else
- mark_blob_uninteresting(lookup_blob(entry->sha1));
- free(entry);
- entry = next;
+ mark_blob_uninteresting(lookup_blob(sha1));
}
+
+ /*
+ * We don't care about the tree any more
+ * after it has been marked uninteresting.
+ */
+ free(tree->buffer);
+ tree->buffer = NULL;
}
void mark_parents_uninteresting(struct commit *commit)
--
1.3.3.gcd01d
^ permalink raw reply related
* [PATCH 7/10] Remove unused "zeropad" entry from tree_list_entry
From: Linus Torvalds @ 2006-05-29 19:19 UTC (permalink / raw)
To: Junio C Hamano, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0605291145360.5623@g5.osdl.org>
That was a hack, only needed because 'git fsck-objects' didn't look at
the raw tree format. Now that fsck traverses the tree itself, we can
drop it.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---
tree.c | 3 +--
tree.h | 1 -
2 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/tree.c b/tree.c
index db6e59f..47318ef 100644
--- a/tree.c
+++ b/tree.c
@@ -217,6 +217,7 @@ struct tree_entry_list *create_tree_entr
struct tree_entry_list *entry;
sha1 = tree_entry_extract(&desc, &path, &mode);
+ update_tree_entry(&desc);
entry = xmalloc(sizeof(struct tree_entry_list));
entry->name = path;
@@ -225,10 +226,8 @@ struct tree_entry_list *create_tree_entr
entry->directory = S_ISDIR(mode) != 0;
entry->executable = (mode & S_IXUSR) != 0;
entry->symlink = S_ISLNK(mode) != 0;
- entry->zeropad = *(const char *)(desc.buf) == '0';
entry->next = NULL;
- update_tree_entry(&desc);
*list_p = entry;
list_p = &entry->next;
}
diff --git a/tree.h b/tree.h
index c7b5248..6a87546 100644
--- a/tree.h
+++ b/tree.h
@@ -10,7 +10,6 @@ struct tree_entry_list {
unsigned directory : 1;
unsigned executable : 1;
unsigned symlink : 1;
- unsigned zeropad : 1;
unsigned int mode;
const char *name;
const unsigned char *sha1;
--
1.3.3.gcd01d
^ permalink raw reply related
* [PATCH 6/10] fsck-objects: avoid unnecessary tree_entry_list usage
From: Linus Torvalds @ 2006-05-29 19:19 UTC (permalink / raw)
To: Junio C Hamano, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0605291145360.5623@g5.osdl.org>
Prime example of where the raw tree parser is easier for everybody.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---
fsck-objects.c | 55 +++++++++++++++++++++++++++++++++++--------------------
1 files changed, 35 insertions(+), 20 deletions(-)
diff --git a/fsck-objects.c b/fsck-objects.c
index 42778e8..a9680dc 100644
--- a/fsck-objects.c
+++ b/fsck-objects.c
@@ -9,6 +9,7 @@ #include "tag.h"
#include "refs.h"
#include "pack.h"
#include "cache-tree.h"
+#include "tree-walk.h"
#define REACHABLE 0x0001
#define SEEN 0x0002
@@ -116,15 +117,15 @@ static void check_connectivity(void)
#define TREE_UNORDERED (-1)
#define TREE_HAS_DUPS (-2)
-static int verify_ordered(struct tree_entry_list *a, struct tree_entry_list *b)
+static int verify_ordered(unsigned mode1, const char *name1, unsigned mode2, const char *name2)
{
- int len1 = strlen(a->name);
- int len2 = strlen(b->name);
+ int len1 = strlen(name1);
+ int len2 = strlen(name2);
int len = len1 < len2 ? len1 : len2;
unsigned char c1, c2;
int cmp;
- cmp = memcmp(a->name, b->name, len);
+ cmp = memcmp(name1, name2, len);
if (cmp < 0)
return 0;
if (cmp > 0)
@@ -135,8 +136,8 @@ static int verify_ordered(struct tree_en
* Now we need to order the next one, but turn
* a '\0' into a '/' for a directory entry.
*/
- c1 = a->name[len];
- c2 = b->name[len];
+ c1 = name1[len];
+ c2 = name2[len];
if (!c1 && !c2)
/*
* git-write-tree used to write out a nonsense tree that has
@@ -144,9 +145,9 @@ static int verify_ordered(struct tree_en
* sure we do not have duplicate entries.
*/
return TREE_HAS_DUPS;
- if (!c1 && a->directory)
+ if (!c1 && S_ISDIR(mode1))
c1 = '/';
- if (!c2 && b->directory)
+ if (!c2 && S_ISDIR(mode2))
c2 = '/';
return c1 < c2 ? 0 : TREE_UNORDERED;
}
@@ -159,15 +160,30 @@ static int fsck_tree(struct tree *item)
int has_bad_modes = 0;
int has_dup_entries = 0;
int not_properly_sorted = 0;
- struct tree_entry_list *entry, *last;
+ struct tree_desc desc;
+ unsigned o_mode;
+ const char *o_name;
+ const unsigned char *o_sha1;
- last = NULL;
- for (entry = create_tree_entry_list(item); entry; entry = entry->next) {
- if (strchr(entry->name, '/'))
+ desc.buf = item->buffer;
+ desc.size = item->size;
+
+ o_mode = 0;
+ o_name = NULL;
+ o_sha1 = NULL;
+ while (desc.size) {
+ unsigned mode;
+ const char *name;
+ const unsigned char *sha1;
+
+ sha1 = tree_entry_extract(&desc, &name, &mode);
+
+ if (strchr(name, '/'))
has_full_path = 1;
- has_zero_pad |= entry->zeropad;
+ has_zero_pad |= *(char *)desc.buf = '0';
+ update_tree_entry(&desc);
- switch (entry->mode) {
+ switch (mode) {
/*
* Standard modes..
*/
@@ -188,8 +204,8 @@ static int fsck_tree(struct tree *item)
has_bad_modes = 1;
}
- if (last) {
- switch (verify_ordered(last, entry)) {
+ if (o_name) {
+ switch (verify_ordered(o_mode, o_name, mode, name)) {
case TREE_UNORDERED:
not_properly_sorted = 1;
break;
@@ -199,13 +215,12 @@ static int fsck_tree(struct tree *item)
default:
break;
}
- free(last);
}
- last = entry;
+ o_mode = mode;
+ o_name = name;
+ o_sha1 = sha1;
}
- if (last)
- free(last);
free(item->buffer);
item->buffer = NULL;
--
1.3.3.gcd01d
^ permalink raw reply related
* [PATCH 5/10] Remove "tree->entries" tree-entry list from tree parser
From: Linus Torvalds @ 2006-05-29 19:18 UTC (permalink / raw)
To: Junio C Hamano, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0605291145360.5623@g5.osdl.org>
Instead, just use the tree buffer directly, and use the tree-walk
infrastructure to walk the 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.
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 67492bf..480e6ed 100644
--- a/builtin-read-tree.c
+++ b/builtin-read-tree.c
@@ -165,7 +165,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;
@@ -370,7 +370,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 ed2eb27..42778e8 100644
--- a/fsck-objects.c
+++ b/fsck-objects.c
@@ -11,6 +11,7 @@ #include "pack.h"
#include "cache-tree.h"
#define REACHABLE 0x0001
+#define SEEN 0x0002
static int show_root = 0;
static int show_tags = 0;
@@ -161,7 +162,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;
@@ -205,7 +206,6 @@ static int fsck_tree(struct tree *item)
}
if (last)
free(last);
- item->entries = NULL;
free(item->buffer);
item->buffer = NULL;
@@ -277,6 +277,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 8d70a6f..c51ea83 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);
--
1.3.3.gcd01d
^ permalink raw reply related
* [PATCH 4/10] builtin-read-tree.c: avoid tree_entry_list in prime_cache_tree_rec()
From: Linus Torvalds @ 2006-05-29 19:18 UTC (permalink / raw)
To: Junio C Hamano, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0605291145360.5623@g5.osdl.org>
Use the raw tree walker instead.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---
builtin-read-tree.c | 20 +++++++++++++++-----
1 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/builtin-read-tree.c b/builtin-read-tree.c
index 5e513c8..67492bf 100644
--- a/builtin-read-tree.c
+++ b/builtin-read-tree.c
@@ -9,6 +9,7 @@ #include "cache.h"
#include "object.h"
#include "tree.h"
+#include "tree-walk.h"
#include "cache-tree.h"
#include <sys/time.h>
#include <signal.h>
@@ -775,19 +776,28 @@ static int read_cache_unmerged(void)
static void prime_cache_tree_rec(struct cache_tree *it, struct tree *tree)
{
- struct tree_entry_list *ent;
+ struct tree_desc desc;
int cnt;
memcpy(it->sha1, tree->object.sha1, 20);
- for (cnt = 0, ent = tree->entries; ent; ent = ent->next) {
- if (!ent->directory)
+ desc.buf = tree->buffer;
+ desc.size = tree->size;
+ cnt = 0;
+ 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))
cnt++;
else {
struct cache_tree_sub *sub;
- struct tree *subtree = lookup_tree(ent->sha1);
+ struct tree *subtree = lookup_tree(sha1);
if (!subtree->object.parsed)
parse_tree(subtree);
- sub = cache_tree_sub(it, ent->name);
+ sub = cache_tree_sub(it, name);
sub->cache_tree = cache_tree();
prime_cache_tree_rec(sub->cache_tree, subtree);
cnt += sub->cache_tree->entry_count;
--
1.3.3.gcd01d
^ permalink raw reply related
* [PATCH 3/10] Switch "read_tree_recursive()" over to tree-walk functionality
From: Linus Torvalds @ 2006-05-29 19:17 UTC (permalink / raw)
To: Junio C Hamano, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0605291145360.5623@g5.osdl.org>
Don't use the tree_entry list any more.
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);
--
1.3.3.gcd01d
^ permalink raw reply related
* [PATCH 2/10] Make "tree_entry" have a SHA1 instead of a union of object pointers
From: Linus Torvalds @ 2006-05-29 19:16 UTC (permalink / raw)
To: Junio C Hamano, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0605291145360.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.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---
blame.c | 4 ++--
builtin-read-tree.c | 9 +++++----
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, 31 insertions(+), 30 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 6876f3d..5e513c8 100644
--- a/builtin-read-tree.c
+++ b/builtin-read-tree.c
@@ -161,9 +161,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;
@@ -187,7 +188,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;
@@ -783,7 +784,7 @@ static void prime_cache_tree_rec(struct
cnt++;
else {
struct cache_tree_sub *sub;
- struct tree *subtree = (struct tree *)ent->item.tree;
+ struct tree *subtree = lookup_tree(ent->sha1);
if (!subtree->object.parsed)
parse_tree(subtree);
sub = cache_tree_sub(it, ent->name);
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 5e65df4..ed2eb27 100644
--- a/fsck-objects.c
+++ b/fsck-objects.c
@@ -464,6 +464,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 42c077a..8d70a6f 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,
--
1.3.3.gcd01d
^ permalink raw reply related
* [PATCH 1/10] Make "struct tree" contain the pointer to the tree buffer
From: Linus Torvalds @ 2006-05-29 19:16 UTC (permalink / raw)
To: Junio C Hamano, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0605291145360.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.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---
builtin-read-tree.c | 4 ++--
builtin-rev-list.c | 3 ++-
fsck-objects.c | 7 +++----
object.c | 5 ++++-
tree.c | 47 ++++++++++++++++++++++-------------------------
tree.h | 4 +++-
6 files changed, 36 insertions(+), 34 deletions(-)
diff --git a/builtin-read-tree.c b/builtin-read-tree.c
index 716f792..6876f3d 100644
--- a/builtin-read-tree.c
+++ b/builtin-read-tree.c
@@ -39,7 +39,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);
@@ -67,7 +67,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 1922b6d..5e65df4 100644
--- a/fsck-objects.c
+++ b/fsck-objects.c
@@ -198,17 +198,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;
};
--
1.3.3.gcd01d
^ permalink raw reply related
* [PATCH 0/10] re-based and expanded tree-walker cleanup patches
From: Linus Torvalds @ 2006-05-29 19:15 UTC (permalink / raw)
To: Junio C Hamano, Git Mailing List
Ok, this is largely the same series as the previous 1..4 patches, but
rebased on top of the current master tree because the cache-tree patches
added some tree_entry_list walkers (which accounts for one extra patch in
the series, and some trivial merge fixups).
Two new patches then clean up fsck-objects, which really didn't want the
old tree_entry_list at all (and had added some hacks to the list entry
just because fsck actually needed to check the raw data).
Another two new patches convert the last remnant of tree_entry_list in
revision.c and fetch.c respectively to the new world order.
And the final patch then moves the "tree_entry_list" crud into the only
remaining user, namely builtin-read-tree.c. That file is pretty messy and
hard to convert, and I don't want to touch it right now, so I left it with
the nasty compatibility functions. But now that's at least well-contained.
I think the series is all good, and should replace the old one in "next"
(and cook there for a while just to make sure it's ok).
Linus
^ permalink raw reply
* Re: [PATCH] Make git-diff-tree indicate when it flushes
From: Junio C Hamano @ 2006-05-29 18:38 UTC (permalink / raw)
To: Paul Mackerras; +Cc: git
In-Reply-To: <17530.59395.5611.931858@cargo.ozlabs.ibm.com>
Paul Mackerras <paulus@samba.org> writes:
> There are times when gitk needs to know that the commits it has sent
> to git-diff-tree --stdin did not match, and it needs to know in a
> timely fashion even if none of them match. At the moment,
> git-diff-tree outputs nothing for non-matching commits, so it is
> impossible for gitk to distinguish between git-diff-tree being slow
> and git-diff-tree saying no.
Wouldn't this help?
$ git-diff-tree --stdin --always
^ permalink raw reply
* Re: [PATCH 1/1] Tried to fix git-svn's handling of filenames with embedded '@'.
From: Seth Falcon @ 2006-05-29 17:47 UTC (permalink / raw)
To: git
In-Reply-To: <20060529063543.GA8128@localdomain>
Eric Wong <normalperson@yhbt.net> writes:
> Seth: how does this work?
Your revised patch works for me, thanks.
+ seth
^ permalink raw reply
* Re: [PATCH] git-receive-pack needs to set umask(2)
From: Linus Torvalds @ 2006-05-29 17:00 UTC (permalink / raw)
To: Salikh Zakirov; +Cc: git
In-Reply-To: <447ADAEF.3030806@Intel.com>
I realize that you already found the solution (Core.SharedRepository),
but:
On Mon, 29 May 2006, Salikh Zakirov wrote:
>
> 2) I have 'umask 002' in my ~/.profile. Somehow, it does not help,
> because ~/.profile is not read on non-interactive SSH sessions
> (to verify that, just try to do 'ssh somehost umask')
The ".profile" thing is indeed read only for interactive tasks.
So use ".bashrc" instead.
The reason I mention that is that this has come up before: if you need to
do things like setting PATH to point to your ~/bin directory (to use your
own version of git rather than the system one), or if you want to set
environment variables like GIT_COMMITTER_NAME etc, you should always use
.bashrc, so that you get the same answers whether you log in
interactively, or whether you just do "ssh host git-cmd".
Linus
^ permalink raw reply
* Re: [PATCH] git-receive-pack needs to set umask(2)
From: Michael Richardson @ 2006-05-29 16:03 UTC (permalink / raw)
To: Petr Baudis; +Cc: git
In-Reply-To: <20060528220628.GE10488@pasky.or.cz>
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
>>>>> "Petr" == Petr Baudis <pasky@ucw.cz> writes:
Petr> The object database is considered "append-only" unless you do
Petr> git-prune (and you should better not let anyone do that), thus
Petr> it's enough if you set all directories group-writable. Other
Exactly, you have to do that. And only the owner can change the modes,
thus, unless all users have their umask set up right, someone gets toasted.
Since the directories are created on the fly, they need to be created
with the right permissions.
Petr> than access the object database, the users probably only want
Petr> to update the refs - the solution is to make refs/heads/ and
Petr> refs/tags/ group-writable and setgid. This is also what
Petr> git-init-db --shared (or tools like cg-admin-setuprepo) should
Petr> already set up for you.
Petr> So, what did break?
Never heard of "git-init-db --shared".
> A shared repository allows users belonging to the same group to push
> into that repository. When specifying `--shared` the config variable
> "core.sharedRepository" is set to 'true' so that directories under
> `$GIT_DIR` are made group writable (and g+sx, since the git group may
> be not the primary group of all users).
That would seem to be the right thing.
Seems it was added in December.
- --
] 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
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (GNU/Linux)
Comment: Finger me for keys
iQEVAwUBRHsbW4CLcPvd0N1lAQKa/gf+MF93+zbNnmqpysWMmYPVhW6HvU6XFyCQ
KyTfA7dxVX3tS9coSAcT73IX659umMz1MkyG7YR4ISFLlhLmdthq6l/ETueTZPVw
SgTSEU9TT2sM+gjtzy6v1wGQJAXJxYw6kJgKOFgCfyIPsb7EZWyQBmZLiNU0omnv
gkV8Ja5pJPTNHcinzzNyg8LIm0j55cS9OG9XQrXm46q+9OX+y39BoxGnz3Guzmry
yzfx1ipDuW54QCzKRyBpwt7/1LBfk/eJAH0wP9IAA4qz39+OA2yz8fTMvHDB1a6V
H18SkBENb6ZllGovu60IUgJCKy2sizGkBGUax9ec2ByAzHL1al3W3g==
=arDu
-----END PGP SIGNATURE-----
^ permalink raw reply
* [PATCH] cg-clean fails on files beginning with a dash
From: Dennis Stosberg @ 2006-05-29 15:06 UTC (permalink / raw)
To: Petr Baudis; +Cc: git
Reproducible with:
$ git init-db
$ echo "some text" >-file
$ cg clean
Removing -file
rm: invalid option -- l
Try `rm --help' for more information.
Signed-off-by: Dennis Stosberg <dennis@stosberg.net>
---
cg-clean | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/cg-clean b/cg-clean
index 5f438eb..fe611ac 100755
--- a/cg-clean
+++ b/cg-clean
@@ -67,13 +67,13 @@ while read -r file; do
if [ "$cleandirhard" ]; then
chmod -R 700 "$file"
fi
- $rm -rf "$file"
+ $rm -rf -- "$file"
if [ -e "$file" -o -L "$file" ]; then
echo "Cannot remove $file"
fi
elif [ -e "$file" -o -L "$file" ]; then
[ "$quiet" ] || echo "Removing $file"
- "$rm" -f "$file"
+ "$rm" -f -- "$file"
# rm would complain itself on failure
else
echo "File $file has disappeared!"
--
1.3.3+git20060528-dest1
^ permalink raw reply related
* [PATCH] git-clean fails on files beginning with a dash
From: Dennis Stosberg @ 2006-05-29 15:06 UTC (permalink / raw)
To: git
Reproducible with:
$ git init-db
$ echo "some text" >-file
$ git clean
Removing -file
rm: invalid option -- l
Try `rm --help' for more information.
Signed-off-by: Dennis Stosberg <dennis@stosberg.net>
---
git-clean.sh | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/git-clean.sh b/git-clean.sh
index bb56264..3834323 100755
--- a/git-clean.sh
+++ b/git-clean.sh
@@ -19,8 +19,8 @@ ignored=
ignoredonly=
cleandir=
quiet=
-rmf="rm -f"
-rmrf="rm -rf"
+rmf="rm -f --"
+rmrf="rm -rf --"
rm_refuse="echo Not removing"
echo1="echo"
--
1.3.3+git20060528-dest1
^ permalink raw reply related
* Re: [PATCH] Read configuration also from ~/.gitrc
From: Jakub Narebski @ 2006-05-29 14:00 UTC (permalink / raw)
To: git
In-Reply-To: <Pine.LNX.4.63.0605290913330.8863@wbgn013.biozentrum.uni-wuerzburg.de>
Johannes Schindelin wrote:
> But would this not break for the normal case? If you override one key in
> the repository's config, with this patch, repo-config will barf. The
> normal case is that you do not expect multiple values for the same key.
> Your patch reads both ~/.gitrc and $GIT_DIR/config, and if a key has a
> value in both (even if they are identical), repo-config will error out.
So the patch was to simplistic. Values from user's configuration file
~/.gitrc should be marked, to be overridden by $GIT_DIR/config per
repository configuration file.
> Further, storing a key will no longer work. This is an obscure side
> effect of this patch not caring about storing anything in ~/.gitrc: If you
> find the key section (or the key) in ~/.gitrc, the offset will be stored,
> _and used on $GIT_DIR/config_!
I think that storing a key should (unless new option --user-config or
--global is used) should store it in $GIT_DIR/config file; of course index
has to be found there, and if not found it key should be created. Per
configuration file offsets?
> I agree it is nice to have a global git configuration, but I have it: I
> use templates.
There are system-wide templates. git-init-db(1) doesn't show default
directory for _user_ templates...
And I guess that these are the issues why Junio C Hamano wrote:
> * The 'pu' branch, in addition, has these.
>
> - $HOME/.gitrc (Petr Baudis)
> Read configuration also from ~/.gitrc
>
> * I like this but it breaks the tests big time. Not "next"
> material yet, unfortunately.
--
Jakub Narebski
Warsaw, Poland
^ permalink raw reply
* Re: gitk highlighting descendents/ancestors
From: Matthias Kestenholz @ 2006-05-29 12:55 UTC (permalink / raw)
To: Paul Mackerras; +Cc: git
In-Reply-To: <17530.60026.636981.60532@cargo.ozlabs.ibm.com>
Hi,
* Paul Mackerras (paulus@samba.org) wrote:
> I have implemented a feature in gitk (on the "new" branch) where it
> can highlight the commits that are, or are not, descendents or
> ancestors of the selected commit. For now it is invoked via a
> drop-down menu. Does this look useful to people?
>
Yes, this is very useful for me. I have a complicated history graph
because I manage the codebase for several websites with one git
repository. It gets very hard to follow the colored lines in gitk
when there are many merges of feature branches.
The most useful feature for me is probably the "ancestor" view; "not
ancestor" could also be interesting if I wanted to visualize which
feature branches were already merged and which are not.
Thanks,
Matthias
^ permalink raw reply
* gitk highlighting descendents/ancestors
From: Paul Mackerras @ 2006-05-29 12:35 UTC (permalink / raw)
To: git
I have implemented a feature in gitk (on the "new" branch) where it
can highlight the commits that are, or are not, descendents or
ancestors of the selected commit. For now it is invoked via a
drop-down menu. Does this look useful to people?
At the moment, if you select "Not descendent" then the selected
commit and all the commits below it will be highlighted (since they
can't be descendents of the selected commit). Similarly if you select
"Not ancestor" then the selected commit and all commits above it are
highlighted. That's technically correct but doesn't seem very useful;
maybe I should suppress those highlights.
Also, whatever matches the string put in the "Find" field will be
highlighted. I have taken out the "Files" and "Pickaxe" options in
the Find function, and put the pickaxe function into a new drop-down
menu for the highlighting function. I have code ready to go for
shift-up and shift-down to move to the previous/next highlighted row,
once Junio applies my tiny patch to builtin-diff-tree.c.
Paul.
^ permalink raw reply
* [PATCH] Make git-diff-tree indicate when it flushes
From: Paul Mackerras @ 2006-05-29 12:24 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
There are times when gitk needs to know that the commits it has sent
to git-diff-tree --stdin did not match, and it needs to know in a
timely fashion even if none of them match. At the moment,
git-diff-tree outputs nothing for non-matching commits, so it is
impossible for gitk to distinguish between git-diff-tree being slow
and git-diff-tree saying no.
This makes git-diff-tree output a blank line in response to a blank
line in its input (which already causes git-diff-tree to flush its
output buffers). Gitk, or other users of git-diff-tree --stdin, can
use the blank line to indicate that git-diff-tree has processed all
the commits on its input up to the input blank line, and any commits
that have not been output do not match.
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
diff --git a/builtin-diff-tree.c b/builtin-diff-tree.c
index cc53b81..dbe5737 100644
--- a/builtin-diff-tree.c
+++ b/builtin-diff-tree.c
@@ -139,9 +139,10 @@ int cmd_diff_tree(int argc, const char *
opt->diffopt.setup |= (DIFF_SETUP_USE_SIZE_CACHE |
DIFF_SETUP_USE_CACHE);
while (fgets(line, sizeof(line), stdin))
- if (line[0] == '\n')
+ if (line[0] == '\n') {
+ putchar('\n');
fflush(stdout);
- else
+ } else
diff_tree_stdin(line);
return 0;
^ permalink raw reply related
* RE: [PATCH] git-receive-pack needs to set umask(2)
From: Zakirov, Salikh @ 2006-05-29 12:07 UTC (permalink / raw)
To: spearce; +Cc: git
Thanks a lot, that works!
Shawn wrote:
>
> > Could you please elaborate on what does it mean "make it shared"?
>
> Try setting 'core.sharedRepository' to true:
>
>
> git repo-config core.sharedRepository true
>
> and running your chmod script one last time. See
> Documentation/config.txt for some details on this switch.
^ permalink raw reply
* Re: [PATCH] git-receive-pack needs to set umask(2)
From: Shawn Pearce @ 2006-05-29 11:33 UTC (permalink / raw)
To: Salikh Zakirov; +Cc: git
In-Reply-To: <447ADAEF.3030806@Intel.com>
Salikh Zakirov <Salikh.Zakirov@Intel.com> wrote:
> Johannes Schindelin wrote:
> > See also
> >
> > http://thread.gmane.org/gmane.comp.version-control.git/13856/focus=13876
>
> I've read the thread, but couldn't find a practical solution there.
>
> > The essence of the thread: If you want to do anything useful in a non-bare
> > repository, you are likely using other tools than git, which do not
> > interpret core.umask or $GIT_DIR/umask.
> >
> > If you use a bare repository, just make it shared. No need for an umask.
>
> Could you please elaborate on what does it mean "make it shared"?
>
> My setup: I have a bare GIT repository on a machine, where everybody can
> SSH into (with full shell access). I've assigned the repo to a special group
> where everybody belongs, and done a 'find repo.git -type d | xargs chmod 2775'
>
> The problem: After someone pushed to the repository, the object directories
> (i.e repo.git/objects/??)
> get created with 755 access rights, and effectively prevent everyone else from pushing
> objects starting with the same prefix.
>
> The obvious solution to use umask 002 is not applicable, because
> 1) It does not seem practical to enforce umask 002 in everyone's rc files,
> because just one forgetful or careless person can break access for all others
> 2) I have 'umask 002' in my ~/.profile. Somehow, it does not help,
> because ~/.profile is not read on non-interactive SSH sessions
> (to verify that, just try to do 'ssh somehost umask')
>
> The current workaround for the problem is a cron script, which
> makes 'find | xargs chmod 2775' every 5 minutes. It works, but is ugly.
>
> Is there any better way to keep correct access rights in a shared repository?
Try setting 'core.sharedRepository' to true:
git repo-config core.sharedRepository true
and running your chmod script one last time. See
Documentation/config.txt for some details on this switch.
--
Shawn.
^ permalink raw reply
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