Merge branch 'jk/still-interesting' into maint

"git rev-list --objects $old --not --all" to see if everything that
is reachable from $old is already connected to the existing refs
was very inefficient.

* jk/still-interesting:
  limit_list: avoid quadratic behavior from still_interesting
This commit is contained in:
Junio C Hamano 2015-05-26 13:49:26 -07:00
commit df08eb357d

View file

@ -345,14 +345,24 @@ static struct commit *handle_commit(struct rev_info *revs,
die("%s is unknown object", name); die("%s is unknown object", name);
} }
static int everybody_uninteresting(struct commit_list *orig) static int everybody_uninteresting(struct commit_list *orig,
struct commit **interesting_cache)
{ {
struct commit_list *list = orig; struct commit_list *list = orig;
if (*interesting_cache) {
struct commit *commit = *interesting_cache;
if (!(commit->object.flags & UNINTERESTING))
return 0;
}
while (list) { while (list) {
struct commit *commit = list->item; struct commit *commit = list->item;
list = list->next; list = list->next;
if (commit->object.flags & UNINTERESTING) if (commit->object.flags & UNINTERESTING)
continue; continue;
if (interesting_cache)
*interesting_cache = commit;
return 0; return 0;
} }
return 1; return 1;
@ -940,7 +950,8 @@ static void cherry_pick_list(struct commit_list *list, struct rev_info *revs)
/* How many extra uninteresting commits we want to see.. */ /* How many extra uninteresting commits we want to see.. */
#define SLOP 5 #define SLOP 5
static int still_interesting(struct commit_list *src, unsigned long date, int slop) static int still_interesting(struct commit_list *src, unsigned long date, int slop,
struct commit **interesting_cache)
{ {
/* /*
* No source list at all? We're definitely done.. * No source list at all? We're definitely done..
@ -959,7 +970,7 @@ static int still_interesting(struct commit_list *src, unsigned long date, int sl
* Does the source list still have interesting commits in * Does the source list still have interesting commits in
* it? Definitely not done.. * it? Definitely not done..
*/ */
if (!everybody_uninteresting(src)) if (!everybody_uninteresting(src, interesting_cache))
return SLOP; return SLOP;
/* Ok, we're closing in.. */ /* Ok, we're closing in.. */
@ -1078,6 +1089,7 @@ static int limit_list(struct rev_info *revs)
struct commit_list *newlist = NULL; struct commit_list *newlist = NULL;
struct commit_list **p = &newlist; struct commit_list **p = &newlist;
struct commit_list *bottom = NULL; struct commit_list *bottom = NULL;
struct commit *interesting_cache = NULL;
if (revs->ancestry_path) { if (revs->ancestry_path) {
bottom = collect_bottom_commits(list); bottom = collect_bottom_commits(list);
@ -1094,6 +1106,9 @@ static int limit_list(struct rev_info *revs)
list = list->next; list = list->next;
free(entry); free(entry);
if (commit == interesting_cache)
interesting_cache = NULL;
if (revs->max_age != -1 && (commit->date < revs->max_age)) if (revs->max_age != -1 && (commit->date < revs->max_age))
obj->flags |= UNINTERESTING; obj->flags |= UNINTERESTING;
if (add_parents_to_list(revs, commit, &list, NULL) < 0) if (add_parents_to_list(revs, commit, &list, NULL) < 0)
@ -1102,7 +1117,7 @@ static int limit_list(struct rev_info *revs)
mark_parents_uninteresting(commit); mark_parents_uninteresting(commit);
if (revs->show_all) if (revs->show_all)
p = &commit_list_insert(commit, p)->next; p = &commit_list_insert(commit, p)->next;
slop = still_interesting(list, date, slop); slop = still_interesting(list, date, slop, &interesting_cache);
if (slop) if (slop)
continue; continue;
/* If showing all, add the whole pending list to the end */ /* If showing all, add the whole pending list to the end */