         // Get the contents using `cat-file`.
         //
         // FIXME: We need to get the raw bytes back, not a String.
-        let output = try Git.runPopen([Git.tool, "-C", path.asString, "cat-file", "-p", hash.bytes.asString!])
+        let output = try runPopen([Git.tool, "-C", path.asString, "cat-file", "-p", hash.bytes.asString!])
         return ByteString(encodingAsUTF8: output)
+    }
+
+    /// Runs the command in the serial queue.
+    private func runCommandQuietly(_ command: [String]) throws {
+        try queue.sync {
+            try Git.runCommandQuietly(command)
+        }
+    }
+
+    /// Executes popen in the serial queue.
+    private func runPopen(_ command: [String]) throws -> String {
+        return try queue.sync {
+            return try Git.runPopen(command)
+        }
     }
 }
 

        } else {
            specifier = treeish
        }
        let response = try Git.runPopen([Git.tool, "-C", path.asString, "rev-parse", "--verify", specifier]).chomp()
        if let hash = Hash(response) {
            return hash
        } else {

    /// Read a tree object.
    func read(tree hash: Hash) throws -> Tree {
        // Get the contents using `ls-tree`.
        let treeInfo = try runPopen([Git.tool, "-C", path.asString, "ls-tree", hash.bytes.asString!])

        var contents: [Tree.Entry] = []
        for line in treeInfo.components(separatedBy: "\n") {
