Skip to content

Commit fcfc2d5

Browse files
committed
Merge branch 'jk/tag-contains-ab' (early part) into maint
* 'jk/tag-contains-ab' (early part): tag: speed up --contains calculation
2 parents 908bb1a + ffc4b80 commit fcfc2d5

File tree

1 file changed

+45
-1
lines changed

1 file changed

+45
-1
lines changed

builtin/tag.c

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include "tag.h"
1313
#include "run-command.h"
1414
#include "parse-options.h"
15+
#include "diff.h"
16+
#include "revision.h"
1517

1618
static const char * const git_tag_usage[] = {
1719
"git tag [-a|-s|-u <key-id>] [-f] [-m <msg>|-F <file>] <tagname> [<head>]",
@@ -40,6 +42,48 @@ static int match_pattern(const char **patterns, const char *ref)
4042
return 0;
4143
}
4244

45+
static int in_commit_list(const struct commit_list *want, struct commit *c)
46+
{
47+
for (; want; want = want->next)
48+
if (!hashcmp(want->item->object.sha1, c->object.sha1))
49+
return 1;
50+
return 0;
51+
}
52+
53+
static int contains_recurse(struct commit *candidate,
54+
const struct commit_list *want)
55+
{
56+
struct commit_list *p;
57+
58+
/* was it previously marked as containing a want commit? */
59+
if (candidate->object.flags & TMP_MARK)
60+
return 1;
61+
/* or marked as not possibly containing a want commit? */
62+
if (candidate->object.flags & UNINTERESTING)
63+
return 0;
64+
/* or are we it? */
65+
if (in_commit_list(want, candidate))
66+
return 1;
67+
68+
if (parse_commit(candidate) < 0)
69+
return 0;
70+
71+
/* Otherwise recurse and mark ourselves for future traversals. */
72+
for (p = candidate->parents; p; p = p->next) {
73+
if (contains_recurse(p->item, want)) {
74+
candidate->object.flags |= TMP_MARK;
75+
return 1;
76+
}
77+
}
78+
candidate->object.flags |= UNINTERESTING;
79+
return 0;
80+
}
81+
82+
static int contains(struct commit *candidate, const struct commit_list *want)
83+
{
84+
return contains_recurse(candidate, want);
85+
}
86+
4387
static int show_reference(const char *refname, const unsigned char *sha1,
4488
int flag, void *cb_data)
4589
{
@@ -58,7 +102,7 @@ static int show_reference(const char *refname, const unsigned char *sha1,
58102
commit = lookup_commit_reference_gently(sha1, 1);
59103
if (!commit)
60104
return 0;
61-
if (!is_descendant_of(commit, filter->with_commit))
105+
if (!contains(commit, filter->with_commit))
62106
return 0;
63107
}
64108

0 commit comments

Comments
 (0)