in src/commit_interleaver.h [307:365]
int commit_interleaver::make_partial_tree(
const commit_source &source, sha1_ref base, sha1_ref mono,
std::vector<git_tree::item_type> &items, dir_mask &source_dirs) {
// Fill in source_dirs as we go.
if (source.has_root || source.is_repeat) {
if (source.is_repeat) {
assert(mono);
assert(!base);
assert(source.dir_index == -1);
source_dirs.bits |= dirs.repeated_dirs.bits;
} else {
assert(base);
assert(source.dir_index != -1);
assert(dirs.list[source.dir_index].is_root);
source_dirs.set(source.dir_index);
}
git_tree tree;
tree.sha1 = source.is_repeat ? mono : base;
if (cache.ls_tree(tree))
return 1;
if (source.is_repeat) {
for (int i = 0; i < tree.num_items; ++i) {
assert(tree.items[i].sha1);
int d = dirs.find_dir(tree.items[i].name);
if (d == -1)
continue;
if (!dirs.repeated_dirs.test(d))
continue;
items.push_back(tree.items[i]);
}
return 0;
}
assert(base);
items.reserve(items.size() + tree.num_items);
for (int i = 0; i < tree.num_items; ++i) {
auto &item = tree.items[i];
if (dirs.is_dir(item.name))
return error("root dir '-' conflicts with tracked dir '" +
base->to_string() + "'");
items.push_back(item);
}
return 0;
}
assert(base);
sha1_ref base_tree;
if (cache.compute_commit_tree(base, base_tree))
return error("failed to look up tree for '" + base->to_string() + "'");
assert(base_tree);
items.emplace_back();
items.back().sha1 = base_tree;
items.back().name = dirs.list[source.dir_index].name;
items.back().type = git_tree::item_type::tree;
source_dirs.set(source.dir_index);
return 0;
}