mirror of
https://github.com/git/git.git
synced 2026-03-15 03:00:07 +01:00
Merge branch 'jk/tag-contains-ab' (early part) into next
* 'jk/tag-contains-ab' (early part): default core.clockskew variable to one day limit "contains" traversals based on commit timestamp tag: speed up --contains calculation
This commit is contained in:
@@ -12,6 +12,8 @@
|
||||
#include "tag.h"
|
||||
#include "run-command.h"
|
||||
#include "parse-options.h"
|
||||
#include "diff.h"
|
||||
#include "revision.h"
|
||||
|
||||
static const char * const git_tag_usage[] = {
|
||||
"git tag [-a|-s|-u <key-id>] [-f] [-m <msg>|-F <file>] <tagname> [<head>]",
|
||||
@@ -23,6 +25,8 @@ static const char * const git_tag_usage[] = {
|
||||
|
||||
static char signingkey[1000];
|
||||
|
||||
static int core_clock_skew = 86400;
|
||||
|
||||
struct tag_filter {
|
||||
const char **patterns;
|
||||
int lines;
|
||||
@@ -40,6 +44,68 @@ static int match_pattern(const char **patterns, const char *ref)
|
||||
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,
|
||||
unsigned long cutoff)
|
||||
{
|
||||
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;
|
||||
|
||||
/* stop searching if we go too far back in time */
|
||||
if (candidate->date < cutoff)
|
||||
return 0;
|
||||
|
||||
/* Otherwise recurse and mark ourselves for future traversals. */
|
||||
for (p = candidate->parents; p; p = p->next) {
|
||||
if (contains_recurse(p->item, want, cutoff)) {
|
||||
candidate->object.flags |= TMP_MARK;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
candidate->object.flags |= UNINTERESTING;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int contains(struct commit *candidate, const struct commit_list *want)
|
||||
{
|
||||
unsigned long cutoff = 0;
|
||||
|
||||
if (core_clock_skew >= 0) {
|
||||
const struct commit_list *c;
|
||||
unsigned long min_date = ULONG_MAX;
|
||||
for (c = want; c; c = c->next) {
|
||||
if (parse_commit(c->item) < 0)
|
||||
continue;
|
||||
if (c->item->date < min_date)
|
||||
min_date = c->item->date;
|
||||
}
|
||||
if (min_date > core_clock_skew)
|
||||
cutoff = min_date - core_clock_skew;
|
||||
}
|
||||
|
||||
return contains_recurse(candidate, want, cutoff);
|
||||
}
|
||||
|
||||
static int show_reference(const char *refname, const unsigned char *sha1,
|
||||
int flag, void *cb_data)
|
||||
{
|
||||
@@ -58,7 +124,7 @@ static int show_reference(const char *refname, const unsigned char *sha1,
|
||||
commit = lookup_commit_reference_gently(sha1, 1);
|
||||
if (!commit)
|
||||
return 0;
|
||||
if (!is_descendant_of(commit, filter->with_commit))
|
||||
if (!contains(commit, filter->with_commit))
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -241,6 +307,14 @@ static int git_tag_config(const char *var, const char *value, void *cb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(var, "core.clockskew")) {
|
||||
if (!value || !strcmp(value, "none"))
|
||||
core_clock_skew = -1;
|
||||
else
|
||||
core_clock_skew = git_config_int(var, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return git_default_config(var, value, cb);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user