Shrink "struct object" a bit
This shrinks "struct object" by a small amount, by getting rid of the "struct type *" pointer and replacing it with a 3-bit bitfield instead. In addition, we merge the bitfields and the "flags" field, which incidentally should also remove a useless 4-byte padding from the object when in 64-bit mode. Now, our "struct object" is still too damn large, but it's now less obviously bloated, and of the remaining fields, only the "util" (which is not used by most things) is clearly something that should be eventually discarded. This shrinks the "git-rev-list --all" memory use by about 2.5% on the kernel archive (and, perhaps more importantly, on the larger mozilla archive). That may not sound like much, but I suspect it's more on a 64-bit platform. There are other remaining inefficiencies (the parent lists, for example, probably have horrible malloc overhead), but this was pretty obvious. Most of the patch is just changing the comparison of the "type" pointer from one of the constant string pointers to the appropriate new TYPE_xxx small integer constant. Signed-off-by: Linus Torvalds <torvalds@osdl.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
parent
210a0be504
commit
885a86abe2
10
blob.c
10
blob.c
@ -10,14 +10,14 @@ struct blob *lookup_blob(const unsigned char *sha1)
|
|||||||
if (!obj) {
|
if (!obj) {
|
||||||
struct blob *ret = xcalloc(1, sizeof(struct blob));
|
struct blob *ret = xcalloc(1, sizeof(struct blob));
|
||||||
created_object(sha1, &ret->object);
|
created_object(sha1, &ret->object);
|
||||||
ret->object.type = blob_type;
|
ret->object.type = TYPE_BLOB;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (!obj->type)
|
if (!obj->type)
|
||||||
obj->type = blob_type;
|
obj->type = TYPE_BLOB;
|
||||||
if (obj->type != blob_type) {
|
if (obj->type != TYPE_BLOB) {
|
||||||
error("Object %s is a %s, not a blob",
|
error("Object %s is a %s, not a blob",
|
||||||
sha1_to_hex(sha1), obj->type);
|
sha1_to_hex(sha1), typename(obj->type));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return (struct blob *) obj;
|
return (struct blob *) obj;
|
||||||
|
@ -303,9 +303,9 @@ int cmd_diff(int argc, const char **argv, char **envp)
|
|||||||
obj = deref_tag(obj, NULL, 0);
|
obj = deref_tag(obj, NULL, 0);
|
||||||
if (!obj)
|
if (!obj)
|
||||||
die("invalid object '%s' given.", name);
|
die("invalid object '%s' given.", name);
|
||||||
if (!strcmp(obj->type, commit_type))
|
if (obj->type == TYPE_COMMIT)
|
||||||
obj = &((struct commit *)obj)->tree->object;
|
obj = &((struct commit *)obj)->tree->object;
|
||||||
if (!strcmp(obj->type, tree_type)) {
|
if (obj->type == TYPE_TREE) {
|
||||||
if (ARRAY_SIZE(ent) <= ents)
|
if (ARRAY_SIZE(ent) <= ents)
|
||||||
die("more than %d trees given: '%s'",
|
die("more than %d trees given: '%s'",
|
||||||
(int) ARRAY_SIZE(ent), name);
|
(int) ARRAY_SIZE(ent), name);
|
||||||
@ -315,7 +315,7 @@ int cmd_diff(int argc, const char **argv, char **envp)
|
|||||||
ents++;
|
ents++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!strcmp(obj->type, blob_type)) {
|
if (obj->type == TYPE_BLOB) {
|
||||||
if (2 <= blobs)
|
if (2 <= blobs)
|
||||||
die("more than two blobs given: '%s'", name);
|
die("more than two blobs given: '%s'", name);
|
||||||
memcpy(blob[blobs].sha1, obj->sha1, 20);
|
memcpy(blob[blobs].sha1, obj->sha1, 20);
|
||||||
|
@ -630,10 +630,9 @@ static int grep_tree(struct grep_opt *opt, const char **paths,
|
|||||||
static int grep_object(struct grep_opt *opt, const char **paths,
|
static int grep_object(struct grep_opt *opt, const char **paths,
|
||||||
struct object *obj, const char *name)
|
struct object *obj, const char *name)
|
||||||
{
|
{
|
||||||
if (!strcmp(obj->type, blob_type))
|
if (obj->type == TYPE_BLOB)
|
||||||
return grep_sha1(opt, obj->sha1, name);
|
return grep_sha1(opt, obj->sha1, name);
|
||||||
if (!strcmp(obj->type, commit_type) ||
|
if (obj->type == TYPE_COMMIT || obj->type == TYPE_TREE) {
|
||||||
!strcmp(obj->type, tree_type)) {
|
|
||||||
struct tree_desc tree;
|
struct tree_desc tree;
|
||||||
void *data;
|
void *data;
|
||||||
int hit;
|
int hit;
|
||||||
@ -646,7 +645,7 @@ static int grep_object(struct grep_opt *opt, const char **paths,
|
|||||||
free(data);
|
free(data);
|
||||||
return hit;
|
return hit;
|
||||||
}
|
}
|
||||||
die("unable to grep from object of type %s", obj->type);
|
die("unable to grep from object of type %s", typename(obj->type));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char builtin_grep_usage[] =
|
static const char builtin_grep_usage[] =
|
||||||
|
@ -158,16 +158,16 @@ static void show_commit_list(struct rev_info *revs)
|
|||||||
const char *name = pending->name;
|
const char *name = pending->name;
|
||||||
if (obj->flags & (UNINTERESTING | SEEN))
|
if (obj->flags & (UNINTERESTING | SEEN))
|
||||||
continue;
|
continue;
|
||||||
if (obj->type == tag_type) {
|
if (obj->type == TYPE_TAG) {
|
||||||
obj->flags |= SEEN;
|
obj->flags |= SEEN;
|
||||||
p = add_object(obj, p, NULL, name);
|
p = add_object(obj, p, NULL, name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (obj->type == tree_type) {
|
if (obj->type == TYPE_TREE) {
|
||||||
p = process_tree((struct tree *)obj, p, NULL, name);
|
p = process_tree((struct tree *)obj, p, NULL, name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (obj->type == blob_type) {
|
if (obj->type == TYPE_BLOB) {
|
||||||
p = process_blob((struct blob *)obj, p, NULL, name);
|
p = process_blob((struct blob *)obj, p, NULL, name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ static const char **default_arg = NULL;
|
|||||||
#define UNINTERESTING 01
|
#define UNINTERESTING 01
|
||||||
|
|
||||||
#define REV_SHIFT 2
|
#define REV_SHIFT 2
|
||||||
#define MAX_REVS 29 /* should not exceed bits_per_int - REV_SHIFT */
|
#define MAX_REVS (FLAG_BITS - REV_SHIFT) /* should not exceed bits_per_int - REV_SHIFT */
|
||||||
|
|
||||||
static struct commit *interesting(struct commit_list *list)
|
static struct commit *interesting(struct commit_list *list)
|
||||||
{
|
{
|
||||||
|
8
commit.c
8
commit.c
@ -56,10 +56,10 @@ static struct commit *check_commit(struct object *obj,
|
|||||||
const unsigned char *sha1,
|
const unsigned char *sha1,
|
||||||
int quiet)
|
int quiet)
|
||||||
{
|
{
|
||||||
if (obj->type != commit_type) {
|
if (obj->type != TYPE_COMMIT) {
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
error("Object %s is a %s, not a commit",
|
error("Object %s is a %s, not a commit",
|
||||||
sha1_to_hex(sha1), obj->type);
|
sha1_to_hex(sha1), typename(obj->type));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return (struct commit *) obj;
|
return (struct commit *) obj;
|
||||||
@ -86,11 +86,11 @@ struct commit *lookup_commit(const unsigned char *sha1)
|
|||||||
if (!obj) {
|
if (!obj) {
|
||||||
struct commit *ret = xcalloc(1, sizeof(struct commit));
|
struct commit *ret = xcalloc(1, sizeof(struct commit));
|
||||||
created_object(sha1, &ret->object);
|
created_object(sha1, &ret->object);
|
||||||
ret->object.type = commit_type;
|
ret->object.type = TYPE_COMMIT;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (!obj->type)
|
if (!obj->type)
|
||||||
obj->type = commit_type;
|
obj->type = TYPE_COMMIT;
|
||||||
return check_commit(obj, sha1, 0);
|
return check_commit(obj, sha1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ static int get_name(const char *path, const unsigned char *sha1)
|
|||||||
* Otherwise only annotated tags are used.
|
* Otherwise only annotated tags are used.
|
||||||
*/
|
*/
|
||||||
if (!strncmp(path, "refs/tags/", 10)) {
|
if (!strncmp(path, "refs/tags/", 10)) {
|
||||||
if (object->type == tag_type)
|
if (object->type == TYPE_TAG)
|
||||||
prio = 2;
|
prio = 2;
|
||||||
else
|
else
|
||||||
prio = 1;
|
prio = 1;
|
||||||
|
10
fetch-pack.c
10
fetch-pack.c
@ -46,7 +46,7 @@ static int rev_list_insert_ref(const char *path, const unsigned char *sha1)
|
|||||||
{
|
{
|
||||||
struct object *o = deref_tag(parse_object(sha1), path, 0);
|
struct object *o = deref_tag(parse_object(sha1), path, 0);
|
||||||
|
|
||||||
if (o && o->type == commit_type)
|
if (o && o->type == TYPE_COMMIT)
|
||||||
rev_list_push((struct commit *)o, SEEN);
|
rev_list_push((struct commit *)o, SEEN);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -251,14 +251,14 @@ static int mark_complete(const char *path, const unsigned char *sha1)
|
|||||||
{
|
{
|
||||||
struct object *o = parse_object(sha1);
|
struct object *o = parse_object(sha1);
|
||||||
|
|
||||||
while (o && o->type == tag_type) {
|
while (o && o->type == TYPE_TAG) {
|
||||||
struct tag *t = (struct tag *) o;
|
struct tag *t = (struct tag *) o;
|
||||||
if (!t->tagged)
|
if (!t->tagged)
|
||||||
break; /* broken repository */
|
break; /* broken repository */
|
||||||
o->flags |= COMPLETE;
|
o->flags |= COMPLETE;
|
||||||
o = parse_object(t->tagged->sha1);
|
o = parse_object(t->tagged->sha1);
|
||||||
}
|
}
|
||||||
if (o && o->type == commit_type) {
|
if (o && o->type == TYPE_COMMIT) {
|
||||||
struct commit *commit = (struct commit *)o;
|
struct commit *commit = (struct commit *)o;
|
||||||
commit->object.flags |= COMPLETE;
|
commit->object.flags |= COMPLETE;
|
||||||
insert_by_date(commit, &complete);
|
insert_by_date(commit, &complete);
|
||||||
@ -352,7 +352,7 @@ static int everything_local(struct ref **refs, int nr_match, char **match)
|
|||||||
* in sync with the other side at some time after
|
* in sync with the other side at some time after
|
||||||
* that (it is OK if we guess wrong here).
|
* that (it is OK if we guess wrong here).
|
||||||
*/
|
*/
|
||||||
if (o->type == commit_type) {
|
if (o->type == TYPE_COMMIT) {
|
||||||
struct commit *commit = (struct commit *)o;
|
struct commit *commit = (struct commit *)o;
|
||||||
if (!cutoff || cutoff < commit->date)
|
if (!cutoff || cutoff < commit->date)
|
||||||
cutoff = commit->date;
|
cutoff = commit->date;
|
||||||
@ -371,7 +371,7 @@ static int everything_local(struct ref **refs, int nr_match, char **match)
|
|||||||
struct object *o = deref_tag(lookup_object(ref->old_sha1),
|
struct object *o = deref_tag(lookup_object(ref->old_sha1),
|
||||||
NULL, 0);
|
NULL, 0);
|
||||||
|
|
||||||
if (!o || o->type != commit_type || !(o->flags & COMPLETE))
|
if (!o || o->type != TYPE_COMMIT || !(o->flags & COMPLETE))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!(o->flags & SEEN)) {
|
if (!(o->flags & SEEN)) {
|
||||||
|
14
fetch.c
14
fetch.c
@ -118,27 +118,27 @@ static struct object_list **process_queue_end = &process_queue;
|
|||||||
|
|
||||||
static int process_object(struct object *obj)
|
static int process_object(struct object *obj)
|
||||||
{
|
{
|
||||||
if (obj->type == commit_type) {
|
if (obj->type == TYPE_COMMIT) {
|
||||||
if (process_commit((struct commit *)obj))
|
if (process_commit((struct commit *)obj))
|
||||||
return -1;
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (obj->type == tree_type) {
|
if (obj->type == TYPE_TREE) {
|
||||||
if (process_tree((struct tree *)obj))
|
if (process_tree((struct tree *)obj))
|
||||||
return -1;
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (obj->type == blob_type) {
|
if (obj->type == TYPE_BLOB) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (obj->type == tag_type) {
|
if (obj->type == TYPE_TAG) {
|
||||||
if (process_tag((struct tag *)obj))
|
if (process_tag((struct tag *)obj))
|
||||||
return -1;
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return error("Unable to determine requirements "
|
return error("Unable to determine requirements "
|
||||||
"of type %s for %s",
|
"of type %s for %s",
|
||||||
obj->type, sha1_to_hex(obj->sha1));
|
typename(obj->type), sha1_to_hex(obj->sha1));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int process(struct object *obj)
|
static int process(struct object *obj)
|
||||||
@ -179,9 +179,7 @@ static int loop(void)
|
|||||||
*/
|
*/
|
||||||
if (! (obj->flags & TO_SCAN)) {
|
if (! (obj->flags & TO_SCAN)) {
|
||||||
if (fetch(obj->sha1)) {
|
if (fetch(obj->sha1)) {
|
||||||
report_missing(obj->type
|
report_missing(typename(obj->type), obj->sha1);
|
||||||
? obj->type
|
|
||||||
: "object", obj->sha1);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ static void objreport(struct object *obj, const char *severity,
|
|||||||
const char *err, va_list params)
|
const char *err, va_list params)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s in %s %s: ",
|
fprintf(stderr, "%s in %s %s: ",
|
||||||
severity, obj->type, sha1_to_hex(obj->sha1));
|
severity, typename(obj->type), sha1_to_hex(obj->sha1));
|
||||||
vfprintf(stderr, err, params);
|
vfprintf(stderr, err, params);
|
||||||
fputs("\n", stderr);
|
fputs("\n", stderr);
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ static void check_connectivity(void)
|
|||||||
; /* it is in pack */
|
; /* it is in pack */
|
||||||
else
|
else
|
||||||
printf("missing %s %s\n",
|
printf("missing %s %s\n",
|
||||||
obj->type, sha1_to_hex(obj->sha1));
|
typename(obj->type), sha1_to_hex(obj->sha1));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,20 +87,20 @@ static void check_connectivity(void)
|
|||||||
(has_sha1_file(ref->sha1)))
|
(has_sha1_file(ref->sha1)))
|
||||||
continue;
|
continue;
|
||||||
printf("broken link from %7s %s\n",
|
printf("broken link from %7s %s\n",
|
||||||
obj->type, sha1_to_hex(obj->sha1));
|
typename(obj->type), sha1_to_hex(obj->sha1));
|
||||||
printf(" to %7s %s\n",
|
printf(" to %7s %s\n",
|
||||||
ref->type, sha1_to_hex(ref->sha1));
|
typename(ref->type), sha1_to_hex(ref->sha1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show_unreachable && !(obj->flags & REACHABLE)) {
|
if (show_unreachable && !(obj->flags & REACHABLE)) {
|
||||||
printf("unreachable %s %s\n",
|
printf("unreachable %s %s\n",
|
||||||
obj->type, sha1_to_hex(obj->sha1));
|
typename(obj->type), sha1_to_hex(obj->sha1));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!obj->used) {
|
if (!obj->used) {
|
||||||
printf("dangling %s %s\n", obj->type,
|
printf("dangling %s %s\n", typename(obj->type),
|
||||||
sha1_to_hex(obj->sha1));
|
sha1_to_hex(obj->sha1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -282,7 +282,7 @@ static int fsck_tag(struct tag *tag)
|
|||||||
if (!show_tags)
|
if (!show_tags)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
printf("tagged %s %s", tagged->type, sha1_to_hex(tagged->sha1));
|
printf("tagged %s %s", typename(tagged->type), sha1_to_hex(tagged->sha1));
|
||||||
printf(" (%s) in %s\n", tag->tag, sha1_to_hex(tag->object.sha1));
|
printf(" (%s) in %s\n", tag->tag, sha1_to_hex(tag->object.sha1));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -295,16 +295,16 @@ static int fsck_sha1(unsigned char *sha1)
|
|||||||
if (obj->flags & SEEN)
|
if (obj->flags & SEEN)
|
||||||
return 0;
|
return 0;
|
||||||
obj->flags |= SEEN;
|
obj->flags |= SEEN;
|
||||||
if (obj->type == blob_type)
|
if (obj->type == TYPE_BLOB)
|
||||||
return 0;
|
return 0;
|
||||||
if (obj->type == tree_type)
|
if (obj->type == TYPE_TREE)
|
||||||
return fsck_tree((struct tree *) obj);
|
return fsck_tree((struct tree *) obj);
|
||||||
if (obj->type == commit_type)
|
if (obj->type == TYPE_COMMIT)
|
||||||
return fsck_commit((struct commit *) obj);
|
return fsck_commit((struct commit *) obj);
|
||||||
if (obj->type == tag_type)
|
if (obj->type == TYPE_TAG)
|
||||||
return fsck_tag((struct tag *) obj);
|
return fsck_tag((struct tag *) obj);
|
||||||
/* By now, parse_object() would've returned NULL instead. */
|
/* By now, parse_object() would've returned NULL instead. */
|
||||||
return objerror(obj, "unknown type '%s' (internal fsck error)", obj->type);
|
return objerror(obj, "unknown type '%d' (internal fsck error)", obj->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -470,7 +470,7 @@ static int fsck_cache_tree(struct cache_tree *it)
|
|||||||
}
|
}
|
||||||
mark_reachable(obj, REACHABLE);
|
mark_reachable(obj, REACHABLE);
|
||||||
obj->used = 1;
|
obj->used = 1;
|
||||||
if (obj->type != tree_type)
|
if (obj->type != TYPE_TREE)
|
||||||
err |= objerror(obj, "non-tree in cache-tree");
|
err |= objerror(obj, "non-tree in cache-tree");
|
||||||
}
|
}
|
||||||
for (i = 0; i < it->subtree_nr; i++)
|
for (i = 0; i < it->subtree_nr; i++)
|
||||||
|
12
http-push.c
12
http-push.c
@ -1773,16 +1773,16 @@ static int get_delta(struct rev_info *revs, struct remote_lock *lock)
|
|||||||
|
|
||||||
if (obj->flags & (UNINTERESTING | SEEN))
|
if (obj->flags & (UNINTERESTING | SEEN))
|
||||||
continue;
|
continue;
|
||||||
if (obj->type == tag_type) {
|
if (obj->type == TYPE_TAG) {
|
||||||
obj->flags |= SEEN;
|
obj->flags |= SEEN;
|
||||||
p = add_object(obj, p, NULL, name);
|
p = add_object(obj, p, NULL, name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (obj->type == tree_type) {
|
if (obj->type == TYPE_TREE) {
|
||||||
p = process_tree((struct tree *)obj, p, NULL, name);
|
p = process_tree((struct tree *)obj, p, NULL, name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (obj->type == blob_type) {
|
if (obj->type == TYPE_BLOB) {
|
||||||
p = process_blob((struct blob *)obj, p, NULL, name);
|
p = process_blob((struct blob *)obj, p, NULL, name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1949,12 +1949,12 @@ static int ref_newer(const unsigned char *new_sha1,
|
|||||||
* old. Otherwise we require --force.
|
* old. Otherwise we require --force.
|
||||||
*/
|
*/
|
||||||
o = deref_tag(parse_object(old_sha1), NULL, 0);
|
o = deref_tag(parse_object(old_sha1), NULL, 0);
|
||||||
if (!o || o->type != commit_type)
|
if (!o || o->type != TYPE_COMMIT)
|
||||||
return 0;
|
return 0;
|
||||||
old = (struct commit *) o;
|
old = (struct commit *) o;
|
||||||
|
|
||||||
o = deref_tag(parse_object(new_sha1), NULL, 0);
|
o = deref_tag(parse_object(new_sha1), NULL, 0);
|
||||||
if (!o || o->type != commit_type)
|
if (!o || o->type != TYPE_COMMIT)
|
||||||
return 0;
|
return 0;
|
||||||
new = (struct commit *) o;
|
new = (struct commit *) o;
|
||||||
|
|
||||||
@ -2033,7 +2033,7 @@ static void add_remote_info_ref(struct remote_ls_ctx *ls)
|
|||||||
fwrite_buffer(ref_info, 1, len, buf);
|
fwrite_buffer(ref_info, 1, len, buf);
|
||||||
free(ref_info);
|
free(ref_info);
|
||||||
|
|
||||||
if (o->type == tag_type) {
|
if (o->type == TYPE_TAG) {
|
||||||
o = deref_tag(o, ls->dentry_name, 0);
|
o = deref_tag(o, ls->dentry_name, 0);
|
||||||
if (o) {
|
if (o) {
|
||||||
len = strlen(ls->dentry_name) + 45;
|
len = strlen(ls->dentry_name) + 45;
|
||||||
|
@ -84,14 +84,14 @@ static int name_ref(const char *path, const unsigned char *sha1)
|
|||||||
if (tags_only && strncmp(path, "refs/tags/", 10))
|
if (tags_only && strncmp(path, "refs/tags/", 10))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
while (o && o->type == tag_type) {
|
while (o && o->type == TYPE_TAG) {
|
||||||
struct tag *t = (struct tag *) o;
|
struct tag *t = (struct tag *) o;
|
||||||
if (!t->tagged)
|
if (!t->tagged)
|
||||||
break; /* broken repository */
|
break; /* broken repository */
|
||||||
o = parse_object(t->tagged->sha1);
|
o = parse_object(t->tagged->sha1);
|
||||||
deref = 1;
|
deref = 1;
|
||||||
}
|
}
|
||||||
if (o && o->type == commit_type) {
|
if (o && o->type == TYPE_COMMIT) {
|
||||||
struct commit *commit = (struct commit *)o;
|
struct commit *commit = (struct commit *)o;
|
||||||
|
|
||||||
if (!strncmp(path, "refs/heads/", 11))
|
if (!strncmp(path, "refs/heads/", 11))
|
||||||
@ -167,7 +167,7 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
o = deref_tag(parse_object(sha1), *argv, 0);
|
o = deref_tag(parse_object(sha1), *argv, 0);
|
||||||
if (!o || o->type != commit_type) {
|
if (!o || o->type != TYPE_COMMIT) {
|
||||||
fprintf(stderr, "Could not get commit for %s. Skipping.\n",
|
fprintf(stderr, "Could not get commit for %s. Skipping.\n",
|
||||||
*argv);
|
*argv);
|
||||||
continue;
|
continue;
|
||||||
|
8
object.c
8
object.c
@ -9,6 +9,10 @@ struct object **objs;
|
|||||||
static int nr_objs;
|
static int nr_objs;
|
||||||
int obj_allocs;
|
int obj_allocs;
|
||||||
|
|
||||||
|
const char *type_names[] = {
|
||||||
|
"none", "blob", "tree", "commit", "bad"
|
||||||
|
};
|
||||||
|
|
||||||
int track_object_refs = 0;
|
int track_object_refs = 0;
|
||||||
|
|
||||||
static int hashtable_index(const unsigned char *sha1)
|
static int hashtable_index(const unsigned char *sha1)
|
||||||
@ -50,7 +54,7 @@ void created_object(const unsigned char *sha1, struct object *obj)
|
|||||||
|
|
||||||
obj->parsed = 0;
|
obj->parsed = 0;
|
||||||
memcpy(obj->sha1, sha1, 20);
|
memcpy(obj->sha1, sha1, 20);
|
||||||
obj->type = NULL;
|
obj->type = TYPE_NONE;
|
||||||
obj->refs = NULL;
|
obj->refs = NULL;
|
||||||
obj->used = 0;
|
obj->used = 0;
|
||||||
|
|
||||||
@ -179,7 +183,7 @@ struct object *lookup_unknown_object(const unsigned char *sha1)
|
|||||||
if (!obj) {
|
if (!obj) {
|
||||||
union any_object *ret = xcalloc(1, sizeof(*ret));
|
union any_object *ret = xcalloc(1, sizeof(*ret));
|
||||||
created_object(sha1, &ret->object);
|
created_object(sha1, &ret->object);
|
||||||
ret->object.type = NULL;
|
ret->object.type = TYPE_NONE;
|
||||||
return &ret->object;
|
return &ret->object;
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
|
20
object.h
20
object.h
@ -12,12 +12,22 @@ struct object_refs {
|
|||||||
struct object *ref[FLEX_ARRAY]; /* more */
|
struct object *ref[FLEX_ARRAY]; /* more */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define TYPE_BITS 3
|
||||||
|
#define FLAG_BITS 27
|
||||||
|
|
||||||
|
#define TYPE_NONE 0
|
||||||
|
#define TYPE_BLOB 1
|
||||||
|
#define TYPE_TREE 2
|
||||||
|
#define TYPE_COMMIT 3
|
||||||
|
#define TYPE_TAG 4
|
||||||
|
#define TYPE_BAD 5
|
||||||
|
|
||||||
struct object {
|
struct object {
|
||||||
unsigned parsed : 1;
|
unsigned parsed : 1;
|
||||||
unsigned used : 1;
|
unsigned used : 1;
|
||||||
unsigned int flags;
|
unsigned type : TYPE_BITS;
|
||||||
|
unsigned flags : FLAG_BITS;
|
||||||
unsigned char sha1[20];
|
unsigned char sha1[20];
|
||||||
const char *type;
|
|
||||||
struct object_refs *refs;
|
struct object_refs *refs;
|
||||||
void *util;
|
void *util;
|
||||||
};
|
};
|
||||||
@ -25,6 +35,12 @@ struct object {
|
|||||||
extern int track_object_refs;
|
extern int track_object_refs;
|
||||||
extern int obj_allocs;
|
extern int obj_allocs;
|
||||||
extern struct object **objs;
|
extern struct object **objs;
|
||||||
|
extern const char *type_names[];
|
||||||
|
|
||||||
|
static inline const char *typename(unsigned int type)
|
||||||
|
{
|
||||||
|
return type_names[type > TYPE_TAG ? TYPE_BAD : type];
|
||||||
|
}
|
||||||
|
|
||||||
/** Internal only **/
|
/** Internal only **/
|
||||||
struct object *lookup_object(const unsigned char *sha1);
|
struct object *lookup_object(const unsigned char *sha1);
|
||||||
|
12
revision.c
12
revision.c
@ -140,7 +140,7 @@ static struct commit *handle_commit(struct rev_info *revs, struct object *object
|
|||||||
/*
|
/*
|
||||||
* Tag object? Look what it points to..
|
* Tag object? Look what it points to..
|
||||||
*/
|
*/
|
||||||
while (object->type == tag_type) {
|
while (object->type == TYPE_TAG) {
|
||||||
struct tag *tag = (struct tag *) object;
|
struct tag *tag = (struct tag *) object;
|
||||||
if (revs->tag_objects && !(flags & UNINTERESTING))
|
if (revs->tag_objects && !(flags & UNINTERESTING))
|
||||||
add_pending_object(revs, object, tag->tag);
|
add_pending_object(revs, object, tag->tag);
|
||||||
@ -153,7 +153,7 @@ static struct commit *handle_commit(struct rev_info *revs, struct object *object
|
|||||||
* Commit object? Just return it, we'll do all the complex
|
* Commit object? Just return it, we'll do all the complex
|
||||||
* reachability crud.
|
* reachability crud.
|
||||||
*/
|
*/
|
||||||
if (object->type == commit_type) {
|
if (object->type == TYPE_COMMIT) {
|
||||||
struct commit *commit = (struct commit *)object;
|
struct commit *commit = (struct commit *)object;
|
||||||
if (parse_commit(commit) < 0)
|
if (parse_commit(commit) < 0)
|
||||||
die("unable to parse commit %s", name);
|
die("unable to parse commit %s", name);
|
||||||
@ -169,7 +169,7 @@ static struct commit *handle_commit(struct rev_info *revs, struct object *object
|
|||||||
* Tree object? Either mark it uniniteresting, or add it
|
* Tree object? Either mark it uniniteresting, or add it
|
||||||
* to the list of objects to look at later..
|
* to the list of objects to look at later..
|
||||||
*/
|
*/
|
||||||
if (object->type == tree_type) {
|
if (object->type == TYPE_TREE) {
|
||||||
struct tree *tree = (struct tree *)object;
|
struct tree *tree = (struct tree *)object;
|
||||||
if (!revs->tree_objects)
|
if (!revs->tree_objects)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -184,7 +184,7 @@ static struct commit *handle_commit(struct rev_info *revs, struct object *object
|
|||||||
/*
|
/*
|
||||||
* Blob object? You know the drill by now..
|
* Blob object? You know the drill by now..
|
||||||
*/
|
*/
|
||||||
if (object->type == blob_type) {
|
if (object->type == TYPE_BLOB) {
|
||||||
struct blob *blob = (struct blob *)object;
|
struct blob *blob = (struct blob *)object;
|
||||||
if (!revs->blob_objects)
|
if (!revs->blob_objects)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -498,11 +498,11 @@ static int add_parents_only(struct rev_info *revs, const char *arg, int flags)
|
|||||||
return 0;
|
return 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
it = get_reference(revs, arg, sha1, 0);
|
it = get_reference(revs, arg, sha1, 0);
|
||||||
if (strcmp(it->type, tag_type))
|
if (it->type != TYPE_TAG)
|
||||||
break;
|
break;
|
||||||
memcpy(sha1, ((struct tag*)it)->tagged->sha1, 20);
|
memcpy(sha1, ((struct tag*)it)->tagged->sha1, 20);
|
||||||
}
|
}
|
||||||
if (strcmp(it->type, commit_type))
|
if (it->type != TYPE_COMMIT)
|
||||||
return 0;
|
return 0;
|
||||||
commit = (struct commit *)it;
|
commit = (struct commit *)it;
|
||||||
for (parents = commit->parents; parents; parents = parents->next) {
|
for (parents = commit->parents; parents; parents = parents->next) {
|
||||||
|
@ -151,12 +151,12 @@ static int ref_newer(const unsigned char *new_sha1,
|
|||||||
* old. Otherwise we require --force.
|
* old. Otherwise we require --force.
|
||||||
*/
|
*/
|
||||||
o = deref_tag(parse_object(old_sha1), NULL, 0);
|
o = deref_tag(parse_object(old_sha1), NULL, 0);
|
||||||
if (!o || o->type != commit_type)
|
if (!o || o->type != TYPE_COMMIT)
|
||||||
return 0;
|
return 0;
|
||||||
old = (struct commit *) o;
|
old = (struct commit *) o;
|
||||||
|
|
||||||
o = deref_tag(parse_object(new_sha1), NULL, 0);
|
o = deref_tag(parse_object(new_sha1), NULL, 0);
|
||||||
if (!o || o->type != commit_type)
|
if (!o || o->type != TYPE_COMMIT)
|
||||||
return 0;
|
return 0;
|
||||||
new = (struct commit *) o;
|
new = (struct commit *) o;
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ static int add_info_ref(const char *path, const unsigned char *sha1)
|
|||||||
struct object *o = parse_object(sha1);
|
struct object *o = parse_object(sha1);
|
||||||
|
|
||||||
fprintf(info_ref_fp, "%s %s\n", sha1_to_hex(sha1), path);
|
fprintf(info_ref_fp, "%s %s\n", sha1_to_hex(sha1), path);
|
||||||
if (o->type == tag_type) {
|
if (o->type == TYPE_TAG) {
|
||||||
o = deref_tag(o, path, 0);
|
o = deref_tag(o, path, 0);
|
||||||
if (o)
|
if (o)
|
||||||
fprintf(info_ref_fp, "%s %s^{}\n",
|
fprintf(info_ref_fp, "%s %s^{}\n",
|
||||||
|
22
sha1_name.c
22
sha1_name.c
@ -357,7 +357,7 @@ static int peel_onion(const char *name, int len, unsigned char *sha1)
|
|||||||
{
|
{
|
||||||
unsigned char outer[20];
|
unsigned char outer[20];
|
||||||
const char *sp;
|
const char *sp;
|
||||||
const char *type_string = NULL;
|
unsigned int expected_type = 0;
|
||||||
struct object *o;
|
struct object *o;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -381,13 +381,13 @@ static int peel_onion(const char *name, int len, unsigned char *sha1)
|
|||||||
|
|
||||||
sp++; /* beginning of type name, or closing brace for empty */
|
sp++; /* beginning of type name, or closing brace for empty */
|
||||||
if (!strncmp(commit_type, sp, 6) && sp[6] == '}')
|
if (!strncmp(commit_type, sp, 6) && sp[6] == '}')
|
||||||
type_string = commit_type;
|
expected_type = TYPE_COMMIT;
|
||||||
else if (!strncmp(tree_type, sp, 4) && sp[4] == '}')
|
else if (!strncmp(tree_type, sp, 4) && sp[4] == '}')
|
||||||
type_string = tree_type;
|
expected_type = TYPE_TREE;
|
||||||
else if (!strncmp(blob_type, sp, 4) && sp[4] == '}')
|
else if (!strncmp(blob_type, sp, 4) && sp[4] == '}')
|
||||||
type_string = blob_type;
|
expected_type = TYPE_BLOB;
|
||||||
else if (sp[0] == '}')
|
else if (sp[0] == '}')
|
||||||
type_string = NULL;
|
expected_type = TYPE_NONE;
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -397,7 +397,7 @@ static int peel_onion(const char *name, int len, unsigned char *sha1)
|
|||||||
o = parse_object(outer);
|
o = parse_object(outer);
|
||||||
if (!o)
|
if (!o)
|
||||||
return -1;
|
return -1;
|
||||||
if (!type_string) {
|
if (!expected_type) {
|
||||||
o = deref_tag(o, name, sp - name - 2);
|
o = deref_tag(o, name, sp - name - 2);
|
||||||
if (!o || (!o->parsed && !parse_object(o->sha1)))
|
if (!o || (!o->parsed && !parse_object(o->sha1)))
|
||||||
return -1;
|
return -1;
|
||||||
@ -412,18 +412,18 @@ static int peel_onion(const char *name, int len, unsigned char *sha1)
|
|||||||
while (1) {
|
while (1) {
|
||||||
if (!o || (!o->parsed && !parse_object(o->sha1)))
|
if (!o || (!o->parsed && !parse_object(o->sha1)))
|
||||||
return -1;
|
return -1;
|
||||||
if (o->type == type_string) {
|
if (o->type == expected_type) {
|
||||||
memcpy(sha1, o->sha1, 20);
|
memcpy(sha1, o->sha1, 20);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (o->type == tag_type)
|
if (o->type == TYPE_TAG)
|
||||||
o = ((struct tag*) o)->tagged;
|
o = ((struct tag*) o)->tagged;
|
||||||
else if (o->type == commit_type)
|
else if (o->type == TYPE_COMMIT)
|
||||||
o = &(((struct commit *) o)->tree->object);
|
o = &(((struct commit *) o)->tree->object);
|
||||||
else
|
else
|
||||||
return error("%.*s: expected %s type, but the object dereferences to %s type",
|
return error("%.*s: expected %s type, but the object dereferences to %s type",
|
||||||
len, name, type_string,
|
len, name, typename(expected_type),
|
||||||
o->type);
|
typename(o->type));
|
||||||
if (!o->parsed)
|
if (!o->parsed)
|
||||||
parse_object(o->sha1);
|
parse_object(o->sha1);
|
||||||
}
|
}
|
||||||
|
12
tag.c
12
tag.c
@ -5,7 +5,7 @@ const char *tag_type = "tag";
|
|||||||
|
|
||||||
struct object *deref_tag(struct object *o, const char *warn, int warnlen)
|
struct object *deref_tag(struct object *o, const char *warn, int warnlen)
|
||||||
{
|
{
|
||||||
while (o && o->type == tag_type)
|
while (o && o->type == TYPE_TAG)
|
||||||
o = parse_object(((struct tag *)o)->tagged->sha1);
|
o = parse_object(((struct tag *)o)->tagged->sha1);
|
||||||
if (!o && warn) {
|
if (!o && warn) {
|
||||||
if (!warnlen)
|
if (!warnlen)
|
||||||
@ -21,14 +21,14 @@ struct tag *lookup_tag(const unsigned char *sha1)
|
|||||||
if (!obj) {
|
if (!obj) {
|
||||||
struct tag *ret = xcalloc(1, sizeof(struct tag));
|
struct tag *ret = xcalloc(1, sizeof(struct tag));
|
||||||
created_object(sha1, &ret->object);
|
created_object(sha1, &ret->object);
|
||||||
ret->object.type = tag_type;
|
ret->object.type = TYPE_TAG;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (!obj->type)
|
if (!obj->type)
|
||||||
obj->type = tag_type;
|
obj->type = TYPE_TAG;
|
||||||
if (obj->type != tag_type) {
|
if (obj->type != TYPE_TAG) {
|
||||||
error("Object %s is a %s, not a tree",
|
error("Object %s is a %s, not a tree",
|
||||||
sha1_to_hex(sha1), obj->type);
|
sha1_to_hex(sha1), typename(obj->type));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return (struct tag *) obj;
|
return (struct tag *) obj;
|
||||||
|
16
tree.c
16
tree.c
@ -131,14 +131,14 @@ struct tree *lookup_tree(const unsigned char *sha1)
|
|||||||
if (!obj) {
|
if (!obj) {
|
||||||
struct tree *ret = xcalloc(1, sizeof(struct tree));
|
struct tree *ret = xcalloc(1, sizeof(struct tree));
|
||||||
created_object(sha1, &ret->object);
|
created_object(sha1, &ret->object);
|
||||||
ret->object.type = tree_type;
|
ret->object.type = TYPE_TREE;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (!obj->type)
|
if (!obj->type)
|
||||||
obj->type = tree_type;
|
obj->type = TYPE_TREE;
|
||||||
if (obj->type != tree_type) {
|
if (obj->type != TYPE_TREE) {
|
||||||
error("Object %s is a %s, not a tree",
|
error("Object %s is a %s, not a tree",
|
||||||
sha1_to_hex(sha1), obj->type);
|
sha1_to_hex(sha1), typename(obj->type));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return (struct tree *) obj;
|
return (struct tree *) obj;
|
||||||
@ -216,11 +216,11 @@ struct tree *parse_tree_indirect(const unsigned char *sha1)
|
|||||||
do {
|
do {
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (obj->type == tree_type)
|
if (obj->type == TYPE_TREE)
|
||||||
return (struct tree *) obj;
|
return (struct tree *) obj;
|
||||||
else if (obj->type == commit_type)
|
else if (obj->type == TYPE_COMMIT)
|
||||||
obj = &(((struct commit *) obj)->tree->object);
|
obj = &(((struct commit *) obj)->tree->object);
|
||||||
else if (obj->type == tag_type)
|
else if (obj->type == TYPE_TAG)
|
||||||
obj = ((struct tag *) obj)->tagged;
|
obj = ((struct tag *) obj)->tagged;
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -105,7 +105,7 @@ static int got_sha1(char *hex, unsigned char *sha1)
|
|||||||
o = parse_object(sha1);
|
o = parse_object(sha1);
|
||||||
if (!o)
|
if (!o)
|
||||||
die("oops (%s)", sha1_to_hex(sha1));
|
die("oops (%s)", sha1_to_hex(sha1));
|
||||||
if (o->type == commit_type) {
|
if (o->type == TYPE_COMMIT) {
|
||||||
struct commit_list *parents;
|
struct commit_list *parents;
|
||||||
if (o->flags & THEY_HAVE)
|
if (o->flags & THEY_HAVE)
|
||||||
return 0;
|
return 0;
|
||||||
@ -234,7 +234,7 @@ static int send_ref(const char *refname, const unsigned char *sha1)
|
|||||||
o->flags |= OUR_REF;
|
o->flags |= OUR_REF;
|
||||||
nr_our_refs++;
|
nr_our_refs++;
|
||||||
}
|
}
|
||||||
if (o->type == tag_type) {
|
if (o->type == TYPE_TAG) {
|
||||||
o = deref_tag(o, refname, 0);
|
o = deref_tag(o, refname, 0);
|
||||||
packet_write(1, "%s %s^{}\n", sha1_to_hex(o->sha1), refname);
|
packet_write(1, "%s %s^{}\n", sha1_to_hex(o->sha1), refname);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user