Do not output "GEN " when generating perl.mak
[gitweb.git] / revision.c
index f5b8ae4f031a059cff08328cf661515b9e68ccec..3c2eb125e6e9332fe32be9bcec6fb2005228c211 100644 (file)
@@ -437,36 +437,6 @@ static void limit_list(struct rev_info *revs)
                        continue;
                p = &commit_list_insert(commit, p)->next;
        }
-       if (revs->boundary) {
-               /* mark the ones that are on the result list first */
-               for (list = newlist; list; list = list->next) {
-                       struct commit *commit = list->item;
-                       commit->object.flags |= TMP_MARK;
-               }
-               for (list = newlist; list; list = list->next) {
-                       struct commit *commit = list->item;
-                       struct object *obj = &commit->object;
-                       struct commit_list *parent;
-                       if (obj->flags & UNINTERESTING)
-                               continue;
-                       for (parent = commit->parents;
-                            parent;
-                            parent = parent->next) {
-                               struct commit *pcommit = parent->item;
-                               if (!(pcommit->object.flags & UNINTERESTING))
-                                       continue;
-                               pcommit->object.flags |= BOUNDARY;
-                               if (pcommit->object.flags & TMP_MARK)
-                                       continue;
-                               pcommit->object.flags |= TMP_MARK;
-                               p = &commit_list_insert(pcommit, p)->next;
-                       }
-               }
-               for (list = newlist; list; list = list->next) {
-                       struct commit *commit = list->item;
-                       commit->object.flags &= ~TMP_MARK;
-               }
-       }
        revs->commits = newlist;
 }
 
@@ -1193,17 +1163,6 @@ static void rewrite_parents(struct rev_info *revs, struct commit *commit)
        }
 }
 
-static void mark_boundary_to_show(struct commit *commit)
-{
-       struct commit_list *p = commit->parents;
-       while (p) {
-               commit = p->item;
-               p = p->next;
-               if (commit->object.flags & BOUNDARY)
-                       commit->object.flags |= BOUNDARY_SHOW;
-       }
-}
-
 static int commit_match(struct commit *commit, struct rev_info *opt)
 {
        if (!opt->grep_filter)
@@ -1235,15 +1194,9 @@ static struct commit *get_revision_1(struct rev_info *revs)
                 */
                if (!revs->limited) {
                        if (revs->max_age != -1 &&
-                           (commit->date < revs->max_age)) {
-                               if (revs->boundary)
-                                       commit->object.flags |=
-                                               BOUNDARY_SHOW | BOUNDARY;
-                               else
-                                       continue;
-                       } else
-                               add_parents_to_list(revs, commit,
-                                               &revs->commits);
+                           (commit->date < revs->max_age))
+                               continue;
+                       add_parents_to_list(revs, commit, &revs->commits);
                }
                if (commit->object.flags & SHOWN)
                        continue;
@@ -1252,18 +1205,6 @@ static struct commit *get_revision_1(struct rev_info *revs)
                                                    revs->ignore_packed))
                    continue;
 
-               /* We want to show boundary commits only when their
-                * children are shown.  When path-limiter is in effect,
-                * rewrite_parents() drops some commits from getting shown,
-                * and there is no point showing boundary parents that
-                * are not shown.  After rewrite_parents() rewrites the
-                * parents of a commit that is shown, we mark the boundary
-                * parents with BOUNDARY_SHOW.
-                */
-               if (commit->object.flags & BOUNDARY_SHOW) {
-                       commit->object.flags |= SHOWN;
-                       return commit;
-               }
                if (commit->object.flags & UNINTERESTING)
                        continue;
                if (revs->min_age != -1 && (commit->date > revs->min_age))
@@ -1286,80 +1227,136 @@ static struct commit *get_revision_1(struct rev_info *revs)
                        if (revs->parents)
                                rewrite_parents(revs, commit);
                }
-               if (revs->boundary)
-                       mark_boundary_to_show(commit);
-               commit->object.flags |= SHOWN;
                return commit;
        } while (revs->commits);
        return NULL;
 }
 
+static void gc_boundary(struct object_array *array)
+{
+       unsigned nr = array->nr;
+       unsigned alloc = array->alloc;
+       struct object_array_entry *objects = array->objects;
+
+       if (alloc <= nr) {
+               unsigned i, j;
+               for (i = j = 0; i < nr; i++) {
+                       if (objects[i].item->flags & SHOWN)
+                               continue;
+                       if (i != j)
+                               objects[j] = objects[i];
+                       j++;
+               }
+               for (i = j; i < nr; i++)
+                       objects[i].item = NULL;
+               array->nr = j;
+       }
+}
+
 struct commit *get_revision(struct rev_info *revs)
 {
        struct commit *c = NULL;
+       struct commit_list *l;
+
+       if (revs->boundary == 2) {
+               unsigned i;
+               struct object_array *array = &revs->boundary_commits;
+               struct object_array_entry *objects = array->objects;
+               for (i = 0; i < array->nr; i++) {
+                       c = (struct commit *)(objects[i].item);
+                       if (!c)
+                               continue;
+                       if (!(c->object.flags & CHILD_SHOWN))
+                               continue;
+                       if (!(c->object.flags & SHOWN))
+                               break;
+               }
+               if (array->nr <= i)
+                       return NULL;
 
-       if (revs->reverse) {
-               struct commit_list *list;
+               c->object.flags |= SHOWN | BOUNDARY;
+               return c;
+       }
 
-               /*
-                * rev_info.reverse is used to note the fact that we
-                * want to output the list of revisions in reverse
-                * order.  To accomplish this goal, reverse can have
-                * different values:
-                *
-                *  0  do nothing
-                *  1  reverse the list
-                *  2  internal use:  we have already obtained and
-                *     reversed the list, now we only need to yield
-                *     its items.
-                */
+       if (revs->reverse) {
+               int limit = -1;
 
-               if (revs->reverse == 1) {
-                       revs->reverse = 0;
-                       list = NULL;
-                       while ((c = get_revision(revs)))
-                               commit_list_insert(c, &list);
-                       revs->commits = list;
-                       revs->reverse = 2;
+               if (0 <= revs->max_count) {
+                       limit = revs->max_count;
+                       if (0 < revs->skip_count)
+                               limit += revs->skip_count;
                }
-
-               if (!revs->commits)
-                       return NULL;
-               c = revs->commits->item;
-               list = revs->commits->next;
-               free(revs->commits);
-               revs->commits = list;
-               return c;
+               l = NULL;
+               while ((c = get_revision_1(revs))) {
+                       commit_list_insert(c, &l);
+                       if ((0 < limit) && !--limit)
+                               break;
+               }
+               revs->commits = l;
+               revs->reverse = 0;
+               revs->max_count = -1;
+               c = NULL;
        }
 
-       if (0 < revs->skip_count) {
-               while ((c = get_revision_1(revs)) != NULL) {
-                       if (revs->skip_count-- <= 0)
+       /*
+        * Now pick up what they want to give us
+        */
+       c = get_revision_1(revs);
+       if (c) {
+               while (0 < revs->skip_count) {
+                       revs->skip_count--;
+                       c = get_revision_1(revs);
+                       if (!c)
                                break;
                }
        }
 
-       /* Check the max_count ... */
+       /*
+        * Check the max_count.
+        */
        switch (revs->max_count) {
        case -1:
                break;
        case 0:
-               if (revs->boundary) {
-                       struct commit_list *list = revs->commits;
-                       while (list) {
-                               list->item->object.flags |=
-                                       BOUNDARY_SHOW | BOUNDARY;
-                               list = list->next;
-                       }
-                       /* all remaining commits are boundary commits */
-                       revs->max_count = -1;
-                       revs->limited = 1;
-               } else
-                       return NULL;
+               c = NULL;
+               break;
        default:
                revs->max_count--;
        }
+
        if (c)
+               c->object.flags |= SHOWN;
+
+       if (!revs->boundary) {
                return c;
-       return get_revision_1(revs);
+       }
+
+       if (!c) {
+               /*
+                * get_revision_1() runs out the commits, and
+                * we are done computing the boundaries.
+                * switch to boundary commits output mode.
+                */
+               revs->boundary = 2;
+               return get_revision(revs);
+       }
+
+       /*
+        * boundary commits are the commits that are parents of the
+        * ones we got from get_revision_1() but they themselves are
+        * not returned from get_revision_1().  Before returning
+        * 'c', we need to mark its parents that they could be boundaries.
+        */
+
+       for (l = c->parents; l; l = l->next) {
+               struct object *p;
+               p = &(l->item->object);
+               if (p->flags & (CHILD_SHOWN | SHOWN))
+                       continue;
+               p->flags |= CHILD_SHOWN;
+               gc_boundary(&revs->boundary_commits);
+               add_object_array(p, NULL, &revs->boundary_commits);
+       }
+
+       return c;
 }