 
 (defn subscribe [sub-ch bus-out out]
   (go-loop [{:keys [user repo] :as s} (<! sub-ch)]
-             (async/sub bus-out [user repo] out)
-             (println "subscribed: " [user repo])
-             (recur (<! sub-ch))))
+           (async/sub bus-out [user repo] out)
+           (println "subscribed: " [user repo])
+           (recur (<! sub-ch))))
 
 
 (defn publish [pub-ch fetch-ch store bus-in out]
   (go-loop [{:keys [user meta] :as ps} (<! pub-ch)]
            (let [repo (:id meta)
                  nc (<! (new-commits! store meta (<! (-get-in store [user repo]))))]
-             (println "fetching" nc)
              (>! out {:type :fetch
                       :ids nc})
-             (doseq [[repo-id val] (:fetched (<! fetch-ch))]
-               (<! (-assoc-in store [repo-id] val)))
-             (<! (-update-in store [user repo] #(if % (update % meta) meta)))
-             (>! bus-in ps)
-             (println "published:" [user repo])
+             (let [fetched (<! fetch-ch)]
+               (doseq [[repo-id val] (:fetched fetched)]
+                 (<! (-assoc-in store [repo-id] val))))
+             ;; TODO find cleaner way to atomically update
+             (let [old-meta (<! (-get-in store [user repo]))
+                   up-meta (<! (-update-in store [user repo] #(if % (update % meta) meta)))]
+               (when (not= old-meta up-meta)
+                 (println "publishing:" [user repo])
+                 (>! bus-in ps)))
              (recur (<! pub-ch)))))
 
 

            sub-ch (chan)
            fetch-ch (chan)]
        (async/sub p :new-meta sub-ch false)
        (subscribe sub-ch bus-out (print-chan "SUBSOUT" out))

        (async/sub p :meta-up pub-ch false)
        (async/sub p :fetched fetch-ch false)

                                             2 42
                                             3 43}})
           (recur (<! in))))


(defn fake-peer [store]
  (let [fake-id (str "FAKE" (rand-int 100))
        in (chan) #_(print-chan (str fake-id "-IN"))
        out (async/pub in (fn [{:keys [user meta]}] [user (:id meta)]))
        #_(print-chan (str fake-id "-OUT"))]
    {:volatile {:server nil
                :chans [in out]
                :store store}
     :ip fake-id}))


(defn realize-value [stage store eval-fn]
