code: function treewalk(path, prefix, depth, cb) {
  
        function sort(entry) { return self.sortEntry(entry.name + (entry.type === 'dir' ? '/' : '')); }
  
        self.readdir(path, function(err, list) { if (err) return cb(err);
          var ab = asyncbuilder(cb);
  
          // first normalize names to fix decomposed unicode e.g. from OSX-HFS
          u.each(list, function(entry) { entry.name = normalize(entry.name); });
  
          u.each(u.sortBy(list, sort), function(entry) {
            var pathname = u.join(path, entry.name);
            var pname = u.join(prefix, entry.name);
            if (self.exclude(entry)) return;
            if (entry.type === 'dir') {
              if (depth >= self.depth) return;
              return treewalk(pathname, pname, depth + 1, ab.asyncAppend()); // recurse
            }
            if (self.mm && !self.mm.match(pname.slice(1))) return; // failed minimatch glob test
            if (entry.type === 'file') {
              var listEntry = { filepath:pname };
              if (entry.sha) { listEntry.sha = entry.sha; }
              if (entry.hash) { listEntry.hash = entry.hash; }
              return ab.append(listEntry);
            }
          });
  
          ab.complete();
        });
      }
docs: async recursive treewalk walks directory tree starting in path - uses asyncbuilder to preserve name-based ordering returns cb(err,tree) where tree[] = array of names (for files) or arrays (for directories)