# How to organise files Use catalog records to give stored payloads names and directories. Run changes inside the application’s write transaction against the selected store cursor. The examples call that cursor `store` and assume `objects` aliases `ol.xitstash`. ## Create a directory and file together Publish the payload first. Pass its digest as `digest`: ```clojure (objects/create! store [{:name "invoices"} {:under 1 :name "november.pdf" :digest digest}]) ``` The result is a vector containing the directory and file records. Save their `:id` and `:revision` values after the transaction commits. `:under 1` selects the first request in this batch. To put a file in an existing directory, use `:parent` with that directory’s ID. Omit both keys to create a node below root `0`. If a sibling already has the requested name, creation fails. Let the exception abort the transaction, including any payload publication earlier in that callback. ## Find a file Use a read cursor to the same store: ```clojure (let [directory (objects/lookup store 0 "invoices")] (objects/lookup store (:id directory) "november.pdf")) ``` `children` returns a directory’s records in UTF-8 byte name order. `path` returns a vector of names from the root. Neither result needs an open cursor after the call completes. ## Rename without overwriting a concurrent change Save the file record when the user starts editing. Pass that record’s revision to the later write transaction: ```clojure (objects/move! store (:id file) {:name "paid.pdf"} (:revision file)) ``` A stale revision throws `:xitstash/conflict`, even if the requested change would now be a no-op. Read the current file and resolve the conflict before retrying. Do not silently substitute its new revision. To move between directories, add `:parent` to the destination. To replace an occupied destination, add `:replace? true`. Replacement requires the same node kind and an empty destination directory. It preserves the source ID and removes the destination record. ## Replace a file's content Prepare the new bytes outside the transaction. Publish them, then update the existing file within the same callback: ```clojure (objects/put! store prepared) (objects/update! store (:id file) (:digest prepared) (:revision file)) ``` The file keeps its ID, name and parent. Its previous payload stays available until explicitly deleted. ## Remove the name ```clojure (objects/remove! store (:id file) (:revision file)) ``` This removes the catalog record, not the payload. For content removal, follow [How to delete content and reclaim space](deletion.adoc). See [`create!`](api/ol-xitstash.adoc#create-BANG-) for name and ID rules. See [Branches need an explicit merge policy](content-and-history.adoc#branches-need-an-explicit-merge-policy) before combining catalogs from separate branches.