             (build-node graph node))]
     (reduce build-step {:node {} :nodes []} flat-tree)))
 
-(defn parse-files [files]
-  (let [data (->> files
-                  (map process-filename)
-                  (reduce parse-step {}))
-        tree (build-tree {:children []} data)
+(defn recursive-merge [a b]
+  (if (and (map? a) (map? b))
+    (merge-with recursive-merge a b)
+    (merge a b)))
+
+(defn merge-file-data [m [path data]]
+  (update-in m (path->segments path) recursive-merge data))
+
+(defn process-files [path->data]
+  (let [data (reduce merge-file-data {} path->data)
+        tree (build-tree data)
         flat-tree (flatten-tree tree)
         graph (build-graph flat-tree)]
     graph))
 
+(defn parse-yaml [data]
+  (try
+    (yaml/parse-string data false)
+    (catch Exception e
+      {:error (str e)})))
+
 (defn parse-uncommitted [dir]
-  (let [files (->> (fs/find-files dir #".*\.yaml$")
-                   (filter #(fs/file? %)))]
-    (parse-files (->> files
-                      (map #(vector (relative-filename dir %)
-                                    (-> %
-                                        slurp
-                                        (yaml/parse-string false))))
-                      (into {})))))
+  (let [files (filter fs/file? (fs/find-files dir #".*\.yaml$"))
+        paths (map #(relative-path dir %) files)
+        datas (map #(parse-yaml (slurp %)) files)
+        path->data (zipmap paths datas)]
+    (process-files path->data)))
 
 (defn parse-commit [repo commit]
   (let [tree (git-commit/tree repo commit)

                      data (String. (:data blob))]
                  (assoc res
                         (.getPathString walk)
                         (yaml/parse-string data false)))
                res))]
      (parse-files (reduce parse-entry {} lazy-walk)))))

                 (fn [mapped-here]
                   (mapv #(hash-map :name %) mapped-here)))})

(defn build-tree [data]
  (letfn [(build-children [name-segments data]
            (into []
                  (comp (filter #(map? (second %)))
                        (map (fn [[k v]]
                               (build-node (conj name-segments k) v))))
                  data))
          (build-node [name-segments data]
            (cond
              (map? data)
              (into {:name (str/join "/" name-segments)
                     :children (build-children name-segments data)}
                    (remove #(map? (second %)) data))))
          (build-step [root [name-segment data]]
            (update root :children conj
                    (build-node [name-segment] data)))]
    (let [root {:name [] :children ()}
          tree (reduce build-step root data)]
      (-> tree
          (process-down set-kind nil)
          (process-down set-parent nil)
          (process-down create-mapped-here-links nil)))))

(defn flatten-tree [node]
