in src/commit_source.h [411:475]
int commit_source::list_first_parents_limit_impl(git_cache &cache,
const std::string &limitter,
std::string start,
sha1_ref &last_first_parent,
std::vector<sha1_ref> stops) {
assert(!start.empty());
// Repeat fparents don't have the right metadata to make this work.
assert(!is_repeat);
auto &git_reply = cache.git_reply;
std::vector<const char *> argv = {
"git",
"log",
"--first-parent",
"--date=raw",
"--format=tformat:%H %ct %P%x00%an%n%cn%n%ad%n%cd%n%ae%n%ce%n%B%x00",
start.c_str(),
};
if (!limitter.empty())
argv.push_back(limitter.c_str());
std::vector<std::string> stop_sha1s;
if (!stops.empty()) {
argv.push_back("--not");
for (auto &stop : stops)
stop_sha1s.push_back(stop->to_string());
for (auto &stop : stop_sha1s)
argv.push_back(stop.c_str());
}
argv.push_back(nullptr);
git_reply.clear();
if (call_git(argv.data(), nullptr, "", git_reply))
return error("git failed");
git_reply.push_back(0);
const char *current = git_reply.data();
const char *end = git_reply.data() + git_reply.size() - 1;
while (current != end) {
fparents.emplace_back(source_index);
fparents.back().is_translated = extra_commits_have_been_translated;
if (cache.pool.parse_sha1(current, fparents.back().commit) ||
parse_space(current) || parse_ct(current, fparents.back().ct) ||
parse_space(current))
return error("failed to parse commit and ct");
validate_last_ct();
last_first_parent = sha1_ref();
const char *metadata = current;
const char *end_metadata = end;
if (cache.parse_for_store_metadata(fparents.back().commit, metadata,
end_metadata, fparents.back().is_merge,
last_first_parent))
return 1;
cache.store_metadata_if_new(fparents.back().commit, metadata, end_metadata,
fparents.back().is_merge, last_first_parent);
current = end_metadata;
if (last_first_parent) {
fparents.back().has_parents = true;
fparents.back().head_p = 0;
}
if (parse_null(current) || parse_newline(current))
return 1;
}
return 0;
}