in src/translation_queue.h [189:254]
int translation_queue::find_repeat_commits_and_head(commit_source *repeat,
sha1_ref &head) {
if (!repeat)
return 0;
assert(repeat->is_repeat);
if (repeat->goal == repeat->head)
return repeat->skip_repeat_commits();
// Set a lower bound for how far back to create merges. Note that branches
// can have a head from a start directive, without any of the sources having
// an appropriate head.
long long min_ct_to_merge = 0;
if (head)
if (cache.compute_ct(head, min_ct_to_merge))
return error("failed to %ct of head '" + head->to_string() +
"' for stopping repeat '" + repeat->goal->to_string() + "'");
// If it's possible to fast forward from head, figure out how far.
bool can_ff_head = false;
bool any_source_cts = false;
if (!head || cache.merge_base_is_ancestor(head, repeat->goal)) {
can_ff_head = true;
for (auto &source : sources) {
if (source.is_repeat)
continue;
if (!source.head)
continue;
// If there's a head and it's not an ancestor of the repeat commit goal,
// then we should stretch repeat back to it.
sha1_ref mono;
if (cache.compute_mono(source.head, mono))
return error("could not find monorepo hash for '" +
source.head->to_string() + "'");
if (cache.merge_base_is_ancestor(mono, repeat->goal))
continue;
long long ct;
if (cache.compute_ct(source.head, ct))
return error("could not grab commit date of '" +
source.head->to_string() + "'");
min_ct_to_merge = std::max(min_ct_to_merge, ct);
any_source_cts = true;
}
}
// Try harder to fast-forward.
if (can_ff_head && !any_source_cts) {
if (fparents.empty()) {
// If there is nothing to translate and all the heads can fast-forward to
// the repeat goal, then we only need to look back far enough to
// determine the goal and refine the head.
min_ct_to_merge = LLONG_MAX;
} else {
// Get the real ct, not the ct used for sorting.
if (cache.compute_ct(fparents.back().commit, min_ct_to_merge))
return error("could not grab commit date of '" +
fparents.back().commit->to_string() + "'");
}
}
// We should have found this by now.
assert(min_ct_to_merge);
return repeat->find_repeat_commits_and_head(cache, min_ct_to_merge);
}