int commit_source::find_dir_commit_parents_to_translate()

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;
}