X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=revision.h;h=8970b57e3c7e2ca8d213258f1befb84ac06e3a13;hb=293532739415d287786a312ec10849723383796e;hp=7791a72e0abc7b7fad4b99aadbbe2e604b03c881;hpb=b51ad4314078298194d23d46e2b4473ffd32a88a;p=git.git diff --git a/revision.h b/revision.h index 7791a72e..8970b57e 100644 --- a/revision.h +++ b/revision.h @@ -1,164 +1,80 @@ #ifndef REVISION_H #define REVISION_H -/* - * The low 16 bits of the "flags" field shows whether - * a commit is part of the path to the root for that - * parent. - * - * Bit 16 is an internal flag that we've seen the - * definition for this rev, and not just seen it as - * a parent target. - */ -#define marked(rev) ((rev)->flags & 0xffff) -#define SEEN 0x10000 -#define USED 0x20000 -#define REACHABLE 0x40000 - -struct parent { - struct revision *parent; - struct parent *next; +#define SEEN (1u<<0) +#define UNINTERESTING (1u<<1) +#define TREECHANGE (1u<<2) +#define SHOWN (1u<<3) +#define TMP_MARK (1u<<4) /* for isolated cases; clean after use */ +#define BOUNDARY (1u<<5) +#define ADDED (1u<<6) /* Parents already parsed and added? */ + +struct rev_info; + +typedef void (prune_fn_t)(struct rev_info *revs, struct commit *commit); + +struct rev_info { + /* Starting list */ + struct commit_list *commits; + struct object_list *pending_objects; + + /* Basic information */ + const char *prefix; + void *prune_data; + prune_fn_t *prune_fn; + + /* Traversal flags */ + unsigned int dense:1, + no_merges:1, + remove_empty_trees:1, + lifo:1, + topo_order:1, + tag_objects:1, + tree_objects:1, + blob_objects:1, + edge_hint:1, + limited:1, + unpacked:1, + boundary:1, + parents:1; + + /* special limits */ + int max_count; + unsigned long max_age; + unsigned long min_age; + + /* paths limiting */ + struct diff_options diffopt; + + topo_sort_set_fn_t topo_setter; + topo_sort_get_fn_t topo_getter; }; -struct revision { - unsigned int flags; - unsigned char sha1[20]; - unsigned long date; - struct parent *parent; - char tag[1]; +#define REV_TREE_SAME 0 +#define REV_TREE_NEW 1 +#define REV_TREE_DIFFERENT 2 + +/* revision.c */ +extern int rev_same_tree_as_empty(struct rev_info *, struct tree *t1); +extern int rev_compare_tree(struct rev_info *, struct tree *t1, struct tree *t2); + +extern void init_revisions(struct rev_info *revs); +extern int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def); +extern void prepare_revision_walk(struct rev_info *revs); +extern struct commit *get_revision(struct rev_info *revs); + +extern void mark_parents_uninteresting(struct commit *commit); +extern void mark_tree_uninteresting(struct tree *tree); + +struct name_path { + struct name_path *up; + int elem_len; + const char *elem; }; -static struct revision **revs; -static int nr_revs, rev_allocs; - -static int find_rev(unsigned char *sha1) -{ - int first = 0, last = nr_revs; - - while (first < last) { - int next = (first + last) / 2; - struct revision *rev = revs[next]; - int cmp; - - cmp = memcmp(sha1, rev->sha1, 20); - if (!cmp) - return next; - if (cmp < 0) { - last = next; - continue; - } - first = next+1; - } - return -first-1; -} - -static struct revision *lookup_rev(unsigned char *sha1, const char *tag) -{ - int pos = find_rev(sha1); - struct revision *n; - - if (pos >= 0) { - n = revs[pos]; - if (strcmp(n->tag, tag)) - error("expected tag %s on object %s: got %s", tag, sha1_to_hex(sha1), n->tag); - return n; - } - - pos = -pos-1; - - if (rev_allocs == nr_revs) { - rev_allocs = alloc_nr(rev_allocs); - revs = realloc(revs, rev_allocs * sizeof(struct revision *)); - } - n = malloc(sizeof(struct revision) + strlen(tag)); - - n->flags = 0; - memcpy(n->sha1, sha1, 20); - n->parent = NULL; - strcpy(n->tag, tag); - - /* Insert it into the right place */ - memmove(revs + pos + 1, revs + pos, (nr_revs - pos) * sizeof(struct revision *)); - revs[pos] = n; - nr_revs++; - - return n; -} - -static struct revision *add_relationship(struct revision *rev, unsigned char *needs, const char *tag) -{ - struct revision *parent_rev = lookup_rev(needs, tag); - struct parent **pp = &rev->parent, *p; - - while ((p = *pp) != NULL) { - if (p->parent == parent_rev) - return parent_rev; - pp = &p->next; - } - - p = malloc(sizeof(*p)); - p->parent = parent_rev; - p->next = NULL; - *pp = p; - return parent_rev; -} - -static void mark_reachable(struct revision *rev, unsigned int mask) -{ - struct parent *p = rev->parent; - - /* If we've been here already, don't bother */ - if (rev->flags & mask) - return; - rev->flags |= mask | USED; - while (p) { - mark_reachable(p->parent, mask); - p = p->next; - } -} - -static unsigned long parse_commit_date(const char *buf) -{ - unsigned long date; - - if (memcmp(buf, "author", 6)) - return 0; - while (*buf++ != '\n') - /* nada */; - if (memcmp(buf, "committer", 9)) - return 0; - while (*buf++ != '>') - /* nada */; - date = strtoul(buf, NULL, 10); - if (date == ULONG_MAX) - date = 0; - return date; -} - -static struct revision * parse_commit(unsigned char *sha1) -{ - struct revision *rev = lookup_rev(sha1, "commit"); - - if (!(rev->flags & SEEN)) { - void *buffer, *bufptr; - unsigned long size; - char type[20]; - unsigned char parent[20]; - - rev->flags |= SEEN; - buffer = bufptr = read_sha1_file(sha1, type, &size); - if (!buffer || strcmp(type, "commit")) - die("%s is not a commit object", sha1_to_hex(sha1)); - bufptr += 46; /* "tree " + "hex sha1" + "\n" */ - while (!memcmp(bufptr, "parent ", 7) && !get_sha1_hex(bufptr+7, parent)) { - add_relationship(rev, parent, "commit"); - parse_commit(parent); - bufptr += 48; /* "parent " + "hex sha1" + "\n" */ - } - rev->date = parse_commit_date(bufptr); - free(buffer); - } - return rev; -} - -#endif /* REVISION_H */ +extern struct object_list **add_object(struct object *obj, + struct object_list **p, + struct name_path *path, + const char *name); + +#endif