Skip to content

Commit

Permalink
merge-base: avoid unnecessary postprocessing.
Browse files Browse the repository at this point in the history
When we have only one merge-base candidates in the result list,
there is no point going back to mark the reachable commits
again.  And that is the most common case, so try not to waste
time on it.  Suggested by Linus.

Signed-off-by: Junio C Hamano <junkio@cox.net>
  • Loading branch information
Junio C Hamano committed Nov 11, 2005
1 parent ed9a540 commit 9e5f4a5
Showing 1 changed file with 43 additions and 34 deletions.
77 changes: 43 additions & 34 deletions merge-base.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,47 @@ static struct commit *interesting(struct commit_list *list)

static int show_all = 0;

static void mark_reachable_commits(struct commit_list *result,
struct commit_list *list)
{
struct commit_list *tmp;

/*
* Postprocess to fully contaminate the well.
*/
for (tmp = result; tmp; tmp = tmp->next) {
struct commit *c = tmp->item;
/* Reinject uninteresting ones to list,
* so we can scan their parents.
*/
if (c->object.flags & UNINTERESTING)
commit_list_insert(c, &list);
}
while (list) {
struct commit *c = list->item;
struct commit_list *parents;

tmp = list;
list = list->next;
free(tmp);

/* Anything taken out of the list is uninteresting, so
* mark all its parents uninteresting. We do not
* parse new ones (we already parsed all the relevant
* ones).
*/
parents = c->parents;
while (parents) {
struct commit *p = parents->item;
parents = parents->next;
if (!(p->object.flags & UNINTERESTING)) {
p->object.flags |= UNINTERESTING;
commit_list_insert(p, &list);
}
}
}
}

static int merge_base(struct commit *rev1, struct commit *rev2)
{
struct commit_list *list = NULL;
Expand Down Expand Up @@ -171,40 +212,8 @@ static int merge_base(struct commit *rev1, struct commit *rev2)
if (!result)
return 1;

/*
* Postprocess to fully contaminate the well.
*/
for (tmp = result; tmp; tmp = tmp->next) {
struct commit *c = tmp->item;
/* Reinject uninteresting ones to list,
* so we can scan their parents.
*/
if (c->object.flags & UNINTERESTING)
commit_list_insert(c, &list);
}
while (list) {
struct commit *c = list->item;
struct commit_list *parents;

tmp = list;
list = list->next;
free(tmp);

/* Anything taken out of the list is uninteresting, so
* mark all its parents uninteresting. We do not
* parse new ones (we already parsed all the relevant
* ones).
*/
parents = c->parents;
while (parents) {
struct commit *p = parents->item;
parents = parents->next;
if (!(p->object.flags & UNINTERESTING)) {
p->object.flags |= UNINTERESTING;
commit_list_insert(p, &list);
}
}
}
if (result->next && list)
mark_reachable_commits(result, list);

while (result) {
struct commit *commit = result->item;
Expand Down

0 comments on commit 9e5f4a5

Please sign in to comment.