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:
Junio C Hamano
2018-06-25 13:22:36 -07:00
11 changed files with 209 additions and 56 deletions

View File

@ -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);