summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2016-10-18 12:25:25 -0700
committerJunio C Hamano <gitster@pobox.com>2016-10-18 12:25:25 -0700
commit4397cafc7895c857cf38a920125a91f1cb13060c (patch)
treeea75f7e3c2507946c3f4c7e6b10c25153617e4ce
parent23415c26fef155f2fa9aebf8a48a6ae457b68c7b (diff)
downloadgit-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.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/commit.c b/commit.c
index aada266f9a..6266c0380c 100644
--- a/commit.c
+++ b/commit.c
@@ -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);