diff options
author | Junio C Hamano <gitster@pobox.com> | 2016-10-18 12:25:25 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2016-10-18 12:25:25 -0700 |
commit | 4397cafc7895c857cf38a920125a91f1cb13060c (patch) | |
tree | ea75f7e3c2507946c3f4c7e6b10c25153617e4ce | |
parent | 23415c26fef155f2fa9aebf8a48a6ae457b68c7b (diff) | |
download | git-4397cafc7895c857cf38a920125a91f1cb13060c.tar.gz |
commit: simplify fastpath of merge-base
The get_merge_bases_many*() family of functions first call
merge_bases_many() to find all possible merge bases between a single
commit "one" and a set of other commits "twos[]". Because this
typically involves traversing the commit graph, which uses the
object flags on the commits involved, the function needs to clear
the flags before it returns.
Except for one special case. If "one" is exactly one of the "twos",
"one" is the merge base and merge_bases_many() returns a list of
merge bases with a single element, "one", on it, without smudging
the object flags of the commits at all.
We used to use a loop over "twos[]" array to see if this fast-path
would have kicked in in merge_bases_many(), but inspecting the
result is conceptually cleaner.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r-- | commit.c | 15 |
1 files changed, 11 insertions, 4 deletions
@@ -955,10 +955,17 @@ static struct commit_list *get_merge_bases_many_0(struct commit *one, int cnt, i; result = merge_bases_many(one, n, twos); - for (i = 0; i < n; i++) { - if (one == twos[i]) - return result; - } + + /* + * The fast-path of 'one' being the merge-base; there is no + * need to clean the object flags in this case. + */ + if (result && !result->next && + result->item == one && + !(one->object.flags & RESULT)) + return result; + + /* If we didn't get any, or there is only one, we are done */ if (!result || !result->next) { if (cleanup) { clear_commit_marks(one, all_flags); |