int commit_interleaver::compare_trees()

in src/commit_interleaver.h [871:905]


int commit_interleaver::compare_trees(const commit_source &source,
                                      const git_tree &head_tree, sha1_ref sha1,
                                      dir_mask &changed_dirs) {
  assert(source.has_root || source.is_repeat);
  git_tree tree;
  tree.sha1 = sha1;
  if (cache.ls_tree(tree))
    return 1;

  std::vector<git_tree::item_type> items;
  for (int i = 0; i < tree.num_items; ++i) {
    int d = dirs.find_dir(tree.items[i].name);
    if (d != -1)
      if (source.is_repeat ? dirs.repeated_dirs.test(d) : dirs.list[d].is_root)
        items.push_back(tree.items[i]);
  }
  for (int i = 0; i < head_tree.num_items; ++i) {
    int d = dirs.find_dir(head_tree.items[i].name);
    if (d != -1)
      if (source.is_repeat ? dirs.repeated_dirs.test(d) : dirs.list[d].is_root)
        items.push_back(head_tree.items[i]);
  }
  // Sort and see if we're matched up pairwise.
  std::sort(items.begin(), items.end());
  if (!source.is_repeat)
    if (items.size() % 2) {
      changed_dirs.set(dirs.find_dir("-"));
      return 0;
    }

  for (int i = 0, ie = items.size(); i < ie; i += 2)
    if (i + 1 == ie || items[i] < items[i + 1])
      changed_dirs.set(dirs.find_dir(items[i].name));
  return 0;
}