diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,171 @@
+## Changelog
+
+#### Upcoming
+
+#### v0.3.1.2
+
+*Revisions*
+
+* Fixed a bug causing prettifying to fail across filesystem boundaries. ([#72](https://github.com/hjwylde/git-fmt/issues/72))
+
+#### v0.3.1.1
+
+*Revisions*
+
+* Fixed a bug causing the program to hang when not in the root directory. ([#66](https://github.com/hjwylde/git-fmt/issues/66))
+* Fixed a bug that omitted searching the drive for a config file. ([#66](https://github.com/hjwylde/git-fmt/issues/66))
+* Fixed a bug where output files could be created outside of the temp directory. ([#68](https://github.com/hjwylde/git-fmt/issues/68))
+
+#### v0.3.1.0
+
+*Minor*
+
+* Added timeout wrapper for the program command. ([#52](https://github.com/hjwylde/git-fmt/issues/52))
+* Added `diff` mode. ([#23](https://github.com/hjwylde/git-fmt/issues/23))
+
+#### v0.3.0.5
+
+*Revisions*
+
+* Fixed a bug causing prettifying to fail across filesystem boundaries. ([#72](https://github.com/hjwylde/git-fmt/issues/72))
+
+#### v0.3.0.4
+
+*Revisions*
+
+* Fixed a bug causing the program to hang when not in the root directory. ([#66](https://github.com/hjwylde/git-fmt/issues/66))
+* Fixed a bug that omitted searching the drive for a config file. ([#66](https://github.com/hjwylde/git-fmt/issues/66))
+* Fixed a bug where output files could be created outside of the temp directory. ([#68](https://github.com/hjwylde/git-fmt/issues/68))
+
+#### v0.3.0.3
+
+*Revisions*
+
+* Restricted use of `--operate-on-tracked` and `--operate-on REF` at the same time. ([#65](https://github.com/hjwylde/git-fmt/issues/65))
+* Removed long option for help text (as git overrides it for man pages). ([#65](https://github.com/hjwylde/git-fmt/issues/65))
+
+#### v0.3.0.2
+
+*Revisions*
+
+* Fixed a bug where passing arguments didn't properly narrow down the operation files. ([#64](https://github.com/hjwylde/git-fmt/issues/64))
+
+#### v0.3.0.1
+
+*Revisions*
+
+* Relaxed version constraints. ([#63](https://github.com/hjwylde/git-fmt/issues/63))
+
+#### v0.3.0.0
+
+*Major*
+
+* Restricted arguments to being inside the repository. ([#34](https://github.com/hjwylde/git-fmt/issues/34))
+* Refactored library to use pipes. ([#32](https://github.com/hjwylde/git-fmt/issues/32))
+* Made `Options` and `Version` modules private. ([#62](https://github.com/hjwylde/git-fmt/issues/62))
+* Renamed library modules to `Omnifmt`. ([#62](https://github.com/hjwylde/git-fmt/issues/62))
+* Refactored pipeline to feed and consume triples. ([#61](https://github.com/hjwylde/git-fmt/issues/61))
+* Set default `--operate-on` to `head`. ([#28](https://github.com/hjwylde/git-fmt/issues/28))
+
+*Minor*
+
+* Changed "not found" status to print as debug message. ([#61](https://github.com/hjwylde/git-fmt/issues/61))
+* Added "unsupported" status as debug message. ([#61](https://github.com/hjwylde/git-fmt/issues/61))
+* Added `--operate-on-tracked` and `--operate-on REF` options. ([#28](https://github.com/hjwylde/git-fmt/issues/28))
+
+#### v0.2.2.1
+
+*Revisions*
+
+* Fixed a bug causing prettifying to fail across filesystem boundaries. ([#72](https://github.com/hjwylde/git-fmt/issues/72))
+
+#### v0.2.2.0
+
+*Minor*
+
+* Added `--threads` option to change the number of threads for parallelisation. ([#54](https://github.com/hjwylde/git-fmt/issues/54))
+
+*Revisions*
+
+* Added quoting to the command variables during substitution. ([#59](https://github.com/hjwylde/git-fmt/issues/59))
+* Changed parallelisation to use the number of capabilities (and processors) for the number of
+  threads by default. ([#54](https://github.com/hjwylde/git-fmt/issues/54))
+
+#### v0.2.1.2
+
+*Revisions*
+
+* Fixed a bug causing prettifying to fail across filesystem boundaries. ([#72](https://github.com/hjwylde/git-fmt/issues/72))
+
+#### v0.2.1.1
+
+*Revisions*
+
+* Fixed a bug where passing arguments would only work when running in the git directory. ([#57](https://github.com/hjwylde/git-fmt/issues/57))
+
+#### v0.2.1.0
+
+*Minor*
+
+* Added default use of stdin and stdout when variables not specified in a program command. ([#49](https://github.com/hjwylde/git-fmt/issues/49))
+
+#### v0.2.0.2
+
+*Revisions*
+
+* Fixed a bug causing prettifying to fail across filesystem boundaries. ([#72](https://github.com/hjwylde/git-fmt/issues/72))
+
+#### v0.2.0.1
+
+*Revisions*
+
+* Fixed a bug where passing arguments would only work when running in the git directory. ([#57](https://github.com/hjwylde/git-fmt/issues/57))
+
+#### v0.2.0.0
+
+*Major*
+
+* Removed `--list-ugly` and `--dry-run` options. ([#29](https://github.com/hjwylde/git-fmt/issues/29))
+* Restricted use of `--quiet` and `--verbose` at the same time. ([#35](https://github.com/hjwylde/git-fmt/issues/35))
+* Updated project structure to delegate pretty printing to other binaries. ([#38](https://github.com/hjwylde/git-fmt/issues/38))
+* Added a `.omniyaml.yaml` config file. ([#38](https://github.com/hjwylde/git-fmt/issues/38))
+
+*Minor*
+
+* Added `--mode` option (either `normal` or `dry-run`). ([#29](https://github.com/hjwylde/git-fmt/issues/29))
+* Added `--null` option (use the null terminator as the delimiter for inputs). ([#27](https://github.com/hjwylde/git-fmt/issues/27))
+* Added support for directories as arguments (directories include all files within recursively). ([#30](https://github.com/hjwylde/git-fmt/issues/30))
+* Added parallelisation. ([#48](https://github.com/hjwylde/git-fmt/issues/48))
+
+*Revisions*
+
+* Added a warning for when files aren't found. ([#29](https://github.com/hjwylde/git-fmt/issues/29))
+* Updated internal use of `git ls-files` to use the null terminator option. ([#27](https://github.com/hjwylde/git-fmt/issues/27))
+* Fixed debug log messages to have timestamp and log level on all lines. ([#33](https://github.com/hjwylde/git-fmt/issues/33))
+* Tidied up error messages from git. ([#40](https://github.com/hjwylde/git-fmt/issues/40))
+* Tidied up error messages from parsing the config. ([#43](https://github.com/hjwylde/git-fmt/issues/43))
+
+#### v0.1.0.3
+
+*Revisions*
+
+* Fixed a bug where passing arguments would only work when running in the git directory. ([#57](https://github.com/hjwylde/git-fmt/issues/57))
+
+#### v0.1.0.2
+
+*Revisions*
+
+* Fixed a bug where UTF-8 characters in strings weren't printed properly. ([#26](https://github.com/hjwylde/git-fmt/issues/26))
+
+#### v0.1.0.1
+
+*Revisions*
+
+* Fixed a bug where integers were printed as rationals. ([#25](https://github.com/hjwylde/git-fmt/issues/25))
+
+#### v0.1.0.0
+
+This is first release of the `git-fmt` binary!
+It provides a basic syntax for formatting files in a git repository.
+Currently only JSON is supported.
+
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,119 @@
+# git-fmt
+
+[![Project Status: Wip - Initial development is in progress, but there has not yet been a stable, usable release suitable for the public.](http://www.repostatus.org/badges/1.0.0/wip.svg)](http://www.repostatus.org/#wip)
+[![Build Status](https://travis-ci.org/hjwylde/git-fmt.svg?branch=master)](https://travis-ci.org/hjwylde/git-fmt)
+[![Release](https://img.shields.io/github/release/hjwylde/git-fmt.svg)](https://github.com/hjwylde/git-fmt/releases/latest)
+[![git-fmt on Stackage LTS](http://stackage.org/package/git-fmt/badge/lts)](http://stackage.org/lts/package/git-fmt)
+[![git-fmt on Stackage Nightly](http://stackage.org/package/git-fmt/badge/nightly)](http://stackage.org/nightly/package/git-fmt)
+
+(Side note: the formatting component of this project will eventually be split out and named omnifmt.)
+
+git-fmt was created to make prettifying code easy.
+It adds a custom (easy to use) command to Git that formats code through external pretty-printers.
+
+Formatted code is:
+
+* Easier to write: never worry about minor formatting concerns while hacking away.
+* Easier to read: when all code looks the same you need not mentally convert others' formatting
+  style into something you can understand.
+* Easier to maintain: mechanical changes to the source don't cause unrelated changes to the file's
+  formatting; diffs show only the real changes.
+* Uncontroversial: never have a debate about spacing or brace position ever again.
+
+(Bullet points taken from https://blog.golang.org/go-fmt-your-code.)
+
+### Installing
+
+Installing git-fmt is easiest done using either
+    [stack](https://github.com/commercialhaskell/stack) (recommended) or
+    [Cabal](https://github.com/haskell/cabal).
+
+**Using stack:**
+
+```bash
+stack install git-fmt
+export PATH=$PATH:~/.local/bin
+```
+
+**Using Cabal:**
+
+```bash
+cabal-install git-fmt
+export PATH=$PATH:~/.cabal/bin
+```
+
+### Usage
+
+The git-fmt binary provides an interface for selecting files and piping them through external
+    pretty-printers.
+It supports both prettifying the files immediately and performing dry-runs to see which files are
+    ugly.
+
+**The basics:**
+
+git-fmt operates only on tracked git files (thus it implicitly respects the '.gitignore' file).
+By default it operates on files in the index (i.e., `--operate-on head`).
+It is possible to operate on all tracked files (`--operate-on-tracked`) or on a specific reference
+    (`--operate-on REF`).
+The `REF` argument is passed directly into `git diff REF --name-only`, so you can even play with
+    ranges such as `master...`.
+
+Passing arguments to git-fmt will narrow down the operation files.
+For example, `git fmt --operate-on-tracked src/` will format all tracked files under 'src/' and
+    `git fmt --operate-on head src/` will format all files in the index under 'src/'.
+
+**Modes:**
+
+git-fmt can run in three different modes, *normal*, *dry-run* and *diff*.
+
+Normal mode writes to (prettifies) all ugly files immediately and outputs the prettified file paths
+    to *stdout*.
+
+Dry-run mode outputs the ugly file paths to stdout.
+
+Diff mode outputs a diff of all ugly files with their prettified version.
+By default the diff isn't paged, so to get output similar to `git diff` or `git log` it is
+    recommended to use `[-p|--paginate]` with this mode, e.g., `git -p fmt -m diff`.
+
+**NB:** it isn't possible to pipe the diff into `git apply` due to the destination file path
+    header.
+
+#### Configuration
+
+Configuration is done via an '.omnifmt.yaml' file in the git repository.
+The file contains a list of *programs* that link *extensions* to a prettifying *command*, e.g.,
+```yaml
+haskell:
+    extensions: ["hs", "lhs"]
+    command:    "stylish-haskell {{input}} > {{output}}"
+
+javascript:
+    extensions: ["js"]
+    command:    "js-beautify -f {{input}}"
+
+json:
+    extensions: ["json"]
+    command:    "json_pp"
+
+ruby:
+    extensions: ["rb"]
+    command:    "ruby-beautify"
+```
+
+Each command declares how to read the *input file* and how to write to the *output file*.
+If the input variable is omitted, the file contents are fed to the command through *stdin*.
+Likewise if the output variable is omitted, the pretty contents are read from stdout.
+The output file is used to compare whether the original was pretty or ugly before writing to it.
+
+The extensions field is pretty self explanatory, but if you use the same extension more than once
+    then precedence goes to the program defined first.
+
+#### Examples
+
+See the [docs/example-configs/](https://github.com/hjwylde/git-fmt/tree/master/docs/example-configs/)
+    directory for some common pretty-printers and their corresponding omnifmt config (pull requests
+    are welcome for adding more).
+Just don't forget to actually call the config file .omnifmt.yaml!
+
+**NB:** I haven't tested them fully, be careful in case one is buggy.
+
diff --git a/git-fmt.cabal b/git-fmt.cabal
--- a/git-fmt.cabal
+++ b/git-fmt.cabal
@@ -1,5 +1,5 @@
 name:           git-fmt
-version:        0.3.1.1
+version:        0.3.1.2
 
 author:         Henry J. Wylde
 maintainer:     public@hjwylde.com
@@ -16,6 +16,8 @@
 cabal-version:  >= 1.10
 category:       Development
 build-type:     Simple
+
+extra-source-files: CHANGELOG.md README.md
 
 source-repository head
     type:       git
diff --git a/src/Omnifmt/Pipes.hs b/src/Omnifmt/Pipes.hs
--- a/src/Omnifmt/Pipes.hs
+++ b/src/Omnifmt/Pipes.hs
@@ -38,6 +38,8 @@
 import qualified Data.Text        as T
 import           Data.Tuple.Extra (fst3)
 
+import GHC.IO.Exception (IOErrorType (..))
+
 import Omnifmt.Config
 import Omnifmt.Process
 
@@ -47,6 +49,7 @@
 import System.Directory.Extra
 import System.Exit
 import System.FilePath
+import System.IO.Error
 
 -- | A status for a file going through the omnifmt pipeline.
 data Status = Unknown       -- ^ The file has not been processed.
@@ -135,7 +138,11 @@
 --   This function updates the status to 'Prettified'.
 commit :: MonadIO m => Pipe (Status, FilePath, FilePath) (Status, FilePath, FilePath) m ()
 commit = select [Ugly] $ \(_, uglyFilePath, prettyFilePath) -> do
-    liftIO $ renameFile prettyFilePath uglyFilePath
+    -- Try move the file, but if it's across a filesystem boundary then we may need to copy instead
+    liftIO $ renameFile prettyFilePath uglyFilePath `catchIOError` \e ->
+        if ioeGetErrorType e == UnsupportedOperation
+            then copyFile prettyFilePath uglyFilePath >> removeFile prettyFilePath
+            else ioError e
 
     return (Prettified, uglyFilePath, prettyFilePath)
 
