1
0
mirror of https://github.com/git/git synced 2024-07-07 19:39:27 +00:00

Merge branch 'bc/tree-walk-oid'

The code to walk tree objects has been taught that we may be
working with object names that are not computed with SHA-1.

* bc/tree-walk-oid:
  cache: make oidcpy always copy GIT_MAX_RAWSZ bytes
  tree-walk: store object_id in a separate member
  match-trees: use hashcpy to splice trees
  match-trees: compute buffer offset correctly when splicing
  tree-walk: copy object ID before use
This commit is contained in:
Junio C Hamano 2019-01-29 12:47:56 -08:00
commit 371820d5f1
21 changed files with 84 additions and 98 deletions

View File

@ -570,7 +570,7 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
strbuf_add(base, entry.path, te_len); strbuf_add(base, entry.path, te_len);
if (S_ISREG(entry.mode)) { if (S_ISREG(entry.mode)) {
hit |= grep_oid(opt, entry.oid, base->buf, tn_len, hit |= grep_oid(opt, &entry.oid, base->buf, tn_len,
check_attr ? base->buf + tn_len : NULL); check_attr ? base->buf + tn_len : NULL);
} else if (S_ISDIR(entry.mode)) { } else if (S_ISDIR(entry.mode)) {
enum object_type type; enum object_type type;
@ -578,10 +578,10 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
void *data; void *data;
unsigned long size; unsigned long size;
data = lock_and_read_oid_file(entry.oid, &type, &size); data = lock_and_read_oid_file(&entry.oid, &type, &size);
if (!data) if (!data)
die(_("unable to read tree (%s)"), die(_("unable to read tree (%s)"),
oid_to_hex(entry.oid)); oid_to_hex(&entry.oid));
strbuf_addch(base, '/'); strbuf_addch(base, '/');
init_tree_desc(&sub, data, size); init_tree_desc(&sub, data, size);
@ -589,7 +589,7 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
check_attr, repo); check_attr, repo);
free(data); free(data);
} else if (recurse_submodules && S_ISGITLINK(entry.mode)) { } else if (recurse_submodules && S_ISGITLINK(entry.mode)) {
hit |= grep_submodule(opt, repo, pathspec, entry.oid, hit |= grep_submodule(opt, repo, pathspec, &entry.oid,
base->buf, base->buf + tn_len); base->buf, base->buf + tn_len);
} }

View File

@ -154,15 +154,15 @@ static void show_result(void)
/* An empty entry never compares same, not even to another empty entry */ /* An empty entry never compares same, not even to another empty entry */
static int same_entry(struct name_entry *a, struct name_entry *b) static int same_entry(struct name_entry *a, struct name_entry *b)
{ {
return a->oid && return !is_null_oid(&a->oid) &&
b->oid && !is_null_oid(&b->oid) &&
oideq(a->oid, b->oid) && oideq(&a->oid, &b->oid) &&
a->mode == b->mode; a->mode == b->mode;
} }
static int both_empty(struct name_entry *a, struct name_entry *b) static int both_empty(struct name_entry *a, struct name_entry *b)
{ {
return !(a->oid || b->oid); return is_null_oid(&a->oid) && is_null_oid(&b->oid);
} }
static struct merge_list *create_entry(unsigned stage, unsigned mode, const struct object_id *oid, const char *path) static struct merge_list *create_entry(unsigned stage, unsigned mode, const struct object_id *oid, const char *path)
@ -178,7 +178,7 @@ static struct merge_list *create_entry(unsigned stage, unsigned mode, const stru
static char *traverse_path(const struct traverse_info *info, const struct name_entry *n) static char *traverse_path(const struct traverse_info *info, const struct name_entry *n)
{ {
char *path = xmallocz(traverse_path_len(info, n)); char *path = xmallocz(traverse_path_len(info, n) + the_hash_algo->rawsz);
return make_traverse_path(path, info, n); return make_traverse_path(path, info, n);
} }
@ -192,8 +192,8 @@ static void resolve(const struct traverse_info *info, struct name_entry *ours, s
return; return;
path = traverse_path(info, result); path = traverse_path(info, result);
orig = create_entry(2, ours->mode, ours->oid, path); orig = create_entry(2, ours->mode, &ours->oid, path);
final = create_entry(0, result->mode, result->oid, path); final = create_entry(0, result->mode, &result->oid, path);
final->link = orig; final->link = orig;
@ -217,7 +217,7 @@ static void unresolved_directory(const struct traverse_info *info,
newbase = traverse_path(info, p); newbase = traverse_path(info, p);
#define ENTRY_OID(e) (((e)->mode && S_ISDIR((e)->mode)) ? (e)->oid : NULL) #define ENTRY_OID(e) (((e)->mode && S_ISDIR((e)->mode)) ? &(e)->oid : NULL)
buf0 = fill_tree_descriptor(t + 0, ENTRY_OID(n + 0)); buf0 = fill_tree_descriptor(t + 0, ENTRY_OID(n + 0));
buf1 = fill_tree_descriptor(t + 1, ENTRY_OID(n + 1)); buf1 = fill_tree_descriptor(t + 1, ENTRY_OID(n + 1));
buf2 = fill_tree_descriptor(t + 2, ENTRY_OID(n + 2)); buf2 = fill_tree_descriptor(t + 2, ENTRY_OID(n + 2));
@ -243,7 +243,7 @@ static struct merge_list *link_entry(unsigned stage, const struct traverse_info
path = entry->path; path = entry->path;
else else
path = traverse_path(info, n); path = traverse_path(info, n);
link = create_entry(stage, n->mode, n->oid, path); link = create_entry(stage, n->mode, &n->oid, path);
link->link = entry; link->link = entry;
return link; return link;
} }
@ -318,7 +318,7 @@ static int threeway_callback(int n, unsigned long mask, unsigned long dirmask, s
} }
if (same_entry(entry+0, entry+1)) { if (same_entry(entry+0, entry+1)) {
if (entry[2].oid && !S_ISDIR(entry[2].mode)) { if (!is_null_oid(&entry[2].oid) && !S_ISDIR(entry[2].mode)) {
/* We did not touch, they modified -- take theirs */ /* We did not touch, they modified -- take theirs */
resolve(info, entry+1, entry+2); resolve(info, entry+1, entry+2);
return mask; return mask;

View File

@ -1334,7 +1334,7 @@ static void add_pbase_object(struct tree_desc *tree,
if (cmp < 0) if (cmp < 0)
return; return;
if (name[cmplen] != '/') { if (name[cmplen] != '/') {
add_object_entry(entry.oid, add_object_entry(&entry.oid,
object_type(entry.mode), object_type(entry.mode),
fullname, 1); fullname, 1);
return; return;
@ -1345,7 +1345,7 @@ static void add_pbase_object(struct tree_desc *tree,
const char *down = name+cmplen+1; const char *down = name+cmplen+1;
int downlen = name_cmp_len(down); int downlen = name_cmp_len(down);
tree = pbase_tree_get(entry.oid); tree = pbase_tree_get(&entry.oid);
if (!tree) if (!tree)
return; return;
init_tree_desc(&sub, tree->tree_data, tree->tree_size); init_tree_desc(&sub, tree->tree_data, tree->tree_size);

View File

@ -94,8 +94,8 @@ static int tree_is_complete(const struct object_id *oid)
init_tree_desc(&desc, tree->buffer, tree->size); init_tree_desc(&desc, tree->buffer, tree->size);
complete = 1; complete = 1;
while (tree_entry(&desc, &entry)) { while (tree_entry(&desc, &entry)) {
if (!has_sha1_file(entry.oid->hash) || if (!has_sha1_file(entry.oid.hash) ||
(S_ISDIR(entry.mode) && !tree_is_complete(entry.oid))) { (S_ISDIR(entry.mode) && !tree_is_complete(&entry.oid))) {
tree->object.flags |= INCOMPLETE; tree->object.flags |= INCOMPLETE;
complete = 0; complete = 0;
} }

View File

@ -675,7 +675,7 @@ static void prime_cache_tree_rec(struct repository *r,
cnt++; cnt++;
else { else {
struct cache_tree_sub *sub; struct cache_tree_sub *sub;
struct tree *subtree = lookup_tree(r, entry.oid); struct tree *subtree = lookup_tree(r, &entry.oid);
if (!subtree->object.parsed) if (!subtree->object.parsed)
parse_tree(subtree); parse_tree(subtree);
sub = cache_tree_sub(it, entry.path); sub = cache_tree_sub(it, entry.path);
@ -724,7 +724,7 @@ int cache_tree_matches_traversal(struct cache_tree *root,
it = find_cache_tree_from_traversal(root, info); it = find_cache_tree_from_traversal(root, info);
it = cache_tree_find(it, ent->path); it = cache_tree_find(it, ent->path);
if (it && it->entry_count > 0 && oideq(ent->oid, &it->oid)) if (it && it->entry_count > 0 && oideq(&ent->oid, &it->oid))
return it->entry_count; return it->entry_count;
return 0; return 0;
} }

View File

@ -1084,7 +1084,7 @@ static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src)
static inline void oidcpy(struct object_id *dst, const struct object_id *src) static inline void oidcpy(struct object_id *dst, const struct object_id *src)
{ {
hashcpy(dst->hash, src->hash); memcpy(dst->hash, src->hash, GIT_MAX_RAWSZ);
} }
static inline struct object_id *oiddup(const struct object_id *src) static inline struct object_id *oiddup(const struct object_id *src)

View File

@ -86,36 +86,6 @@ struct object_id OID;
- hashcmp(OID.hash, OIDPTR->hash) - hashcmp(OID.hash, OIDPTR->hash)
+ oidcmp(&OID, OIDPTR) + oidcmp(&OID, OIDPTR)
@@
struct object_id OID1, OID2;
@@
- hashcpy(OID1.hash, OID2.hash)
+ oidcpy(&OID1, &OID2)
@@
identifier f != oidcpy;
struct object_id *OIDPTR1;
struct object_id *OIDPTR2;
@@
f(...) {<...
- hashcpy(OIDPTR1->hash, OIDPTR2->hash)
+ oidcpy(OIDPTR1, OIDPTR2)
...>}
@@
struct object_id *OIDPTR;
struct object_id OID;
@@
- hashcpy(OIDPTR->hash, OID.hash)
+ oidcpy(OIDPTR, &OID)
@@
struct object_id *OIDPTR;
struct object_id OID;
@@
- hashcpy(OID.hash, OIDPTR->hash)
+ oidcpy(&OID, OIDPTR)
@@ @@
struct object_id *OIDPTR1; struct object_id *OIDPTR1;
struct object_id *OIDPTR2; struct object_id *OIDPTR2;

View File

@ -296,7 +296,7 @@ void resolve_tree_islands(struct repository *r,
if (S_ISGITLINK(entry.mode)) if (S_ISGITLINK(entry.mode))
continue; continue;
obj = lookup_object(r, entry.oid->hash); obj = lookup_object(r, entry.oid.hash);
if (!obj) if (!obj)
continue; continue;

4
fsck.c
View File

@ -410,14 +410,14 @@ static int fsck_walk_tree(struct tree *tree, void *data, struct fsck_options *op
continue; continue;
if (S_ISDIR(entry.mode)) { if (S_ISDIR(entry.mode)) {
obj = (struct object *)lookup_tree(the_repository, entry.oid); obj = (struct object *)lookup_tree(the_repository, &entry.oid);
if (name && obj) if (name && obj)
put_object_name(options, obj, "%s%s/", name, put_object_name(options, obj, "%s%s/", name,
entry.path); entry.path);
result = options->walk(obj, OBJ_TREE, data, options); result = options->walk(obj, OBJ_TREE, data, options);
} }
else if (S_ISREG(entry.mode) || S_ISLNK(entry.mode)) { else if (S_ISREG(entry.mode) || S_ISLNK(entry.mode)) {
obj = (struct object *)lookup_blob(the_repository, entry.oid); obj = (struct object *)lookup_blob(the_repository, &entry.oid);
if (name && obj) if (name && obj)
put_object_name(options, obj, "%s%s", name, put_object_name(options, obj, "%s%s", name,
entry.path); entry.path);

View File

@ -1311,11 +1311,11 @@ static struct object_list **process_tree(struct tree *tree,
while (tree_entry(&desc, &entry)) while (tree_entry(&desc, &entry))
switch (object_type(entry.mode)) { switch (object_type(entry.mode)) {
case OBJ_TREE: case OBJ_TREE:
p = process_tree(lookup_tree(the_repository, entry.oid), p = process_tree(lookup_tree(the_repository, &entry.oid),
p); p);
break; break;
case OBJ_BLOB: case OBJ_BLOB:
p = process_blob(lookup_blob(the_repository, entry.oid), p = process_blob(lookup_blob(the_repository, &entry.oid),
p); p);
break; break;
default: default:

View File

@ -124,15 +124,15 @@ static void process_tree_contents(struct traversal_context *ctx,
} }
if (S_ISDIR(entry.mode)) { if (S_ISDIR(entry.mode)) {
struct tree *t = lookup_tree(ctx->revs->repo, entry.oid); struct tree *t = lookup_tree(ctx->revs->repo, &entry.oid);
t->object.flags |= NOT_USER_GIVEN; t->object.flags |= NOT_USER_GIVEN;
process_tree(ctx, t, base, entry.path); process_tree(ctx, t, base, entry.path);
} }
else if (S_ISGITLINK(entry.mode)) else if (S_ISGITLINK(entry.mode))
process_gitlink(ctx, entry.oid->hash, process_gitlink(ctx, entry.oid.hash,
base, entry.path); base, entry.path);
else { else {
struct blob *b = lookup_blob(ctx->revs->repo, entry.oid); struct blob *b = lookup_blob(ctx->revs->repo, &entry.oid);
b->object.flags |= NOT_USER_GIVEN; b->object.flags |= NOT_USER_GIVEN;
process_blob(ctx, b, base, entry.path); process_blob(ctx, b, base, entry.path);
} }

View File

@ -106,7 +106,7 @@ static int score_trees(const struct object_id *hash1, const struct object_id *ha
update_tree_entry(&two); update_tree_entry(&two);
} else { } else {
/* path appears in both */ /* path appears in both */
if (!oideq(one.entry.oid, two.entry.oid)) { if (!oideq(&one.entry.oid, &two.entry.oid)) {
/* they are different */ /* they are different */
score += score_differs(one.entry.mode, score += score_differs(one.entry.mode,
two.entry.mode, two.entry.mode,
@ -179,7 +179,7 @@ static int splice_tree(const struct object_id *oid1, const char *prefix,
char *buf; char *buf;
unsigned long sz; unsigned long sz;
struct tree_desc desc; struct tree_desc desc;
struct object_id *rewrite_here; unsigned char *rewrite_here;
const struct object_id *rewrite_with; const struct object_id *rewrite_with;
struct object_id subtree; struct object_id subtree;
enum object_type type; enum object_type type;
@ -199,15 +199,26 @@ static int splice_tree(const struct object_id *oid1, const char *prefix,
while (desc.size) { while (desc.size) {
const char *name; const char *name;
unsigned mode; unsigned mode;
const struct object_id *oid;
oid = tree_entry_extract(&desc, &name, &mode); tree_entry_extract(&desc, &name, &mode);
if (strlen(name) == toplen && if (strlen(name) == toplen &&
!memcmp(name, prefix, toplen)) { !memcmp(name, prefix, toplen)) {
if (!S_ISDIR(mode)) if (!S_ISDIR(mode))
die("entry %s in tree %s is not a tree", name, die("entry %s in tree %s is not a tree", name,
oid_to_hex(oid1)); oid_to_hex(oid1));
rewrite_here = (struct object_id *)oid;
/*
* We cast here for two reasons:
*
* - to flip the "char *" (for the path) to "unsigned
* char *" (for the hash stored after it)
*
* - to discard the "const"; this is OK because we
* know it points into our non-const "buf"
*/
rewrite_here = (unsigned char *)(desc.entry.path +
strlen(desc.entry.path) +
1);
break; break;
} }
update_tree_entry(&desc); update_tree_entry(&desc);
@ -216,14 +227,16 @@ static int splice_tree(const struct object_id *oid1, const char *prefix,
die("entry %.*s not found in tree %s", toplen, prefix, die("entry %.*s not found in tree %s", toplen, prefix,
oid_to_hex(oid1)); oid_to_hex(oid1));
if (*subpath) { if (*subpath) {
status = splice_tree(rewrite_here, subpath, oid2, &subtree); struct object_id tree_oid;
hashcpy(tree_oid.hash, rewrite_here);
status = splice_tree(&tree_oid, subpath, oid2, &subtree);
if (status) if (status)
return status; return status;
rewrite_with = &subtree; rewrite_with = &subtree;
} else { } else {
rewrite_with = oid2; rewrite_with = oid2;
} }
oidcpy(rewrite_here, rewrite_with); hashcpy(rewrite_here, rewrite_with->hash);
status = write_object_file(buf, sz, tree_type, result); status = write_object_file(buf, sz, tree_type, result);
free(buf); free(buf);
return status; return status;

View File

@ -450,7 +450,7 @@ static void load_subtree(struct notes_tree *t, struct leaf_node *subtree,
l = xcalloc(1, sizeof(*l)); l = xcalloc(1, sizeof(*l));
oidcpy(&l->key_oid, &object_oid); oidcpy(&l->key_oid, &object_oid);
oidcpy(&l->val_oid, entry.oid); oidcpy(&l->val_oid, &entry.oid);
if (note_tree_insert(t, node, n, l, type, if (note_tree_insert(t, node, n, l, type,
combine_notes_concatenate)) combine_notes_concatenate))
die("Failed to load %s %s into notes tree " die("Failed to load %s %s into notes tree "
@ -481,7 +481,7 @@ static void load_subtree(struct notes_tree *t, struct leaf_node *subtree,
} }
strbuf_addstr(&non_note_path, entry.path); strbuf_addstr(&non_note_path, entry.path);
add_non_note(t, strbuf_detach(&non_note_path, NULL), add_non_note(t, strbuf_detach(&non_note_path, NULL),
entry.mode, entry.oid->hash); entry.mode, entry.oid.hash);
} }
} }
free(buf); free(buf);

View File

@ -2097,7 +2097,7 @@ static int add_promisor_object(const struct object_id *oid,
*/ */
return 0; return 0;
while (tree_entry_gently(&desc, &entry)) while (tree_entry_gently(&desc, &entry))
oidset_insert(set, entry.oid); oidset_insert(set, &entry.oid);
} else if (obj->type == OBJ_COMMIT) { } else if (obj->type == OBJ_COMMIT) {
struct commit *commit = (struct commit *) obj; struct commit *commit = (struct commit *) obj;
struct commit_list *parents = commit->parents; struct commit_list *parents = commit->parents;

View File

@ -67,10 +67,10 @@ static void mark_tree_contents_uninteresting(struct repository *r,
while (tree_entry(&desc, &entry)) { while (tree_entry(&desc, &entry)) {
switch (object_type(entry.mode)) { switch (object_type(entry.mode)) {
case OBJ_TREE: case OBJ_TREE:
mark_tree_uninteresting(r, lookup_tree(r, entry.oid)); mark_tree_uninteresting(r, lookup_tree(r, &entry.oid));
break; break;
case OBJ_BLOB: case OBJ_BLOB:
mark_blob_uninteresting(lookup_blob(r, entry.oid)); mark_blob_uninteresting(lookup_blob(r, &entry.oid));
break; break;
default: default:
/* Subproject commit - not in this repository */ /* Subproject commit - not in this repository */

View File

@ -239,7 +239,7 @@ static struct combine_diff_path *emit_path(struct combine_diff_path *p,
DIFF_STATUS_ADDED; DIFF_STATUS_ADDED;
if (tpi_valid) { if (tpi_valid) {
oid_i = tp[i].entry.oid; oid_i = &tp[i].entry.oid;
mode_i = tp[i].entry.mode; mode_i = tp[i].entry.mode;
} }
else { else {
@ -280,7 +280,7 @@ static struct combine_diff_path *emit_path(struct combine_diff_path *p,
/* same rule as in emitthis */ /* same rule as in emitthis */
int tpi_valid = tp && !(tp[i].entry.mode & S_IFXMIN_NEQ); int tpi_valid = tp && !(tp[i].entry.mode & S_IFXMIN_NEQ);
parents_oid[i] = tpi_valid ? tp[i].entry.oid : NULL; parents_oid[i] = tpi_valid ? &tp[i].entry.oid : NULL;
} }
strbuf_add(base, path, pathlen); strbuf_add(base, path, pathlen);
@ -492,7 +492,7 @@ static struct combine_diff_path *ll_diff_tree_paths(
continue; continue;
/* diff(t,pi) != ø */ /* diff(t,pi) != ø */
if (!oideq(t.entry.oid, tp[i].entry.oid) || if (!oideq(&t.entry.oid, &tp[i].entry.oid) ||
(t.entry.mode != tp[i].entry.mode)) (t.entry.mode != tp[i].entry.mode))
continue; continue;

View File

@ -48,7 +48,8 @@ static int decode_tree_entry(struct tree_desc *desc, const char *buf, unsigned l
/* Initialize the descriptor entry */ /* Initialize the descriptor entry */
desc->entry.path = path; desc->entry.path = path;
desc->entry.mode = canon_mode(mode); desc->entry.mode = canon_mode(mode);
desc->entry.oid = (const struct object_id *)(path + len); desc->entry.pathlen = len - 1;
hashcpy(desc->entry.oid.hash, (const unsigned char *)path + len);
return 0; return 0;
} }
@ -107,7 +108,7 @@ static void entry_extract(struct tree_desc *t, struct name_entry *a)
static int update_tree_entry_internal(struct tree_desc *desc, struct strbuf *err) static int update_tree_entry_internal(struct tree_desc *desc, struct strbuf *err)
{ {
const void *buf = desc->buffer; const void *buf = desc->buffer;
const unsigned char *end = desc->entry.oid->hash + the_hash_algo->rawsz; const unsigned char *end = (const unsigned char *)desc->entry.path + desc->entry.pathlen + 1 + the_hash_algo->rawsz;
unsigned long size = desc->size; unsigned long size = desc->size;
unsigned long len = end - (const unsigned char *)buf; unsigned long len = end - (const unsigned char *)buf;
@ -175,9 +176,11 @@ void setup_traverse_info(struct traverse_info *info, const char *base)
pathlen--; pathlen--;
info->pathlen = pathlen ? pathlen + 1 : 0; info->pathlen = pathlen ? pathlen + 1 : 0;
info->name.path = base; info->name.path = base;
info->name.oid = (void *)(base + pathlen + 1); info->name.pathlen = pathlen;
if (pathlen) if (pathlen) {
hashcpy(info->name.oid.hash, (const unsigned char *)base + pathlen + 1);
info->prev = &dummy; info->prev = &dummy;
}
} }
char *make_traverse_path(char *path, const struct traverse_info *info, const struct name_entry *n) char *make_traverse_path(char *path, const struct traverse_info *info, const struct name_entry *n)
@ -502,10 +505,10 @@ static int find_tree_entry(struct tree_desc *t, const char *name, struct object_
int namelen = strlen(name); int namelen = strlen(name);
while (t->size) { while (t->size) {
const char *entry; const char *entry;
const struct object_id *oid; struct object_id oid;
int entrylen, cmp; int entrylen, cmp;
oid = tree_entry_extract(t, &entry, mode); oidcpy(&oid, tree_entry_extract(t, &entry, mode));
entrylen = tree_entry_len(&t->entry); entrylen = tree_entry_len(&t->entry);
update_tree_entry(t); update_tree_entry(t);
if (entrylen > namelen) if (entrylen > namelen)
@ -516,7 +519,7 @@ static int find_tree_entry(struct tree_desc *t, const char *name, struct object_
if (cmp < 0) if (cmp < 0)
break; break;
if (entrylen == namelen) { if (entrylen == namelen) {
oidcpy(result, oid); oidcpy(result, &oid);
return 0; return 0;
} }
if (name[entrylen] != '/') if (name[entrylen] != '/')
@ -524,10 +527,10 @@ static int find_tree_entry(struct tree_desc *t, const char *name, struct object_
if (!S_ISDIR(*mode)) if (!S_ISDIR(*mode))
break; break;
if (++entrylen == namelen) { if (++entrylen == namelen) {
oidcpy(result, oid); oidcpy(result, &oid);
return 0; return 0;
} }
return get_tree_entry(oid, name + entrylen, result, mode); return get_tree_entry(&oid, name + entrylen, result, mode);
} }
return -1; return -1;
} }

View File

@ -1,12 +1,12 @@
#ifndef TREE_WALK_H #ifndef TREE_WALK_H
#define TREE_WALK_H #define TREE_WALK_H
struct index_state; #include "cache.h"
struct strbuf;
struct name_entry { struct name_entry {
const struct object_id *oid; struct object_id oid;
const char *path; const char *path;
int pathlen;
unsigned int mode; unsigned int mode;
}; };
@ -20,12 +20,12 @@ static inline const struct object_id *tree_entry_extract(struct tree_desc *desc,
{ {
*pathp = desc->entry.path; *pathp = desc->entry.path;
*modep = desc->entry.mode; *modep = desc->entry.mode;
return desc->entry.oid; return &desc->entry.oid;
} }
static inline int tree_entry_len(const struct name_entry *ne) static inline int tree_entry_len(const struct name_entry *ne)
{ {
return (const char *)ne->oid - ne->path - 1; return ne->pathlen;
} }
/* /*

10
tree.c
View File

@ -86,7 +86,7 @@ static int read_tree_1(struct repository *r,
continue; continue;
} }
switch (fn(entry.oid, base, switch (fn(&entry.oid, base,
entry.path, entry.mode, stage, context)) { entry.path, entry.mode, stage, context)) {
case 0: case 0:
continue; continue;
@ -97,19 +97,19 @@ static int read_tree_1(struct repository *r,
} }
if (S_ISDIR(entry.mode)) if (S_ISDIR(entry.mode))
oidcpy(&oid, entry.oid); oidcpy(&oid, &entry.oid);
else if (S_ISGITLINK(entry.mode)) { else if (S_ISGITLINK(entry.mode)) {
struct commit *commit; struct commit *commit;
commit = lookup_commit(r, entry.oid); commit = lookup_commit(r, &entry.oid);
if (!commit) if (!commit)
die("Commit %s in submodule path %s%s not found", die("Commit %s in submodule path %s%s not found",
oid_to_hex(entry.oid), oid_to_hex(&entry.oid),
base->buf, entry.path); base->buf, entry.path);
if (parse_commit(commit)) if (parse_commit(commit))
die("Invalid commit %s in submodule path %s%s", die("Invalid commit %s in submodule path %s%s",
oid_to_hex(entry.oid), oid_to_hex(&entry.oid),
base->buf, entry.path); base->buf, entry.path);
oidcpy(&oid, get_commit_tree_oid(commit)); oidcpy(&oid, get_commit_tree_oid(commit));

View File

@ -679,7 +679,7 @@ static int switch_cache_bottom(struct traverse_info *info)
static inline int are_same_oid(struct name_entry *name_j, struct name_entry *name_k) static inline int are_same_oid(struct name_entry *name_j, struct name_entry *name_k)
{ {
return name_j->oid && name_k->oid && oideq(name_j->oid, name_k->oid); return !is_null_oid(&name_j->oid) && !is_null_oid(&name_k->oid) && oideq(&name_j->oid, &name_k->oid);
} }
static int all_trees_same_as_cache_tree(int n, unsigned long dirmask, static int all_trees_same_as_cache_tree(int n, unsigned long dirmask,
@ -857,7 +857,7 @@ static int traverse_trees_recursive(int n, unsigned long dirmask,
else { else {
const struct object_id *oid = NULL; const struct object_id *oid = NULL;
if (dirmask & 1) if (dirmask & 1)
oid = names[i].oid; oid = &names[i].oid;
buf[nr_buf++] = fill_tree_descriptor(t + i, oid); buf[nr_buf++] = fill_tree_descriptor(t + i, oid);
} }
} }
@ -981,7 +981,7 @@ static struct cache_entry *create_ce_entry(const struct traverse_info *info,
ce->ce_mode = create_ce_mode(n->mode); ce->ce_mode = create_ce_mode(n->mode);
ce->ce_flags = create_ce_flags(stage); ce->ce_flags = create_ce_flags(stage);
ce->ce_namelen = len; ce->ce_namelen = len;
oidcpy(&ce->oid, n->oid); oidcpy(&ce->oid, &n->oid);
make_traverse_path(ce->name, info, n); make_traverse_path(ce->name, info, n);
return ce; return ce;

View File

@ -50,13 +50,13 @@ static int process_tree(struct walker *walker, struct tree *tree)
continue; continue;
if (S_ISDIR(entry.mode)) { if (S_ISDIR(entry.mode)) {
struct tree *tree = lookup_tree(the_repository, struct tree *tree = lookup_tree(the_repository,
entry.oid); &entry.oid);
if (tree) if (tree)
obj = &tree->object; obj = &tree->object;
} }
else { else {
struct blob *blob = lookup_blob(the_repository, struct blob *blob = lookup_blob(the_repository,
entry.oid); &entry.oid);
if (blob) if (blob)
obj = &blob->object; obj = &blob->object;
} }