Skip to content

Commit c1dd29a

Browse files
committed
Merge branch 'generation-numbers-in--contains'
These two changes improve these commands: 1. `git tag --contains` 2. `git branch --contains` For `git branch --contains` the improvement depends on the tips, so the boost will not work for recent remote branches (where we haven't initialized the commit yet) but will help reduce the cost of containment queries for old branches.
2 parents 4a130da + 21188e8 commit c1dd29a

File tree

2 files changed

+27
-6
lines changed

2 files changed

+27
-6
lines changed

commit.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1076,12 +1076,19 @@ int in_merge_bases_many(struct commit *commit, int nr_reference, struct commit *
10761076
{
10771077
struct commit_list *bases;
10781078
int ret = 0, i;
1079+
uint32_t min_generation = GENERATION_NUMBER_UNDEF;
10791080

10801081
if (parse_commit(commit))
10811082
return ret;
1082-
for (i = 0; i < nr_reference; i++)
1083+
for (i = 0; i < nr_reference; i++) {
10831084
if (parse_commit(reference[i]))
10841085
return ret;
1086+
if (min_generation > reference[i]->generation)
1087+
min_generation = reference[i]->generation;
1088+
}
1089+
1090+
if (commit->generation > min_generation)
1091+
return 0;
10851092

10861093
bases = paint_down_to_common(commit, nr_reference, reference);
10871094
if (commit->object.flags & PARENT2)

ref-filter.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1584,7 +1584,8 @@ static int in_commit_list(const struct commit_list *want, struct commit *c)
15841584
*/
15851585
static enum contains_result contains_test(struct commit *candidate,
15861586
const struct commit_list *want,
1587-
struct contains_cache *cache)
1587+
struct contains_cache *cache,
1588+
uint32_t cutoff)
15881589
{
15891590
enum contains_result *cached = contains_cache_at(cache, candidate);
15901591

@@ -1598,8 +1599,11 @@ static enum contains_result contains_test(struct commit *candidate,
15981599
return CONTAINS_YES;
15991600
}
16001601

1601-
/* Otherwise, we don't know; prepare to recurse */
16021602
parse_commit_or_die(candidate);
1603+
1604+
if (candidate->generation < cutoff)
1605+
return CONTAINS_NO;
1606+
16031607
return CONTAINS_UNKNOWN;
16041608
}
16051609

@@ -1615,8 +1619,18 @@ static enum contains_result contains_tag_algo(struct commit *candidate,
16151619
struct contains_cache *cache)
16161620
{
16171621
struct contains_stack contains_stack = { 0, 0, NULL };
1618-
enum contains_result result = contains_test(candidate, want, cache);
1622+
enum contains_result result;
1623+
uint32_t cutoff = GENERATION_NUMBER_UNDEF;
1624+
const struct commit_list *p;
1625+
1626+
for (p = want; p; p = p->next) {
1627+
struct commit *c = p->item;
1628+
parse_commit_or_die(c);
1629+
if (c->generation < cutoff)
1630+
cutoff = c->generation;
1631+
}
16191632

1633+
result = contains_test(candidate, want, cache, cutoff);
16201634
if (result != CONTAINS_UNKNOWN)
16211635
return result;
16221636

@@ -1634,7 +1648,7 @@ static enum contains_result contains_tag_algo(struct commit *candidate,
16341648
* If we just popped the stack, parents->item has been marked,
16351649
* therefore contains_test will return a meaningful yes/no.
16361650
*/
1637-
else switch (contains_test(parents->item, want, cache)) {
1651+
else switch (contains_test(parents->item, want, cache, cutoff)) {
16381652
case CONTAINS_YES:
16391653
*contains_cache_at(cache, commit) = CONTAINS_YES;
16401654
contains_stack.nr--;
@@ -1648,7 +1662,7 @@ static enum contains_result contains_tag_algo(struct commit *candidate,
16481662
}
16491663
}
16501664
free(contains_stack.contains_stack);
1651-
return contains_test(candidate, want, cache);
1665+
return contains_test(candidate, want, cache, cutoff);
16521666
}
16531667

16541668
static int commit_contains(struct ref_filter *filter, struct commit *commit,

0 commit comments

Comments
 (0)