in src/commit_source.h [798:876]
int commit_source::find_dir_commit_parents_to_translate(
git_cache &cache, bump_allocator &parent_alloc,
std::vector<commit_type> &untranslated) {
assert(!is_repeat);
assert(goal);
std::vector<std::string> mtsplits;
if (extract_mtsplits(cache, mtsplits))
return 1;
std::string start_sha1 = goal->to_string();
std::vector<const char *> argv = {
"git",
"log",
"--reverse",
"--date-order",
"--date=raw",
"--format=tformat:%m%H %T %P%x00%an%n%cn%n%ad%n%cd%n%ae%n%ce%n%B%x00",
start_sha1.c_str(),
"--not",
};
for (auto &mtsplit : mtsplits)
argv.push_back(mtsplit.c_str());
argv.push_back(nullptr);
auto &git_reply = cache.git_reply;
git_reply.clear();
if (call_git(argv.data(), nullptr, "", git_reply))
return 1;
git_reply.push_back(0);
// Translate the commits.
commits.first = untranslated.size();
std::vector<sha1_ref> parents;
const char *current = git_reply.data();
const char *end = git_reply.data() + git_reply.size() - 1;
while (current != end) {
// line ::= ( GT | MINUS ) commit SP tree ( SP parent )*
bool is_boundary = false;
sha1_ref commit, tree;
if (parse_boundary(current, is_boundary) ||
cache.pool.parse_sha1(current, commit) || parse_space(current) ||
cache.pool.parse_sha1(current, tree))
return 1;
// Warm the cache.
assert(commit);
assert(tree);
cache.note_commit_tree(commit, tree);
if (is_boundary) {
// If this is a boundary commit, skip ahead after warming the cache.
if (parse_boundary_metadata(cache, commit, current, end))
return 1;
continue;
}
// Parse the commit.
bool should_skip = false;
untranslated.emplace_back();
untranslated.back().commit = commit;
untranslated.back().tree = tree;
if (parse_untranslated_commit(cache, parent_alloc, commit, current, end,
untranslated.back(), parents, should_skip))
return 1;
// Pop off the commit if it's being skipped.
if (should_skip)
untranslated.pop_back();
}
// Store the number of commits.
commits.count = untranslated.size() - commits.first;
// Start the worker.
if (worker)
worker->start();
return 0;
}