free_patch_ids(&ids);
}
-static void add_to_list(struct commit_list **p, struct commit *commit, struct commit_list *n)
+/* How many extra uninteresting commits we want to see.. */
+#define SLOP 5
+
+static int still_interesting(struct commit_list *src, unsigned long date, int slop)
{
- p = &commit_list_insert(commit, p)->next;
- *p = n;
+ /*
+ * No source list at all? We're definitely done..
+ */
+ if (!src)
+ return 0;
+
+ /*
+ * Does the destination list contain entries with a date
+ * before the source list? Definitely _not_ done.
+ */
+ if (date < src->item->date)
+ return SLOP;
+
+ /*
+ * Does the source list still have interesting commits in
+ * it? Definitely not done..
+ */
+ if (!everybody_uninteresting(src))
+ return SLOP;
+
+ /* Ok, we're closing in.. */
+ return slop-1;
}
static int limit_list(struct rev_info *revs)
{
+ int slop = SLOP;
+ unsigned long date = ~0ul;
struct commit_list *list = revs->commits;
struct commit_list *newlist = NULL;
struct commit_list **p = &newlist;
return -1;
if (obj->flags & UNINTERESTING) {
mark_parents_uninteresting(commit);
- if (everybody_uninteresting(list)) {
- if (revs->show_all)
- add_to_list(p, commit, list);
- break;
- }
- if (!revs->show_all)
- continue;
+ if (revs->show_all)
+ p = &commit_list_insert(commit, p)->next;
+ slop = still_interesting(list, date, slop);
+ if (slop)
+ continue;
+ /* If showing all, add the whole pending list to the end */
+ if (revs->show_all)
+ *p = list;
+ break;
}
if (revs->min_age != -1 && (commit->date > revs->min_age))
continue;
+ date = commit->date;
p = &commit_list_insert(commit, p)->next;
show = show_early_output;
return 0;
}
-static void handle_all(struct rev_info *revs, unsigned flags)
+static void handle_refs(struct rev_info *revs, unsigned flags,
+ int (*for_each)(each_ref_fn, void *))
{
struct all_refs_cb cb;
cb.all_revs = revs;
cb.all_flags = flags;
- for_each_ref(handle_one_ref, &cb);
+ for_each(handle_one_ref, &cb);
}
static void handle_one_reflog_commit(unsigned char *sha1, void *cb_data)
add_pending_object(revs, &head->object, "HEAD");
add_pending_object(revs, &other->object, "MERGE_HEAD");
bases = get_merge_bases(head, other, 1);
- while (bases) {
- struct commit *it = bases->item;
- struct commit_list *n = bases->next;
- free(bases);
- bases = n;
- it->object.flags |= UNINTERESTING;
- add_pending_object(revs, &it->object, "(merge-base)");
- }
+ add_pending_commit_list(revs, bases, UNINTERESTING);
+ free_commit_list(bases);
+ head->object.flags |= SYMMETRIC_LEFT;
if (!active_nr)
read_cache();
i++;
}
revs->prune_data = prune;
+ revs->limited = 1;
}
int handle_revision_arg(const char *arg, struct rev_info *revs,
continue;
}
if (!strcmp(arg, "--all")) {
- handle_all(revs, flags);
+ handle_refs(revs, flags, for_each_ref);
+ continue;
+ }
+ if (!strcmp(arg, "--branches")) {
+ handle_refs(revs, flags, for_each_branch_ref);
+ continue;
+ }
+ if (!strcmp(arg, "--tags")) {
+ handle_refs(revs, flags, for_each_tag_ref);
+ continue;
+ }
+ if (!strcmp(arg, "--remotes")) {
+ handle_refs(revs, flags, for_each_remote_ref);
continue;
}
if (!strcmp(arg, "--first-parent")) {