writeTree method
Implementation
Future<GitHash?> writeTree(GitIndex index) async {
var allTreeDirs = {''};
var treeObjects = {'': GitTree.empty()};
var treeObjFullPath = <GitTree, String>{};
index.entries.forEach((entry) {
var fullPath = entry.path;
var fileName = p.basename(fullPath);
var dirName = p.dirname(fullPath);
// Construct all the tree objects
var allDirs = <String>[];
while (dirName != '.') {
allTreeDirs.add(dirName);
allDirs.add(dirName);
dirName = p.dirname(dirName);
}
allDirs.sort(dirSortFunc);
for (var dir in allDirs) {
if (!treeObjects.containsKey(dir)) {
var tree = GitTree.empty();
treeObjects[dir] = tree;
}
var parentDir = p.dirname(dir);
if (parentDir == '.') parentDir = '';
var parentTree = treeObjects[parentDir]!;
var folderName = p.basename(dir);
treeObjFullPath[parentTree] = parentDir;
var i = parentTree.entries.indexWhere((e) => e.name == folderName);
if (i != -1) {
continue;
}
parentTree.entries.add(GitTreeEntry(
mode: GitFileMode.Dir,
name: folderName,
hash: GitHash.zero(),
));
}
dirName = p.dirname(fullPath);
if (dirName == '.') {
dirName = '';
}
var leaf = GitTreeEntry(
mode: entry.mode,
name: fileName,
hash: entry.hash,
);
treeObjects[dirName]!.entries.add(leaf);
});
assert(treeObjects.containsKey(''));
// Write all the tree objects
var hashMap = <String, GitHash>{};
var allDirs = allTreeDirs.toList();
allDirs.sort(dirSortFunc);
for (var dir in allDirs.reversed) {
var tree = treeObjects[dir]!;
for (var i = 0; i < tree.entries.length; i++) {
var leaf = tree.entries[i];
if (leaf.hash.isNotEmpty) {
//
// Making sure the leaf is a blob
//
assert(await () async {
var leafObjRes = await objStorage.read(leaf.hash);
var leafObj = leafObjRes.get();
return leafObj.formatStr() == 'blob';
}());
continue;
}
var fullPath = p.join(treeObjFullPath[tree]!, leaf.name);
var hash = hashMap[fullPath]!;
tree.entries[i] = GitTreeEntry(
mode: leaf.mode,
name: leaf.name,
hash: hash,
);
}
var hash = await objStorage.writeObject(tree);
hashMap[dir] = hash;
}
return hashMap[''];
}