Merge branch 'jk/tag-contains-ab' (early part) into maint
* 'jk/tag-contains-ab' (early part): tag: speed up --contains calculation
This commit is contained in:
commit
fcfc2d5879
@ -12,6 +12,8 @@
|
|||||||
#include "tag.h"
|
#include "tag.h"
|
||||||
#include "run-command.h"
|
#include "run-command.h"
|
||||||
#include "parse-options.h"
|
#include "parse-options.h"
|
||||||
|
#include "diff.h"
|
||||||
|
#include "revision.h"
|
||||||
|
|
||||||
static const char * const git_tag_usage[] = {
|
static const char * const git_tag_usage[] = {
|
||||||
"git tag [-a|-s|-u <key-id>] [-f] [-m <msg>|-F <file>] <tagname> [<head>]",
|
"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)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int in_commit_list(const struct commit_list *want, struct commit *c)
|
||||||
|
{
|
||||||
|
for (; want; want = want->next)
|
||||||
|
if (!hashcmp(want->item->object.sha1, c->object.sha1))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int contains_recurse(struct commit *candidate,
|
||||||
|
const struct commit_list *want)
|
||||||
|
{
|
||||||
|
struct commit_list *p;
|
||||||
|
|
||||||
|
/* was it previously marked as containing a want commit? */
|
||||||
|
if (candidate->object.flags & TMP_MARK)
|
||||||
|
return 1;
|
||||||
|
/* or marked as not possibly containing a want commit? */
|
||||||
|
if (candidate->object.flags & UNINTERESTING)
|
||||||
|
return 0;
|
||||||
|
/* or are we it? */
|
||||||
|
if (in_commit_list(want, candidate))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (parse_commit(candidate) < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Otherwise recurse and mark ourselves for future traversals. */
|
||||||
|
for (p = candidate->parents; p; p = p->next) {
|
||||||
|
if (contains_recurse(p->item, want)) {
|
||||||
|
candidate->object.flags |= TMP_MARK;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
candidate->object.flags |= UNINTERESTING;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int contains(struct commit *candidate, const struct commit_list *want)
|
||||||
|
{
|
||||||
|
return contains_recurse(candidate, want);
|
||||||
|
}
|
||||||
|
|
||||||
static int show_reference(const char *refname, const unsigned char *sha1,
|
static int show_reference(const char *refname, const unsigned char *sha1,
|
||||||
int flag, void *cb_data)
|
int flag, void *cb_data)
|
||||||
{
|
{
|
||||||
@ -58,7 +102,7 @@ static int show_reference(const char *refname, const unsigned char *sha1,
|
|||||||
commit = lookup_commit_reference_gently(sha1, 1);
|
commit = lookup_commit_reference_gently(sha1, 1);
|
||||||
if (!commit)
|
if (!commit)
|
||||||
return 0;
|
return 0;
|
||||||
if (!is_descendant_of(commit, filter->with_commit))
|
if (!contains(commit, filter->with_commit))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user