1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-11-17 14:34:49 +01:00

Merge branch 'jc/lt-tree-n-cache-tree' into next

* jc/lt-tree-n-cache-tree:
  adjust to the rebased series by Linus.
  Remove last vestiges of generic tree_entry_list
  Convert fetch.c: process_tree() to raw tree walker
  Convert "mark_tree_uninteresting()" to raw tree walker
  Remove unused "zeropad" entry from tree_list_entry
  fsck-objects: avoid unnecessary tree_entry_list usage
  Remove "tree->entries" tree-entry list from tree parser
  builtin-read-tree.c: avoid tree_entry_list in prime_cache_tree_rec()
  Switch "read_tree_recursive()" over to tree-walk functionality
  Make "tree_entry" have a SHA1 instead of a union of object pointers
  Make "struct tree" contain the pointer to the tree buffer
  Make git-diff-tree indicate when it flushes
  Remove unnecessary output from t3600-rm.
This commit is contained in:
Junio C Hamano 2006-05-29 22:16:56 -07:00
commit 5029f6458f
8 changed files with 151 additions and 126 deletions

View file

@ -138,11 +138,15 @@ int cmd_diff_tree(int argc, const char **argv, char **envp)
if (opt->diffopt.detect_rename) if (opt->diffopt.detect_rename)
opt->diffopt.setup |= (DIFF_SETUP_USE_SIZE_CACHE | opt->diffopt.setup |= (DIFF_SETUP_USE_SIZE_CACHE |
DIFF_SETUP_USE_CACHE); DIFF_SETUP_USE_CACHE);
while (fgets(line, sizeof(line), stdin)) while (fgets(line, sizeof(line), stdin)) {
if (line[0] == '\n') unsigned char sha1[20];
if (get_sha1_hex(line, sha1)) {
fputs(line, stdout);
fflush(stdout); fflush(stdout);
}
else else
diff_tree_stdin(line); diff_tree_stdin(line);
}
return 0; return 0;
} }

View file

@ -9,8 +9,8 @@
#include "object.h" #include "object.h"
#include "tree.h" #include "tree.h"
#include "cache-tree.h"
#include "tree-walk.h" #include "tree-walk.h"
#include "cache-tree.h"
#include <sys/time.h> #include <sys/time.h>
#include <signal.h> #include <signal.h>
#include "builtin.h" #include "builtin.h"
@ -31,7 +31,17 @@ static int merge_size = 0;
static struct object_list *trees = NULL; static struct object_list *trees = NULL;
static struct cache_entry df_conflict_entry = { 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 = { static struct tree_entry_list df_conflict_list = {
@ -41,6 +51,39 @@ static struct tree_entry_list df_conflict_list = {
typedef int (*merge_fn_t)(struct cache_entry **src); 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) static int entcmp(const char *name1, int dir1, const char *name2, int dir2)
{ {
int len1 = strlen(name1); int len1 = strlen(name1);
@ -803,12 +846,12 @@ static int read_cache_unmerged(void)
static void prime_cache_tree_rec(struct cache_tree *it, struct tree *tree) static void prime_cache_tree_rec(struct cache_tree *it, struct tree *tree)
{ {
struct tree_desc desc; struct tree_desc desc;
int cnt = 0; int cnt;
memcpy(it->sha1, tree->object.sha1, 20); memcpy(it->sha1, tree->object.sha1, 20);
desc.buf = tree->buffer; desc.buf = tree->buffer;
desc.size = tree->size; desc.size = tree->size;
cnt = 0;
while (desc.size) { while (desc.size) {
unsigned mode; unsigned mode;
const char *name; const char *name;
@ -816,14 +859,11 @@ static void prime_cache_tree_rec(struct cache_tree *it, struct tree *tree)
sha1 = tree_entry_extract(&desc, &name, &mode); sha1 = tree_entry_extract(&desc, &name, &mode);
update_tree_entry(&desc); update_tree_entry(&desc);
if (!S_ISDIR(mode)) if (!S_ISDIR(mode))
cnt++; cnt++;
else { else {
struct cache_tree_sub *sub; struct cache_tree_sub *sub;
struct tree *subtree; struct tree *subtree = lookup_tree(sha1);
subtree = lookup_tree(sha1);
if (!subtree->object.parsed) if (!subtree->object.parsed)
parse_tree(subtree); parse_tree(subtree);
sub = cache_tree_sub(it, name); sub = cache_tree_sub(it, name);

24
fetch.c
View file

@ -3,6 +3,7 @@
#include "cache.h" #include "cache.h"
#include "commit.h" #include "commit.h"
#include "tree.h" #include "tree.h"
#include "tree-walk.h"
#include "tag.h" #include "tag.h"
#include "blob.h" #include "blob.h"
#include "refs.h" #include "refs.h"
@ -37,27 +38,32 @@ static int process(struct object *obj);
static int process_tree(struct tree *tree) static int process_tree(struct tree *tree)
{ {
struct tree_entry_list *entry; struct tree_desc desc;
if (parse_tree(tree)) if (parse_tree(tree))
return -1; return -1;
entry = create_tree_entry_list(tree); desc.buf = tree->buffer;
while (entry) { desc.size = tree->size;
struct tree_entry_list *next = entry->next; while (desc.size) {
unsigned mode;
const char *name;
const unsigned char *sha1;
if (entry->directory) { sha1 = tree_entry_extract(&desc, &name, &mode);
struct tree *tree = lookup_tree(entry->sha1); update_tree_entry(&desc);
if (S_ISDIR(mode)) {
struct tree *tree = lookup_tree(sha1);
process_tree(tree); process_tree(tree);
} else { } else {
struct blob *blob = lookup_blob(entry->sha1); struct blob *blob = lookup_blob(sha1);
process(&blob->object); process(&blob->object);
} }
free(entry);
entry = next;
} }
free(tree->buffer); free(tree->buffer);
tree->buffer = NULL; tree->buffer = NULL;
tree->size = 0;
return 0; return 0;
} }

View file

@ -9,6 +9,7 @@
#include "refs.h" #include "refs.h"
#include "pack.h" #include "pack.h"
#include "cache-tree.h" #include "cache-tree.h"
#include "tree-walk.h"
#define REACHABLE 0x0001 #define REACHABLE 0x0001
#define SEEN 0x0002 #define SEEN 0x0002
@ -116,15 +117,15 @@ static void check_connectivity(void)
#define TREE_UNORDERED (-1) #define TREE_UNORDERED (-1)
#define TREE_HAS_DUPS (-2) #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 len1 = strlen(name1);
int len2 = strlen(b->name); int len2 = strlen(name2);
int len = len1 < len2 ? len1 : len2; int len = len1 < len2 ? len1 : len2;
unsigned char c1, c2; unsigned char c1, c2;
int cmp; int cmp;
cmp = memcmp(a->name, b->name, len); cmp = memcmp(name1, name2, len);
if (cmp < 0) if (cmp < 0)
return 0; return 0;
if (cmp > 0) if (cmp > 0)
@ -135,8 +136,8 @@ static int verify_ordered(struct tree_entry_list *a, struct tree_entry_list *b)
* Now we need to order the next one, but turn * Now we need to order the next one, but turn
* a '\0' into a '/' for a directory entry. * a '\0' into a '/' for a directory entry.
*/ */
c1 = a->name[len]; c1 = name1[len];
c2 = b->name[len]; c2 = name2[len];
if (!c1 && !c2) if (!c1 && !c2)
/* /*
* git-write-tree used to write out a nonsense tree that has * git-write-tree used to write out a nonsense tree that has
@ -144,9 +145,9 @@ static int verify_ordered(struct tree_entry_list *a, struct tree_entry_list *b)
* sure we do not have duplicate entries. * sure we do not have duplicate entries.
*/ */
return TREE_HAS_DUPS; return TREE_HAS_DUPS;
if (!c1 && a->directory) if (!c1 && S_ISDIR(mode1))
c1 = '/'; c1 = '/';
if (!c2 && b->directory) if (!c2 && S_ISDIR(mode2))
c2 = '/'; c2 = '/';
return c1 < c2 ? 0 : TREE_UNORDERED; return c1 < c2 ? 0 : TREE_UNORDERED;
} }
@ -159,17 +160,32 @@ static int fsck_tree(struct tree *item)
int has_bad_modes = 0; int has_bad_modes = 0;
int has_dup_entries = 0; int has_dup_entries = 0;
int not_properly_sorted = 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; desc.buf = item->buffer;
for (entry = create_tree_entry_list(item); entry; entry = entry->next) { desc.size = item->size;
if (strchr(entry->name, '/'))
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_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.. * Standard modes..
*/ */
case S_IFREG | 0755: case S_IFREG | 0755:
case S_IFREG | 0644: case S_IFREG | 0644:
@ -188,8 +204,8 @@ static int fsck_tree(struct tree *item)
has_bad_modes = 1; has_bad_modes = 1;
} }
if (last) { if (o_name) {
switch (verify_ordered(last, entry)) { switch (verify_ordered(o_mode, o_name, mode, name)) {
case TREE_UNORDERED: case TREE_UNORDERED:
not_properly_sorted = 1; not_properly_sorted = 1;
break; break;
@ -199,13 +215,12 @@ static int fsck_tree(struct tree *item)
default: default:
break; break;
} }
free(last);
} }
last = entry; o_mode = mode;
o_name = name;
o_sha1 = sha1;
} }
if (last)
free(last);
free(item->buffer); free(item->buffer);
item->buffer = NULL; item->buffer = NULL;

View file

@ -53,8 +53,8 @@ static void mark_blob_uninteresting(struct blob *blob)
void mark_tree_uninteresting(struct tree *tree) void mark_tree_uninteresting(struct tree *tree)
{ {
struct tree_desc desc;
struct object *obj = &tree->object; struct object *obj = &tree->object;
struct tree_entry_list *entry;
if (obj->flags & UNINTERESTING) if (obj->flags & UNINTERESTING)
return; return;
@ -63,16 +63,29 @@ void mark_tree_uninteresting(struct tree *tree)
return; return;
if (parse_tree(tree) < 0) if (parse_tree(tree) < 0)
die("bad tree %s", sha1_to_hex(obj->sha1)); die("bad tree %s", sha1_to_hex(obj->sha1));
entry = create_tree_entry_list(tree);
while (entry) { desc.buf = tree->buffer;
struct tree_entry_list *next = entry->next; desc.size = tree->size;
if (entry->directory) while (desc.size) {
mark_tree_uninteresting(lookup_tree(entry->sha1)); 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 else
mark_blob_uninteresting(lookup_blob(entry->sha1)); mark_blob_uninteresting(lookup_blob(sha1));
free(entry);
entry = next;
} }
/*
* 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) void mark_parents_uninteresting(struct commit *commit)

View file

@ -8,30 +8,34 @@ test_description='Test of the various options to git-rm.'
. ./test-lib.sh . ./test-lib.sh
# Setup some files to be removed, some with funny characters # Setup some files to be removed, some with funny characters
touch -- foo bar baz 'space embedded' -q test_expect_success \
git-add -- foo bar baz 'space embedded' -q 'Initialize test directory' \
git-commit -m "add normal files" "touch -- foo bar baz 'space embedded' -q &&
test_tabs=y git-add -- foo bar baz 'space embedded' -q &&
if touch -- 'tab embedded' 'newline git-commit -m 'add normal files' &&
test_tabs=y &&
if touch -- 'tab embedded' 'newline
embedded' embedded'
then then
git-add -- 'tab embedded' 'newline git-add -- 'tab embedded' 'newline
embedded' embedded' &&
git-commit -m "add files with tabs and newlines" git-commit -m 'add files with tabs and newlines'
else else
say 'Your filesystem does not allow tabs in filenames.' say 'Your filesystem does not allow tabs in filenames.'
test_tabs=n test_tabs=n
fi fi"
# Later we will try removing an unremovable path to make sure # Later we will try removing an unremovable path to make sure
# git-rm barfs, but if the test is run as root that cannot be # git-rm barfs, but if the test is run as root that cannot be
# arranged. # arranged.
: >test-file test_expect_success \
chmod a-w . 'Determine rm behavior' \
rm -f test-file ': >test-file
test -f test-file && test_failed_remove=y chmod a-w .
chmod 775 . rm -f test-file
rm -f test-file test -f test-file && test_failed_remove=y
chmod 775 .
rm -f test-file'
test_expect_success \ test_expect_success \
'Pre-check that foo exists and is in index before git-rm foo' \ 'Pre-check that foo exists and is in index before git-rm foo' \

43
tree.c
View file

@ -201,49 +201,6 @@ int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size)
return 0; 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);
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->zeropad = *(const char *)(desc.buf) == '0';
entry->next = NULL;
update_tree_entry(&desc);
*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) int parse_tree(struct tree *item)
{ {
char type[20]; char type[20];

14
tree.h
View file

@ -5,26 +5,12 @@
extern const char *tree_type; extern const char *tree_type;
struct tree_entry_list {
struct tree_entry_list *next;
unsigned directory : 1;
unsigned executable : 1;
unsigned symlink : 1;
unsigned zeropad : 1;
unsigned int mode;
const char *name;
const unsigned char *sha1;
};
struct tree { struct tree {
struct object object; struct object object;
void *buffer; void *buffer;
unsigned long size; 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); struct tree *lookup_tree(const unsigned char *sha1);
int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size); int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size);