diff --git a/src/merge.c b/src/merge.c index 0b11c0da3..66952c074 100644 --- a/src/merge.c +++ b/src/merge.c @@ -205,6 +205,12 @@ int git_merge__bases_many(git_commit_list **out, git_revwalk *walk, git_commit_l git_commit_list *result = NULL, *tmp = NULL; git_pqueue list; + /* If there's only the one commit, there can be no merge bases */ + if (twos->length == 0) { + *out = NULL; + return 0; + } + /* if the commit is repeated, we have a our merge base already */ git_vector_foreach(twos, i, two) { if (one == two) diff --git a/src/revwalk.c b/src/revwalk.c index 753911246..f037ee692 100644 --- a/src/revwalk.c +++ b/src/revwalk.c @@ -141,6 +141,9 @@ static int push_commit(git_revwalk *walk, const git_oid *oid, int uninteresting, if (commit == NULL) return -1; /* error already reported by failed lookup */ + if (uninteresting) + walk->did_hide = 1; + commit->uninteresting = uninteresting; if (walk->one == NULL && !uninteresting) { walk->one = commit; @@ -390,11 +393,18 @@ static int prepare_walk(git_revwalk *walk) return GIT_ITEROVER; } - /* first figure out what the merge bases are */ - if (git_merge__bases_many(&bases, walk, walk->one, &walk->twos) < 0) - return -1; + /* + * If the user asked to hide commits, we need to figure out + * what the merge bases are so we can know when we can stop + * marking parents uninteresting. + */ + if (walk->did_hide) { + if (git_merge__bases_many(&bases, walk, walk->one, &walk->twos) < 0) + return -1; + + git_commit_list_free(&bases); + } - git_commit_list_free(&bases); if (process_commit(walk, walk->one, walk->one->uninteresting) < 0) return -1; diff --git a/src/revwalk.h b/src/revwalk.h index 8c821d098..a0ce1ae86 100644 --- a/src/revwalk.h +++ b/src/revwalk.h @@ -32,7 +32,8 @@ struct git_revwalk { int (*enqueue)(git_revwalk *, git_commit_list_node *); unsigned walking:1, - first_parent: 1; + first_parent: 1, + did_hide: 1; unsigned int sorting; /* merge base calculation */