in src/commit_interleaver.h [641:708]
int commit_interleaver::interleave() {
// Persistent buffers.
std::vector<MergeTarget> targets;
std::vector<sha1_ref> new_parents;
std::vector<int> parent_revs;
std::vector<git_tree::item_type> items;
git_cache::commit_tree_buffers buffers;
// Construct trees and commit them.
progress_reporter progress(q);
progress.report();
while (!q.fparents.empty()) {
auto fparent = q.fparents.back();
q.fparents.pop_back();
auto &source = q.sources[fparent.index];
if (fparent.is_translated) {
MergeRequest merge(targets, new_parents, parent_revs, items, buffers);
sha1_ref base, mono;
if (source.is_repeat) {
mono = fparent.commit;
} else {
base = fparent.commit;
if (cache.compute_mono(fparent.commit, mono))
return error("expected '" + fparent.commit->to_string() +
"' to be translated already");
}
targets.emplace_back(source, base, mono);
sha1_ref new_commit;
if (merge_targets(merge, new_commit))
return error("failed to generate merge of '" +
fparent.commit->to_string() + "'");
set_source_head(source, fparent.commit);
head = new_commit;
progress.report_merge();
continue;
}
assert(!source.is_repeat);
if (!source.commits.count)
return error("need to translate '" + fparent.commit->to_string() +
"' but out of commits");
auto untranslated_first = q.commits.begin() + source.commits.first,
untranslated_last = untranslated_first + source.commits.count;
while (untranslated_first->commit != fparent.commit) {
if (translate_commit(source, *untranslated_first, new_parents,
parent_revs, items, buffers))
return error("failed to translate side commit '" +
untranslated_first->commit->to_string() + "'");
if (++untranslated_first == untranslated_last)
return error("first parent missing from side_commits");
progress.report_side();
}
if (translate_commit(source, *untranslated_first, new_parents, parent_revs,
items, buffers, &head, fparent.head_p))
return error("failed to translate commit '" +
untranslated_first->commit->to_string() + "'");
set_source_head(source, fparent.commit);
++untranslated_first;
source.commits.count = untranslated_last - untranslated_first;
source.commits.first = untranslated_first - q.commits.begin();
progress.report_fparent();
}
progress.report();
return 0;
}