       ; return a map describing the view
       {:view git-pane
        :sidebar sidebar
+       :repo repo
        :content content
        :offset offset-atom
-       :close-fn! (fn [])
+       :close-fn! (fn []
+                    (.close repo))
        :should-remove-fn #(not (.exists f))
        :italicize-fn (fn [] false)})))
 

(defn update-sidebar!
  ([]
    (let [{:keys [sidebar
                  content
                  offset]} (get @editors/editors @ui/tree-selection)
          path (ui/get-project-root-path)]
      (when (and sidebar content offset path)
        (update-sidebar! sidebar content offset (git-file path)))))
  ([^JTree sidebar content offset f]
    ; remove existing listener
    (doseq [l (.getTreeSelectionListeners sidebar)]
      (.removeTreeSelectionListener sidebar l))
    ; add model and listener, then re-select the row
    (let [repo (FileRepository. f)
          git (Git. repo)
          commits (cons nil ; represents uncommitted changes
                        (try
                          (-> git .log (.setMaxCount max-commits)
                              (.setSkip @offset) .call .iterator iterator-seq)
                          (catch Exception _ [])))
          selected-row (selected-row sidebar commits)]

          offset-atom (atom 0)
          content (create-content repo)
          sidebar (doto (create-sidebar)
                    (update-sidebar! repo content offset-atom))
          paging-panel (doto (s/horizontal-panel
                               :items (create-paging-buttons offset-atom))
                         (update-paging-buttons! offset-atom))
