Merge branch 'ds/commit-graph-lockfile-fix'
Update to ds/generation-numbers topic. * ds/commit-graph-lockfile-fix: commit-graph: fix UX issue when .lock file exists commit-graph.txt: update design document merge: check config before loading commits commit: use generation number in remove_redundant() commit: add short-circuit to paint_down_to_common() commit: use generation numbers for in_merge_bases() ref-filter: use generation number for --contains commit-graph: always load commit-graph information commit: use generations in paint_down_to_common() commit-graph: compute generation numbers commit: add generation number to struct commit ref-filter: fix outdated comment on in_commit_list
This commit is contained in:
61
commit.c
61
commit.c
@ -344,7 +344,7 @@ const void *detach_commit_buffer(struct commit *commit, unsigned long *sizep)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int parse_commit_buffer(struct commit *item, const void *buffer, unsigned long size)
|
||||
int parse_commit_buffer(struct commit *item, const void *buffer, unsigned long size, int check_graph)
|
||||
{
|
||||
const char *tail = buffer;
|
||||
const char *bufptr = buffer;
|
||||
@ -399,6 +399,9 @@ int parse_commit_buffer(struct commit *item, const void *buffer, unsigned long s
|
||||
}
|
||||
item->date = parse_commit_date(bufptr, tail);
|
||||
|
||||
if (check_graph)
|
||||
load_commit_graph_info(item);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -425,7 +428,7 @@ int parse_commit_gently(struct commit *item, int quiet_on_missing)
|
||||
return error("Object %s not a commit",
|
||||
oid_to_hex(&item->object.oid));
|
||||
}
|
||||
ret = parse_commit_buffer(item, buffer, size);
|
||||
ret = parse_commit_buffer(item, buffer, size, 0);
|
||||
if (save_commit_buffer && !ret) {
|
||||
set_commit_buffer(item, buffer, size);
|
||||
return 0;
|
||||
@ -653,6 +656,24 @@ static int compare_commits_by_author_date(const void *a_, const void *b_,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int compare_commits_by_gen_then_commit_date(const void *a_, const void *b_, void *unused)
|
||||
{
|
||||
const struct commit *a = a_, *b = b_;
|
||||
|
||||
/* newer commits first */
|
||||
if (a->generation < b->generation)
|
||||
return 1;
|
||||
else if (a->generation > b->generation)
|
||||
return -1;
|
||||
|
||||
/* use date as a heuristic when generations are equal */
|
||||
if (a->date < b->date)
|
||||
return 1;
|
||||
else if (a->date > b->date)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int compare_commits_by_commit_date(const void *a_, const void *b_, void *unused)
|
||||
{
|
||||
const struct commit *a = a_, *b = b_;
|
||||
@ -800,11 +821,14 @@ static int queue_has_nonstale(struct prio_queue *queue)
|
||||
}
|
||||
|
||||
/* all input commits in one and twos[] must have been parsed! */
|
||||
static struct commit_list *paint_down_to_common(struct commit *one, int n, struct commit **twos)
|
||||
static struct commit_list *paint_down_to_common(struct commit *one, int n,
|
||||
struct commit **twos,
|
||||
int min_generation)
|
||||
{
|
||||
struct prio_queue queue = { compare_commits_by_commit_date };
|
||||
struct prio_queue queue = { compare_commits_by_gen_then_commit_date };
|
||||
struct commit_list *result = NULL;
|
||||
int i;
|
||||
uint32_t last_gen = GENERATION_NUMBER_INFINITY;
|
||||
|
||||
one->object.flags |= PARENT1;
|
||||
if (!n) {
|
||||
@ -823,6 +847,15 @@ static struct commit_list *paint_down_to_common(struct commit *one, int n, struc
|
||||
struct commit_list *parents;
|
||||
int flags;
|
||||
|
||||
if (commit->generation > last_gen)
|
||||
BUG("bad generation skip %8x > %8x at %s",
|
||||
commit->generation, last_gen,
|
||||
oid_to_hex(&commit->object.oid));
|
||||
last_gen = commit->generation;
|
||||
|
||||
if (commit->generation < min_generation)
|
||||
break;
|
||||
|
||||
flags = commit->object.flags & (PARENT1 | PARENT2 | STALE);
|
||||
if (flags == (PARENT1 | PARENT2)) {
|
||||
if (!(commit->object.flags & RESULT)) {
|
||||
@ -871,7 +904,7 @@ static struct commit_list *merge_bases_many(struct commit *one, int n, struct co
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list = paint_down_to_common(one, n, twos);
|
||||
list = paint_down_to_common(one, n, twos, 0);
|
||||
|
||||
while (list) {
|
||||
struct commit *commit = pop_commit(&list);
|
||||
@ -929,6 +962,7 @@ static int remove_redundant(struct commit **array, int cnt)
|
||||
parse_commit(array[i]);
|
||||
for (i = 0; i < cnt; i++) {
|
||||
struct commit_list *common;
|
||||
uint32_t min_generation = array[i]->generation;
|
||||
|
||||
if (redundant[i])
|
||||
continue;
|
||||
@ -937,8 +971,12 @@ static int remove_redundant(struct commit **array, int cnt)
|
||||
continue;
|
||||
filled_index[filled] = j;
|
||||
work[filled++] = array[j];
|
||||
|
||||
if (array[j]->generation < min_generation)
|
||||
min_generation = array[j]->generation;
|
||||
}
|
||||
common = paint_down_to_common(array[i], filled, work);
|
||||
common = paint_down_to_common(array[i], filled, work,
|
||||
min_generation);
|
||||
if (array[i]->object.flags & PARENT2)
|
||||
redundant[i] = 1;
|
||||
for (j = 0; j < filled; j++)
|
||||
@ -1048,14 +1086,21 @@ int in_merge_bases_many(struct commit *commit, int nr_reference, struct commit *
|
||||
{
|
||||
struct commit_list *bases;
|
||||
int ret = 0, i;
|
||||
uint32_t min_generation = GENERATION_NUMBER_INFINITY;
|
||||
|
||||
if (parse_commit(commit))
|
||||
return ret;
|
||||
for (i = 0; i < nr_reference; i++)
|
||||
for (i = 0; i < nr_reference; i++) {
|
||||
if (parse_commit(reference[i]))
|
||||
return ret;
|
||||
if (reference[i]->generation < min_generation)
|
||||
min_generation = reference[i]->generation;
|
||||
}
|
||||
|
||||
bases = paint_down_to_common(commit, nr_reference, reference);
|
||||
if (commit->generation > min_generation)
|
||||
return ret;
|
||||
|
||||
bases = paint_down_to_common(commit, nr_reference, reference, commit->generation);
|
||||
if (commit->object.flags & PARENT2)
|
||||
ret = 1;
|
||||
clear_commit_marks(commit, all_flags);
|
||||
|
Reference in New Issue
Block a user