int git_cache::compute_rev_with_metadata()

in src/git_cache.h [599:686]


int git_cache::compute_rev_with_metadata(sha1_ref commit, bool is_split,
                                         int &rev, const char *raw_metadata,
                                         bool is_merge, sha1_ref first_parent) {
  if (is_split) {
    // Split commits aren't mapped in the svnbaserev table.
    if (!lookup_rev(commit, rev))
      return 0;
  } else {
    // Starts with a call to lookup_rev.
    if (!compute_base_rev(commit, rev))
      return 0;
  }

  if (!raw_metadata)
    if (compute_metadata(commit, raw_metadata, is_merge, first_parent))
      return 1;

  // Merges cannot be upstream SVN commits.
  if (is_merge)
    return 1;

  if (is_split && first_parent) {
    // If first_parent is in the split2mono database, then commit is not an
    // upstream SVN commit.  This helps to avoid mapping commits like
    // 8bf1494af87f222db2b637a3be6cee40a9a51a62 from swift-clang to commit
    // being cherry-picked (in this case, r354826), since the cherry-pick's
    // parent will not be upstream.
    if (is_being_translated(first_parent))
      return 1;
    sha1_ref mono;
    bool is_based_on_rev = false;
    if (!compute_mono_from_table(first_parent, mono, is_based_on_rev))
      if (!is_based_on_rev)
        return 1;
  }

  parsed_metadata parsed;
  if (parse_commit_metadata_impl(raw_metadata, parsed))
    return 1;

  // Check that committer and author match.
  if (parsed.an != parsed.cn || parsed.ae != parsed.ce ||
      parsed.ad != parsed.cd)
    return 1;

  const char *current = parsed.message;
  while (*current) {
    if (!is_split) {
      if (try_parse_string(current, "llvm-rev: ")) {
        parse_through_newline(current);
        continue;
      }

      int parsed_rev;
      if (parse_num(current, parsed_rev) || parse_ch(current, '\n'))
        break;
      rev = parsed_rev;
      note_rev(commit, rev);
      return 0;
    }

    if (try_parse_string(current,
                         "git-svn-id: https://llvm.org/svn/llvm-project/")) {
      skip_until(current, '\n');
      parse_ch(current, '\n');
      continue;
    }

    int parsed_rev;
    if (skip_until(current, '@') || parse_ch(current, '@') ||
        parse_num(current, parsed_rev) || parse_ch(current, ' '))
      break;

    rev = parsed_rev;
    note_rev(commit, rev);
    return 0;
  }

  // Monorepo commits should always have a rev, either from the 'llvm-rev:' tag
  // or stored in the svnbaserev table.  If we get here there's a problem.
  if (!is_split)
    return error("missing base svn rev for monorepo commit");

  // This is a split commit that's not an upstream commit.
  rev = 0;
  note_rev(commit, rev);
  return 0;
}