Merge branch 'eb/mail' into next
authorJunio C Hamano <junkio@cox.net>
Sun, 18 Jun 2006 01:56:08 +0000 (18:56 -0700)
committerJunio C Hamano <junkio@cox.net>
Sun, 18 Jun 2006 01:56:08 +0000 (18:56 -0700)
* eb/mail:
Fix git-format-patch -s
Some more memory leak avoidance
Move "void *util" from "struct object" into "struct commit"
Shrink "struct object" a bit

24 files changed:
blame.c
blob.c
builtin-diff.c
builtin-grep.c
builtin-log.c
builtin-rev-list.c
builtin-show-branch.c
commit.c
commit.h
describe.c
fetch-pack.c
fetch.c
fsck-objects.c
http-push.c
name-rev.c
object.c
object.h
revision.c
send-pack.c
server-info.c
sha1_name.c
tag.c
tree.c
upload-pack.c
diff --git a/blame.c b/blame.c
index 25d3bcf647f44bbaed1c273d5886df6a7cfe6e03..7c0b62cf3f5ff78f95cf96c2582f693b5d124752 100644 (file)
--- a/blame.c
+++ b/blame.c
@@ -110,8 +110,8 @@ static struct patch *get_patch(struct commit *commit, struct commit *other)
        xdemitconf_t xecfg;
        mmfile_t file_c, file_o;
        xdemitcb_t ecb;
-       struct util_info *info_c = (struct util_info *)commit->object.util;
-       struct util_info *info_o = (struct util_info *)other->object.util;
+       struct util_info *info_c = (struct util_info *)commit->util;
+       struct util_info *info_o = (struct util_info *)other->util;
        struct timeval tv_start, tv_end;
 
        get_blob(commit);
@@ -197,7 +197,7 @@ static int get_blob_sha1_internal(const unsigned char *sha1, const char *base,
 
 static void get_blob(struct commit *commit)
 {
-       struct util_info *info = commit->object.util;
+       struct util_info *info = commit->util;
        char type[20];
 
        if (info->buf)
@@ -223,8 +223,8 @@ static void print_patch(struct patch *p)
 /* For debugging only */
 static void print_map(struct commit *cmit, struct commit *other)
 {
-       struct util_info *util = cmit->object.util;
-       struct util_info *util2 = other->object.util;
+       struct util_info *util = cmit->util;
+       struct util_info *util2 = other->util;
 
        int i;
        int max =
@@ -259,8 +259,8 @@ static void print_map(struct commit *cmit, struct commit *other)
 static void fill_line_map(struct commit *commit, struct commit *other,
                          struct patch *p)
 {
-       struct util_info *util = commit->object.util;
-       struct util_info *util2 = other->object.util;
+       struct util_info *util = commit->util;
+       struct util_info *util2 = other->util;
        int *map = util->line_map;
        int *map2 = util2->line_map;
        int cur_chunk = 0;
@@ -322,14 +322,14 @@ static void fill_line_map(struct commit *commit, struct commit *other,
 
 static int map_line(struct commit *commit, int line)
 {
-       struct util_info *info = commit->object.util;
+       struct util_info *info = commit->util;
        assert(line >= 0 && line < info->num_lines);
        return info->line_map[line];
 }
 
 static struct util_info* get_util(struct commit *commit)
 {
-       struct util_info *util = commit->object.util;
+       struct util_info *util = commit->util;
 
        if (util)
                return util;
@@ -340,13 +340,13 @@ static struct util_info* get_util(struct commit *commit)
        util->line_map = NULL;
        util->num_lines = -1;
        util->pathname = NULL;
-       commit->object.util = util;
+       commit->util = util;
        return util;
 }
 
 static int fill_util_info(struct commit *commit)
 {
-       struct util_info *util = commit->object.util;
+       struct util_info *util = commit->util;
 
        assert(util);
        assert(util->pathname);
@@ -359,7 +359,7 @@ static int fill_util_info(struct commit *commit)
 
 static void alloc_line_map(struct commit *commit)
 {
-       struct util_info *util = commit->object.util;
+       struct util_info *util = commit->util;
        int i;
 
        if (util->line_map)
@@ -383,7 +383,7 @@ static void alloc_line_map(struct commit *commit)
 
 static void init_first_commit(struct commit* commit, const char* filename)
 {
-       struct util_info* util = commit->object.util;
+       struct util_info* util = commit->util;
        int i;
 
        util->pathname = filename;
@@ -392,7 +392,7 @@ static void init_first_commit(struct commit* commit, const char* filename)
 
        alloc_line_map(commit);
 
-       util = commit->object.util;
+       util = commit->util;
 
        for (i = 0; i < util->num_lines; i++)
                util->line_map[i] = i;
@@ -413,7 +413,7 @@ static void process_commits(struct rev_info *rev, const char *path,
        assert(commit);
        init_first_commit(commit, path);
 
-       util = commit->object.util;
+       util = commit->util;
        num_blame_lines = util->num_lines;
        blame_lines = xmalloc(sizeof(struct commit *) * num_blame_lines);
        blame_contents = util->buf;
@@ -452,7 +452,7 @@ static void process_commits(struct rev_info *rev, const char *path,
                        continue;
 
                alloc_line_map(commit);
-               util = commit->object.util;
+               util = commit->util;
 
                for (parents = commit->parents;
                     parents != NULL; parents = parents->next) {
@@ -512,7 +512,7 @@ static int compare_tree_path(struct rev_info* revs,
 {
        int ret;
        const char* paths[2];
-       struct util_info* util = c2->object.util;
+       struct util_info* util = c2->util;
        paths[0] = util->pathname;
        paths[1] = NULL;
 
@@ -541,7 +541,7 @@ static int same_tree_as_empty_path(struct rev_info *revs, struct tree* t1,
 
 static const char* find_rename(struct commit* commit, struct commit* parent)
 {
-       struct util_info* cutil = commit->object.util;
+       struct util_info* cutil = commit->util;
        struct diff_options diff_opts;
        const char *paths[1];
        int i;
@@ -585,7 +585,7 @@ static void simplify_commit(struct rev_info *revs, struct commit *commit)
                return;
 
        if (!commit->parents) {
-               struct util_info* util = commit->object.util;
+               struct util_info* util = commit->util;
                if (!same_tree_as_empty_path(revs, commit->tree,
                                             util->pathname))
                        commit->object.flags |= TREECHANGE;
@@ -612,7 +612,7 @@ static void simplify_commit(struct rev_info *revs, struct commit *commit)
                case REV_TREE_NEW:
                {
 
-                       struct util_info* util = commit->object.util;
+                       struct util_info* util = commit->util;
                        if (revs->remove_empty_trees &&
                            same_tree_as_empty_path(revs, p->tree,
                                                    util->pathname)) {
@@ -709,13 +709,13 @@ static const char* format_time(unsigned long time, const char* tz_str,
 
 static void topo_setter(struct commit* c, void* data)
 {
-       struct util_info* util = c->object.util;
+       struct util_info* util = c->util;
        util->topo_data = data;
 }
 
 static void* topo_getter(struct commit* c)
 {
-       struct util_info* util = c->object.util;
+       struct util_info* util = c->util;
        return util->topo_data;
 }
 
@@ -863,7 +863,7 @@ int main(int argc, const char **argv)
                struct util_info* u;
                if (!c)
                        c = initial;
-               u = c->object.util;
+               u = c->util;
 
                if (!found_rename && strcmp(filename, u->pathname))
                        found_rename = 1;
@@ -881,7 +881,7 @@ int main(int argc, const char **argv)
                if (!c)
                        c = initial;
 
-               u = c->object.util;
+               u = c->util;
                get_commit_info(c, &ci);
                fwrite(sha1_to_hex(c->object.sha1), sha1_len, 1, stdout);
                if(compability) {
diff --git a/blob.c b/blob.c
index c1fdd861c3dedbbd670fcf07989501fd0f9b5fda..7377008744430cea453010fe93e6c1f51c37fdde 100644 (file)
--- a/blob.c
+++ b/blob.c
@@ -10,14 +10,14 @@ struct blob *lookup_blob(const unsigned char *sha1)
        if (!obj) {
                struct blob *ret = xcalloc(1, sizeof(struct blob));
                created_object(sha1, &ret->object);
-               ret->object.type = blob_type;
+               ret->object.type = TYPE_BLOB;
                return ret;
        }
        if (!obj->type)
-               obj->type = blob_type;
-       if (obj->type != blob_type) {
-               error("Object %s is a %s, not a blob", 
-                     sha1_to_hex(sha1), obj->type);
+               obj->type = TYPE_BLOB;
+       if (obj->type != TYPE_BLOB) {
+               error("Object %s is a %s, not a blob",
+                     sha1_to_hex(sha1), typename(obj->type));
                return NULL;
        }
        return (struct blob *) obj;
index 27451d56134e08364c33c26d5074693dd4437d31..6ac3d4b8ca23e7c4d724b22fd3222005d8fe3df8 100644 (file)
@@ -303,9 +303,9 @@ int cmd_diff(int argc, const char **argv, char **envp)
                obj = deref_tag(obj, NULL, 0);
                if (!obj)
                        die("invalid object '%s' given.", name);
-               if (!strcmp(obj->type, commit_type))
+               if (obj->type == TYPE_COMMIT)
                        obj = &((struct commit *)obj)->tree->object;
-               if (!strcmp(obj->type, tree_type)) {
+               if (obj->type == TYPE_TREE) {
                        if (ARRAY_SIZE(ent) <= ents)
                                die("more than %d trees given: '%s'",
                                    (int) ARRAY_SIZE(ent), name);
@@ -315,7 +315,7 @@ int cmd_diff(int argc, const char **argv, char **envp)
                        ents++;
                        continue;
                }
-               if (!strcmp(obj->type, blob_type)) {
+               if (obj->type == TYPE_BLOB) {
                        if (2 <= blobs)
                                die("more than two blobs given: '%s'", name);
                        memcpy(blob[blobs].sha1, obj->sha1, 20);
index 5fac5701e6ccebdbe83b00d2e2df19343d3aea0e..9806499263dcb92c7a6903ead36646baf676b178 100644 (file)
@@ -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,
                       struct object *obj, const char *name)
 {
-       if (!strcmp(obj->type, blob_type))
+       if (obj->type == TYPE_BLOB)
                return grep_sha1(opt, obj->sha1, name);
-       if (!strcmp(obj->type, commit_type) ||
-           !strcmp(obj->type, tree_type)) {
+       if (obj->type == TYPE_COMMIT || obj->type == TYPE_TREE) {
                struct tree_desc tree;
                void *data;
                int hit;
@@ -646,7 +645,7 @@ static int grep_object(struct grep_opt *opt, const char **paths,
                free(data);
                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[] =
index f4d974a7b8bfa0472a110273edf62b34b90902fe..9187fd337ba767384abab26224b95610aa531807 100644 (file)
@@ -40,6 +40,8 @@ static int cmd_log_wc(int argc, const char **argv, char **envp,
                log_tree_commit(rev, commit);
                free(commit->buffer);
                commit->buffer = NULL;
+               free_commit_list(commit->parents);
+               commit->parents = NULL;
        }
        return 0;
 }
@@ -218,8 +220,11 @@ int cmd_format_patch(int argc, const char **argv, char **envp)
                }
                else if (!strcmp(argv[i], "--signoff") ||
                         !strcmp(argv[i], "-s")) {
-                       const char *committer = git_committer_info(1);
-                       const char *endpos = strchr(committer, '>');
+                       const char *committer;
+                       const char *endpos;
+                       setup_ident();
+                       committer = git_committer_info(1);
+                       endpos = strchr(committer, '>');
                        if (!endpos)
                                die("bogos committer info %s\n", committer);
                        add_signoff = xmalloc(endpos - committer + 2);
index e885624255ac8e1007df797d339e3e81020f95a2..71353eb19db158a60a5ae94f83f53059adc3399b 100644 (file)
@@ -89,6 +89,14 @@ static void show_commit(struct commit *commit)
                printf("%s%c", pretty_header, hdr_termination);
        }
        fflush(stdout);
+       if (commit->parents) {
+               free_commit_list(commit->parents);
+               commit->parents = NULL;
+       }
+       if (commit->buffer) {
+               free(commit->buffer);
+               commit->buffer = NULL;
+       }
 }
 
 static struct object_list **process_blob(struct blob *blob,
@@ -158,16 +166,16 @@ static void show_commit_list(struct rev_info *revs)
                const char *name = pending->name;
                if (obj->flags & (UNINTERESTING | SEEN))
                        continue;
-               if (obj->type == tag_type) {
+               if (obj->type == TYPE_TAG) {
                        obj->flags |= SEEN;
                        p = add_object(obj, p, NULL, name);
                        continue;
                }
-               if (obj->type == tree_type) {
+               if (obj->type == TYPE_TREE) {
                        p = process_tree((struct tree *)obj, p, NULL, name);
                        continue;
                }
-               if (obj->type == blob_type) {
+               if (obj->type == TYPE_BLOB) {
                        p = process_blob((struct blob *)obj, p, NULL, name);
                        continue;
                }
index 2895140915cb603e2c5f971d0356f2e48106bc0e..09d82278625584213f710a984652a7efc07339c5 100644 (file)
@@ -15,7 +15,7 @@ static const char **default_arg = NULL;
 #define UNINTERESTING  01
 
 #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)
 {
@@ -51,9 +51,9 @@ struct commit_name {
 static void name_commit(struct commit *commit, const char *head_name, int nth)
 {
        struct commit_name *name;
-       if (!commit->object.util)
-               commit->object.util = xmalloc(sizeof(struct commit_name));
-       name = commit->object.util;
+       if (!commit->util)
+               commit->util = xmalloc(sizeof(struct commit_name));
+       name = commit->util;
        name->head_name = head_name;
        name->generation = nth;
 }
@@ -65,8 +65,8 @@ static void name_commit(struct commit *commit, const char *head_name, int nth)
  */
 static void name_parent(struct commit *commit, struct commit *parent)
 {
-       struct commit_name *commit_name = commit->object.util;
-       struct commit_name *parent_name = parent->object.util;
+       struct commit_name *commit_name = commit->util;
+       struct commit_name *parent_name = parent->util;
        if (!commit_name)
                return;
        if (!parent_name ||
@@ -80,12 +80,12 @@ static int name_first_parent_chain(struct commit *c)
        int i = 0;
        while (c) {
                struct commit *p;
-               if (!c->object.util)
+               if (!c->util)
                        break;
                if (!c->parents)
                        break;
                p = c->parents->item;
-               if (!p->object.util) {
+               if (!p->util) {
                        name_parent(c, p);
                        i++;
                }
@@ -106,7 +106,7 @@ static void name_commits(struct commit_list *list,
        /* First give names to the given heads */
        for (cl = list; cl; cl = cl->next) {
                c = cl->item;
-               if (c->object.util)
+               if (c->util)
                        continue;
                for (i = 0; i < num_rev; i++) {
                        if (rev[i] == c) {
@@ -132,9 +132,9 @@ static void name_commits(struct commit_list *list,
                        struct commit_name *n;
                        int nth;
                        c = cl->item;
-                       if (!c->object.util)
+                       if (!c->util)
                                continue;
-                       n = c->object.util;
+                       n = c->util;
                        parents = c->parents;
                        nth = 0;
                        while (parents) {
@@ -142,7 +142,7 @@ static void name_commits(struct commit_list *list,
                                char newname[1000], *en;
                                parents = parents->next;
                                nth++;
-                               if (p->object.util)
+                               if (p->util)
                                        continue;
                                en = newname;
                                switch (n->generation) {
@@ -257,7 +257,7 @@ static void join_revs(struct commit_list **list_p,
 static void show_one_commit(struct commit *commit, int no_name)
 {
        char pretty[256], *cp;
-       struct commit_name *name = commit->object.util;
+       struct commit_name *name = commit->util;
        if (commit->object.parsed)
                pretty_print_commit(CMIT_FMT_ONELINE, commit, ~0,
                                    pretty, sizeof(pretty), 0, NULL, NULL);
index 94f470b75cfc68bfd8e14d1e421e19c5ad6004d6..5914200a2fba2d618951c3210e2b407c29a62d7b 100644 (file)
--- a/commit.c
+++ b/commit.c
@@ -56,10 +56,10 @@ static struct commit *check_commit(struct object *obj,
                                   const unsigned char *sha1,
                                   int quiet)
 {
-       if (obj->type != commit_type) {
+       if (obj->type != TYPE_COMMIT) {
                if (!quiet)
                        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 (struct commit *) obj;
@@ -86,11 +86,11 @@ struct commit *lookup_commit(const unsigned char *sha1)
        if (!obj) {
                struct commit *ret = xcalloc(1, sizeof(struct commit));
                created_object(sha1, &ret->object);
-               ret->object.type = commit_type;
+               ret->object.type = TYPE_COMMIT;
                return ret;
        }
        if (!obj->type)
-               obj->type = commit_type;
+               obj->type = TYPE_COMMIT;
        return check_commit(obj, sha1, 0);
 }
 
@@ -711,12 +711,12 @@ int count_parents(struct commit * commit)
 
 void topo_sort_default_setter(struct commit *c, void *data)
 {
-       c->object.util = data;
+       c->util = data;
 }
 
 void *topo_sort_default_getter(struct commit *c)
 {
-       return c->object.util;
+       return c->util;
 }
 
 /*
index c9de1677e903ead414e5133424b722bea907b4d9..7c9ca3fbed728d946e48c787720b3ab5ad575a85 100644 (file)
--- a/commit.h
+++ b/commit.h
@@ -11,6 +11,7 @@ struct commit_list {
 
 struct commit {
        struct object object;
+       void *util;
        unsigned long date;
        struct commit_list *parents;
        struct tree *tree;
index 8a9cd5d52c555330c512b977179ab030ccd28861..aa3434a4cbfe62563b7621ddd7e72be3adbea1cc 100644 (file)
@@ -67,7 +67,7 @@ static int get_name(const char *path, const unsigned char *sha1)
         * Otherwise only annotated tags are used.
         */
        if (!strncmp(path, "refs/tags/", 10)) {
-               if (object->type == tag_type)
+               if (object->type == TYPE_TAG)
                        prio = 2;
                else
                        prio = 1;
index 83713485562fd340a67e5073b443679d0b2a4c24..7d23a8071a9c2923b1f9bcf1d897e590e04f432b 100644 (file)
@@ -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);
 
-       if (o && o->type == commit_type)
+       if (o && o->type == TYPE_COMMIT)
                rev_list_push((struct commit *)o, SEEN);
 
        return 0;
@@ -251,14 +251,14 @@ static int mark_complete(const char *path, const unsigned char *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;
                if (!t->tagged)
                        break; /* broken repository */
                o->flags |= COMPLETE;
                o = parse_object(t->tagged->sha1);
        }
-       if (o && o->type == commit_type) {
+       if (o && o->type == TYPE_COMMIT) {
                struct commit *commit = (struct commit *)o;
                commit->object.flags |= 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
                 * 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;
                        if (!cutoff || 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),
                                             NULL, 0);
 
-               if (!o || o->type != commit_type || !(o->flags & COMPLETE))
+               if (!o || o->type != TYPE_COMMIT || !(o->flags & COMPLETE))
                        continue;
 
                if (!(o->flags & SEEN)) {
diff --git a/fetch.c b/fetch.c
index cf6c99490c234c5854146f8f6e72d8c615517eea..238032b798008cd1f96d5083b63dc582f8191a1d 100644 (file)
--- a/fetch.c
+++ b/fetch.c
@@ -118,27 +118,27 @@ static struct object_list **process_queue_end = &process_queue;
 
 static int process_object(struct object *obj)
 {
-       if (obj->type == commit_type) {
+       if (obj->type == TYPE_COMMIT) {
                if (process_commit((struct commit *)obj))
                        return -1;
                return 0;
        }
-       if (obj->type == tree_type) {
+       if (obj->type == TYPE_TREE) {
                if (process_tree((struct tree *)obj))
                        return -1;
                return 0;
        }
-       if (obj->type == blob_type) {
+       if (obj->type == TYPE_BLOB) {
                return 0;
        }
-       if (obj->type == tag_type) {
+       if (obj->type == TYPE_TAG) {
                if (process_tag((struct tag *)obj))
                        return -1;
                return 0;
        }
        return error("Unable to determine requirements "
                     "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)
@@ -179,9 +179,7 @@ static int loop(void)
                 */
                if (! (obj->flags & TO_SCAN)) {
                        if (fetch(obj->sha1)) {
-                               report_missing(obj->type
-                                              ? obj->type
-                                              : "object", obj->sha1);
+                               report_missing(typename(obj->type), obj->sha1);
                                return -1;
                        }
                }
index 33ce366e99376619c96ad3b1a1d883a98d55193b..2b1aab488f2b8d64fa799adf427b6eeca35ac757 100644 (file)
@@ -34,7 +34,7 @@ static void objreport(struct object *obj, const char *severity,
                       const char *err, va_list params)
 {
        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);
        fputs("\n", stderr);
 }
@@ -74,7 +74,7 @@ static void check_connectivity(void)
                                ; /* it is in pack */
                        else
                                printf("missing %s %s\n",
-                                      obj->type, sha1_to_hex(obj->sha1));
+                                      typename(obj->type), sha1_to_hex(obj->sha1));
                        continue;
                }
 
@@ -87,20 +87,20 @@ static void check_connectivity(void)
                                    (has_sha1_file(ref->sha1)))
                                        continue;
                                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",
-                                      ref->type, sha1_to_hex(ref->sha1));
+                                      typename(ref->type), sha1_to_hex(ref->sha1));
                        }
                }
 
                if (show_unreachable && !(obj->flags & REACHABLE)) {
                        printf("unreachable %s %s\n",
-                              obj->type, sha1_to_hex(obj->sha1));
+                              typename(obj->type), sha1_to_hex(obj->sha1));
                        continue;
                }
 
                if (!obj->used) {
-                       printf("dangling %s %s\n", obj->type, 
+                       printf("dangling %s %s\n", typename(obj->type),
                               sha1_to_hex(obj->sha1));
                }
        }
@@ -282,7 +282,7 @@ static int fsck_tag(struct tag *tag)
        if (!show_tags)
                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));
        return 0;
 }
@@ -295,16 +295,16 @@ static int fsck_sha1(unsigned char *sha1)
        if (obj->flags & SEEN)
                return 0;
        obj->flags |= SEEN;
-       if (obj->type == blob_type)
+       if (obj->type == TYPE_BLOB)
                return 0;
-       if (obj->type == tree_type)
+       if (obj->type == TYPE_TREE)
                return fsck_tree((struct tree *) obj);
-       if (obj->type == commit_type)
+       if (obj->type == TYPE_COMMIT)
                return fsck_commit((struct commit *) obj);
-       if (obj->type == tag_type)
+       if (obj->type == TYPE_TAG)
                return fsck_tag((struct tag *) obj);
        /* 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);
                obj->used = 1;
-               if (obj->type != tree_type)
+               if (obj->type != TYPE_TREE)
                        err |= objerror(obj, "non-tree in cache-tree");
        }
        for (i = 0; i < it->subtree_nr; i++)
index 2d9441ec60222be6806eddbd5e515b2233a4f06d..ba64f8fff58936ab59074b835b9df06eecf3031e 100644 (file)
@@ -1773,16 +1773,16 @@ static int get_delta(struct rev_info *revs, struct remote_lock *lock)
 
                if (obj->flags & (UNINTERESTING | SEEN))
                        continue;
-               if (obj->type == tag_type) {
+               if (obj->type == TYPE_TAG) {
                        obj->flags |= SEEN;
                        p = add_object(obj, p, NULL, name);
                        continue;
                }
-               if (obj->type == tree_type) {
+               if (obj->type == TYPE_TREE) {
                        p = process_tree((struct tree *)obj, p, NULL, name);
                        continue;
                }
-               if (obj->type == blob_type) {
+               if (obj->type == TYPE_BLOB) {
                        p = process_blob((struct blob *)obj, p, NULL, name);
                        continue;
                }
@@ -1949,12 +1949,12 @@ static int ref_newer(const unsigned char *new_sha1,
         * old.  Otherwise we require --force.
         */
        o = deref_tag(parse_object(old_sha1), NULL, 0);
-       if (!o || o->type != commit_type)
+       if (!o || o->type != TYPE_COMMIT)
                return 0;
        old = (struct commit *) o;
 
        o = deref_tag(parse_object(new_sha1), NULL, 0);
-       if (!o || o->type != commit_type)
+       if (!o || o->type != TYPE_COMMIT)
                return 0;
        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);
        free(ref_info);
 
-       if (o->type == tag_type) {
+       if (o->type == TYPE_TAG) {
                o = deref_tag(o, ls->dentry_name, 0);
                if (o) {
                        len = strlen(ls->dentry_name) + 45;
index bad8a5377771e678624d01895ca0603070d6bede..c29b93ea7199643885cd74148d03db7d1bbb533b 100644 (file)
@@ -19,7 +19,7 @@ static void name_rev(struct commit *commit,
                const char *tip_name, int merge_traversals, int generation,
                int deref)
 {
-       struct rev_name *name = (struct rev_name *)commit->object.util;
+       struct rev_name *name = (struct rev_name *)commit->util;
        struct commit_list *parents;
        int parent_number = 1;
 
@@ -41,7 +41,7 @@ static void name_rev(struct commit *commit,
 
        if (name == NULL) {
                name = xmalloc(sizeof(rev_name));
-               commit->object.util = name;
+               commit->util = name;
                goto copy_data;
        } else if (name->merge_traversals > merge_traversals ||
                        (name->merge_traversals == merge_traversals &&
@@ -84,14 +84,14 @@ static int name_ref(const char *path, const unsigned char *sha1)
        if (tags_only && strncmp(path, "refs/tags/", 10))
                return 0;
 
-       while (o && o->type == tag_type) {
+       while (o && o->type == TYPE_TAG) {
                struct tag *t = (struct tag *) o;
                if (!t->tagged)
                        break; /* broken repository */
                o = parse_object(t->tagged->sha1);
                deref = 1;
        }
-       if (o && o->type == commit_type) {
+       if (o && o->type == TYPE_COMMIT) {
                struct commit *commit = (struct commit *)o;
 
                if (!strncmp(path, "refs/heads/", 11))
@@ -108,7 +108,13 @@ static int name_ref(const char *path, const unsigned char *sha1)
 static const char* get_rev_name(struct object *o)
 {
        static char buffer[1024];
-       struct rev_name *n = (struct rev_name *)o->util;
+       struct rev_name *n;
+       struct commit *c;
+
+       if (o->type != TYPE_COMMIT)
+               return "undefined";
+       c = (struct commit *) o;
+       n = c->util;
        if (!n)
                return "undefined";
 
@@ -167,7 +173,7 @@ int main(int argc, char **argv)
                }
 
                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",
                                        *argv);
                        continue;
index 9adc87479bde2a0b2a0a0335aed12a9f485facff..0f70890a4582fec845fb9399b3dc9f388c6538fc 100644 (file)
--- a/object.c
+++ b/object.c
@@ -9,6 +9,10 @@ struct object **objs;
 static int nr_objs;
 int obj_allocs;
 
+const char *type_names[] = {
+       "none", "blob", "tree", "commit", "bad"
+};
+
 int track_object_refs = 0;
 
 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;
        memcpy(obj->sha1, sha1, 20);
-       obj->type = NULL;
+       obj->type = TYPE_NONE;
        obj->refs = NULL;
        obj->used = 0;
 
@@ -179,7 +183,7 @@ struct object *lookup_unknown_object(const unsigned char *sha1)
        if (!obj) {
                union any_object *ret = xcalloc(1, sizeof(*ret));
                created_object(sha1, &ret->object);
-               ret->object.type = NULL;
+               ret->object.type = TYPE_NONE;
                return &ret->object;
        }
        return obj;
index e08afbd29ff04cf463a4aacdc4fe141a2ab54ce6..f4ee2e55ba7853e3b49cbca7409c89b71d4b848f 100644 (file)
--- a/object.h
+++ b/object.h
@@ -12,19 +12,34 @@ struct object_refs {
        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 {
        unsigned parsed : 1;
        unsigned used : 1;
-       unsigned int flags;
+       unsigned type : TYPE_BITS;
+       unsigned flags : FLAG_BITS;
        unsigned char sha1[20];
-       const char *type;
        struct object_refs *refs;
-       void *util;
 };
 
 extern int track_object_refs;
 extern int obj_allocs;
 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 **/
 struct object *lookup_object(const unsigned char *sha1);
index 75c648c13c6c50335ffc3e79f5d6303bea20104e..7bff2a10b1044651a776b42d4ee3d91661830aa2 100644 (file)
@@ -140,7 +140,7 @@ static struct commit *handle_commit(struct rev_info *revs, struct object *object
        /*
         * Tag object? Look what it points to..
         */
-       while (object->type == tag_type) {
+       while (object->type == TYPE_TAG) {
                struct tag *tag = (struct tag *) object;
                if (revs->tag_objects && !(flags & UNINTERESTING))
                        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
         * reachability crud.
         */
-       if (object->type == commit_type) {
+       if (object->type == TYPE_COMMIT) {
                struct commit *commit = (struct commit *)object;
                if (parse_commit(commit) < 0)
                        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
         * 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;
                if (!revs->tree_objects)
                        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..
         */
-       if (object->type == blob_type) {
+       if (object->type == TYPE_BLOB) {
                struct blob *blob = (struct blob *)object;
                if (!revs->blob_objects)
                        return NULL;
@@ -498,11 +498,11 @@ static int add_parents_only(struct rev_info *revs, const char *arg, int flags)
                return 0;
        while (1) {
                it = get_reference(revs, arg, sha1, 0);
-               if (strcmp(it->type, tag_type))
+               if (it->type != TYPE_TAG)
                        break;
                memcpy(sha1, ((struct tag*)it)->tagged->sha1, 20);
        }
-       if (strcmp(it->type, commit_type))
+       if (it->type != TYPE_COMMIT)
                return 0;
        commit = (struct commit *)it;
        for (parents = commit->parents; parents; parents = parents->next) {
@@ -949,9 +949,11 @@ struct commit *get_revision(struct rev_info *revs)
        }
 
        do {
-               struct commit *commit = revs->commits->item;
+               struct commit_list *entry = revs->commits;
+               struct commit *commit = entry->item;
 
-               revs->commits = revs->commits->next;
+               revs->commits = entry->next;
+               free(entry);
 
                /*
                 * If we haven't done the list limiting, we need to look at
index 409f18850357567748f63f73ec84c066f9e3fe94..af93b11f238e4583f6e7fb9dab5a2224acf4ee1f 100644 (file)
@@ -151,12 +151,12 @@ static int ref_newer(const unsigned char *new_sha1,
         * old.  Otherwise we require --force.
         */
        o = deref_tag(parse_object(old_sha1), NULL, 0);
-       if (!o || o->type != commit_type)
+       if (!o || o->type != TYPE_COMMIT)
                return 0;
        old = (struct commit *) o;
 
        o = deref_tag(parse_object(new_sha1), NULL, 0);
-       if (!o || o->type != commit_type)
+       if (!o || o->type != TYPE_COMMIT)
                return 0;
        new = (struct commit *) o;
 
index 05bce7da3b4935675465f993c24bb1188439d6d9..0eb5132cc1cf09ea7dacdf659d3c03adae761acf 100644 (file)
@@ -12,7 +12,7 @@ static int add_info_ref(const char *path, const unsigned char *sha1)
        struct object *o = parse_object(sha1);
 
        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);
                if (o)
                        fprintf(info_ref_fp, "%s        %s^{}\n",
index 8fe9b7a75f0f8c43744ce6c031d953f51481ecab..cd85d1fa0f9f2afb4e159cb635db435e75ef3e58 100644 (file)
@@ -357,7 +357,7 @@ static int peel_onion(const char *name, int len, unsigned char *sha1)
 {
        unsigned char outer[20];
        const char *sp;
-       const char *type_string = NULL;
+       unsigned int expected_type = 0;
        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 */
        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] == '}')
-               type_string = tree_type;
+               expected_type = TYPE_TREE;
        else if (!strncmp(blob_type, sp, 4) && sp[4] == '}')
-               type_string = blob_type;
+               expected_type = TYPE_BLOB;
        else if (sp[0] == '}')
-               type_string = NULL;
+               expected_type = TYPE_NONE;
        else
                return -1;
 
@@ -397,7 +397,7 @@ static int peel_onion(const char *name, int len, unsigned char *sha1)
        o = parse_object(outer);
        if (!o)
                return -1;
-       if (!type_string) {
+       if (!expected_type) {
                o = deref_tag(o, name, sp - name - 2);
                if (!o || (!o->parsed && !parse_object(o->sha1)))
                        return -1;
@@ -412,18 +412,18 @@ static int peel_onion(const char *name, int len, unsigned char *sha1)
                while (1) {
                        if (!o || (!o->parsed && !parse_object(o->sha1)))
                                return -1;
-                       if (o->type == type_string) {
+                       if (o->type == expected_type) {
                                memcpy(sha1, o->sha1, 20);
                                return 0;
                        }
-                       if (o->type == tag_type)
+                       if (o->type == TYPE_TAG)
                                o = ((struct tag*) o)->tagged;
-                       else if (o->type == commit_type)
+                       else if (o->type == TYPE_COMMIT)
                                o = &(((struct commit *) o)->tree->object);
                        else
                                return error("%.*s: expected %s type, but the object dereferences to %s type",
-                                            len, name, type_string,
-                                            o->type);
+                                            len, name, typename(expected_type),
+                                            typename(o->type));
                        if (!o->parsed)
                                parse_object(o->sha1);
                }
diff --git a/tag.c b/tag.c
index f390ee703036bc74d6447d7e96c828310a948c2b..91913332709eb67252a776ddd1995e183a1a5bf5 100644 (file)
--- a/tag.c
+++ b/tag.c
@@ -5,7 +5,7 @@ const char *tag_type = "tag";
 
 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);
        if (!o && warn) {
                if (!warnlen)
@@ -21,14 +21,14 @@ struct tag *lookup_tag(const unsigned char *sha1)
         if (!obj) {
                 struct tag *ret = xcalloc(1, sizeof(struct tag));
                 created_object(sha1, &ret->object);
-                ret->object.type = tag_type;
+                ret->object.type = TYPE_TAG;
                 return ret;
         }
        if (!obj->type)
-               obj->type = tag_type;
-        if (obj->type != tag_type) {
-                error("Object %s is a %s, not a tree", 
-                      sha1_to_hex(sha1), obj->type);
+               obj->type = TYPE_TAG;
+        if (obj->type != TYPE_TAG) {
+                error("Object %s is a %s, not a tree",
+                      sha1_to_hex(sha1), typename(obj->type));
                 return NULL;
         }
         return (struct tag *) obj;
diff --git a/tree.c b/tree.c
index 9bbe2da37b24007b6409d5e1e5c61a20d0903628..64422fd27e3f855b7989bc8cb9a6a0ada7a30472 100644 (file)
--- a/tree.c
+++ b/tree.c
@@ -131,14 +131,14 @@ struct tree *lookup_tree(const unsigned char *sha1)
        if (!obj) {
                struct tree *ret = xcalloc(1, sizeof(struct tree));
                created_object(sha1, &ret->object);
-               ret->object.type = tree_type;
+               ret->object.type = TYPE_TREE;
                return ret;
        }
        if (!obj->type)
-               obj->type = tree_type;
-       if (obj->type != tree_type) {
-               error("Object %s is a %s, not a tree", 
-                     sha1_to_hex(sha1), obj->type);
+               obj->type = TYPE_TREE;
+       if (obj->type != TYPE_TREE) {
+               error("Object %s is a %s, not a tree",
+                     sha1_to_hex(sha1), typename(obj->type));
                return NULL;
        }
        return (struct tree *) obj;
@@ -216,11 +216,11 @@ struct tree *parse_tree_indirect(const unsigned char *sha1)
        do {
                if (!obj)
                        return NULL;
-               if (obj->type == tree_type)
+               if (obj->type == TYPE_TREE)
                        return (struct tree *) obj;
-               else if (obj->type == commit_type)
+               else if (obj->type == TYPE_COMMIT)
                        obj = &(((struct commit *) obj)->tree->object);
-               else if (obj->type == tag_type)
+               else if (obj->type == TYPE_TAG)
                        obj = ((struct tag *) obj)->tagged;
                else
                        return NULL;
index 47560c9527b9c17db34f10e78d7c1f0d99b746e1..979e58306e46e5fdc005feb9d5a1bf44490fb5c1 100644 (file)
@@ -105,7 +105,7 @@ static int got_sha1(char *hex, unsigned char *sha1)
                        o = parse_object(sha1);
                if (!o)
                        die("oops (%s)", sha1_to_hex(sha1));
-               if (o->type == commit_type) {
+               if (o->type == TYPE_COMMIT) {
                        struct commit_list *parents;
                        if (o->flags & THEY_HAVE)
                                return 0;
@@ -234,7 +234,7 @@ static int send_ref(const char *refname, const unsigned char *sha1)
                o->flags |= OUR_REF;
                nr_our_refs++;
        }
-       if (o->type == tag_type) {
+       if (o->type == TYPE_TAG) {
                o = deref_tag(o, refname, 0);
                packet_write(1, "%s %s^{}\n", sha1_to_hex(o->sha1), refname);
        }