X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=revision.h;h=6c2becad1394829142a3775a43097f65de4e524a;hb=ac5a85181ac18b0119705f46cfa825389643df33;hp=f965f3fc5f66827759223dc9caf63d9abf40ae15;hpb=01796b0e9180f92ed23aa8dc2261857b9dec7d13;p=git.git diff --git a/revision.h b/revision.h index f965f3fc..6c2becad 100644 --- a/revision.h +++ b/revision.h @@ -1,158 +1,73 @@ #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; -}; - -struct revision { - unsigned int flags; - unsigned char sha1[20]; - unsigned long date; - struct parent *parent; +#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 */ + +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; + + /* special limits */ + int max_count; + unsigned long max_age; + unsigned long min_age; + + topo_sort_set_fn_t topo_setter; + topo_sort_get_fn_t topo_getter; }; -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) -{ - int pos = find_rev(sha1); - struct revision *n; - - if (pos >= 0) - return revs[pos]; - - 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)); +#define REV_TREE_SAME 0 +#define REV_TREE_NEW 1 +#define REV_TREE_DIFFERENT 2 - n->flags = 0; - memcpy(n->sha1, sha1, 20); - n->parent = NULL; +/* revision.c */ +extern int rev_same_tree_as_empty(struct tree *t1); +extern int rev_compare_tree(struct tree *t1, struct tree *t2); - /* Insert it into the right place */ - memmove(revs + pos + 1, revs + pos, (nr_revs - pos) * sizeof(struct revision *)); - revs[pos] = n; - nr_revs++; +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); - return n; -} +extern void mark_parents_uninteresting(struct commit *commit); +extern void mark_tree_uninteresting(struct tree *tree); -static struct revision *add_relationship(struct revision *rev, unsigned char *needs) -{ - struct revision *parent_rev = lookup_rev(needs); - 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 int parse_commit(unsigned char *sha1) -{ - struct revision *rev = lookup_rev(sha1); - - if (!(rev->flags & SEEN)) { - void *buffer, *bufptr; - unsigned long size; - char type[20]; - unsigned char parent[20]; +struct name_path { + struct name_path *up; + int elem_len; + const char *elem; +}; - rev->flags |= SEEN; - buffer = bufptr = read_sha1_file(sha1, type, &size); - if (!buffer || strcmp(type, "commit")) - return -1; - bufptr += 46; /* "tree " + "hex sha1" + "\n" */ - while (!memcmp(bufptr, "parent ", 7) && !get_sha1_hex(bufptr+7, parent)) { - add_relationship(rev, parent); - parse_commit(parent); - bufptr += 48; /* "parent " + "hex sha1" + "\n" */ - } - rev->date = parse_commit_date(bufptr); - free(buffer); - } - return 0; -} +extern struct object_list **add_object(struct object *obj, + struct object_list **p, + struct name_path *path, + const char *name); -#endif /* REVISION_H */ +#endif