rewrite building the tree

the current way creates bad trees with duplicate entries, which
fails `git fsck`