diff --git a/Setup.lhs b/Setup.lhs
--- a/Setup.lhs
+++ b/Setup.lhs
@@ -95,6 +95,16 @@
                              | otherwise -> fail $ "Unknown test: " ++ x
                          | w <- if null args then ["tests"] else args ],
 
+  -- Remove the temporary directories created by "cabal test".
+  postClean = \ _ _ _ _ -> mapM_ rmRf
+              ["tests-darcs-2.dir",
+               "tests-hashed.dir",
+               "tests-old-fashioned-inventory.dir",
+               "bugs-darcs-2.dir",
+               "bugs-hashed.dir",
+               "bugs-old-fashioned-inventory.dir",
+               "tests_network-.dir"],
+
   sDistHook = \ pkg lbi hooks flags -> do
     let pkgVer = packageVersion pkg
         verb = fromFlag $ sDistVerbosity flags
diff --git a/darcs.cabal b/darcs.cabal
--- a/darcs.cabal
+++ b/darcs.cabal
@@ -1,5 +1,5 @@
 Name:           darcs
-version:        2.2.0
+version:        2.2.1
 License:        GPL
 License-file:   COPYING
 Author:         David Roundy <droundy@darcs.net>, <darcs-users@darcs.net>
@@ -299,14 +299,14 @@
     build-depends: base < 3
 
   -- We need optimizations, regardless of what Hackage says
-  ghc-options:      -Wall -O2 -funbox-strict-fields -threaded
+  ghc-options:      -Wall -O2 -funbox-strict-fields
   ghc-prof-options: -prof -auto-all
 
   if flag(curl)
     extra-libraries:   curl
     cpp-options:       -DHAVE_CURL
     c-sources:         src/hscurl.c
-    cc-options:        -DHAVE_CURL -DPACKAGE_VERSION="2.2.0"
+    cc-options:        -DHAVE_CURL -DPACKAGE_VERSION="2.2.1"
 
     if flag(curl-pipelining)
       -- curl 7.19.1 has bug-free pipelining
@@ -318,14 +318,14 @@
     if flag(libwww)
       build-tools:    libwww-config >= 5.0
       c-sources:      src/hslibwww.c
-      cc-options:     -DHAVE_LIBWWW -DPACKAGE_VERSION="2.2.0"
+      cc-options:     -DHAVE_LIBWWW -DPACKAGE_VERSION="2.2.1"
       cpp-options:    -DHAVE_LIBWWW
       x-have-libwww:
     else
       if flag(http)
         build-depends:    network == 2.2.*,
                           HTTP    >= 3000.0 && < 3001.1
-        cpp-options:      -DHAVE_HTTP -DPACKAGE_VERSION="2.2.0"
+        cpp-options:      -DHAVE_HTTP -DPACKAGE_VERSION="2.2.1"
         x-have-http:
 
   if flag(external-bytestring)
@@ -437,15 +437,11 @@
   else
     build-depends: base < 3
 
-  -- We need optimizations, regardless of what Hackage says
-  ghc-options:      -Wall -O2 -funbox-strict-fields -threaded
-  ghc-prof-options: -prof -auto-all
-
   if flag(curl)
     extra-libraries:   curl
     cpp-options:       -DHAVE_CURL
     c-sources:         src/hscurl.c
-    cc-options:        -DHAVE_CURL -DPACKAGE_VERSION="2.2.0"
+    cc-options:        -DHAVE_CURL -DPACKAGE_VERSION="2.2.1"
 
     if flag(curl-pipelining)
       -- curl 7.19.1 has bug-free pipelining
@@ -457,14 +453,14 @@
     if flag(libwww)
       build-tools:    libwww-config >= 5.0
       c-sources:      src/hslibwww.c
-      cc-options:     -DHAVE_LIBWWW -DPACKAGE_VERSION="2.2.0"
+      cc-options:     -DHAVE_LIBWWW -DPACKAGE_VERSION="2.2.1"
       cpp-options:    -DHAVE_LIBWWW
       x-have-libwww:
     else
       if flag(http)
         build-depends:    network == 2.2.*,
                           HTTP    >= 3000.0 && < 3001.1
-        cpp-options:      -DHAVE_HTTP -DPACKAGE_VERSION="2.2.0"
+        cpp-options:      -DHAVE_HTTP -DPACKAGE_VERSION="2.2.1"
         x-have-http:
 
   if flag(external-bytestring)
diff --git a/release/distributed-context b/release/distributed-context
--- a/release/distributed-context
+++ b/release/distributed-context
@@ -1,1 +1,1 @@
-Just "\nContext:\n\n[TAG 2.2.0\nPetr Rockai <me@mornfall.net>**20090115150916] \n"
+Just "\nContext:\n\n[TAG 2.2.1\nPetr Rockai <me@mornfall.net>**20090214071133\n Ignore-this: f4a1d192bc93490e498eed18c1165d8d\n] \n"
diff --git a/src/Darcs/Commands/Annotate.lhs b/src/Darcs/Commands/Annotate.lhs
--- a/src/Darcs/Commands/Annotate.lhs
+++ b/src/Darcs/Commands/Annotate.lhs
@@ -161,7 +161,7 @@
   pinfo <- if have_nonrange_match opts
            then return $ patch2patchinfo `unseal2` (match_patch opts r)
            else case mapRL info $ concatRL r of
-                [] -> fail "Annotate doesn't yet work right on empty repositories."
+                [] -> fail "Annotate does not currently work correctly on empty repositories."
                 (x:_) -> return x
   pop <- getRepoPopVersion "." pinfo
 
diff --git a/src/Darcs/Commands/Diff.lhs b/src/Darcs/Commands/Diff.lhs
--- a/src/Darcs/Commands/Diff.lhs
+++ b/src/Darcs/Commands/Diff.lhs
@@ -54,7 +54,7 @@
 import Darcs.External ( execPipeIgnoreError, clonePaths )
 import Darcs.Lock ( withTempDir )
 import Darcs.Sealed ( unsafeUnseal )
-import Printer ( Doc, putDocLn, vcat, empty, ($$) )
+import Printer ( Doc, putDoc, vcat, empty, ($$) )
 #include "impossible.h"
 \end{code}
 
@@ -217,7 +217,7 @@
                                (takeFileName (toFilePath odir) ++ "/" ++ toFilePath f)
                                (takeFileName (toFilePath ndir) ++ "/" ++ toFilePath f)) fs
     morepatches <- read_repo repository
-    putDocLn $ changelog (get_diff_info opts morepatches)
+    putDoc $ changelog (get_diff_info opts morepatches)
             $$ thediff
     where rundiff :: String -> String -> IO Doc
           rundiff f1 f2 =
diff --git a/src/Darcs/Commands/SetPref.lhs b/src/Darcs/Commands/SetPref.lhs
--- a/src/Darcs/Commands/SetPref.lhs
+++ b/src/Darcs/Commands/SetPref.lhs
@@ -43,7 +43,11 @@
 
 valid_prefs :: [String]
 valid_prefs = map fst valid_pref_data
+\end{code}
 
+\options{setpref}
+\haskell{setpref_description}
+\begin{code}
 setpref_description :: String
 setpref_description = "Set the value of a preference (" ++ ps ++ ")."
     where ps = iter valid_prefs
diff --git a/src/Darcs/External.hs b/src/Darcs/External.hs
--- a/src/Darcs/External.hs
+++ b/src/Darcs/External.hs
@@ -105,6 +105,9 @@
              where next = f ++ suffix
                    suffix = "-darcs-backup" ++ show i
 
+-- | @fetchFile fileOrUrl cache@ returns the content of its argument
+-- (either a file or an URL). If it has to download an url, then it
+-- will use a cache as required by its second argument.
 fetchFilePS :: String -> Cachable -> IO B.ByteString
 fetchFilePS fou _ | is_file fou = B.readFile fou
 fetchFilePS fou cache = withTemp $ \t -> do copyFileOrUrl [] fou t cache
diff --git a/src/Darcs/Patch/Match.lhs b/src/Darcs/Patch/Match.lhs
--- a/src/Darcs/Patch/Match.lhs
+++ b/src/Darcs/Patch/Match.lhs
@@ -241,39 +241,59 @@
      q <- quoted
      return $ matcher q
 
+-- FIXME: would this be better defined in Darcs.Commands.Help?
+-- | The string that is emitted when the user runs @darcs help --match@.
 helpOnMatchers :: String
-helpOnMatchers =
-  let blurb :: (String, String, [String], String -> MatchFun Patch) -> String
-      blurb (key, help, examples, _) =
-        "'" ++ key ++ "' " ++ help ++
-        ", e.g.:\n" ++ (unlines $ map (mkExample key) examples)
-      mkExample key x =
-        "  darcs annotate --summary --match '" ++ key ++ " " ++ x ++ "'"
-  in "Matching patches:\n"
-     ++ (unlines $ map blurb primitiveMatchers) ++ "\n"
-     ++ "You can also use logical operators 'and', '&&', 'or', '||', 'not', '!'"
-     ++ " to combine match expressions, as well as parentheses for grouping. "
-     ++ " For more details on matching, see the manual."
+helpOnMatchers = unlines $
+  ["Selecting Patches:",
+   "",
+   "The --patches option yields patches with names matching an `extended'",
+   "regular expression.  See regex(7) for details.  The --matches option",
+   "yields patches that match a logical (Boolean) expression: one or more",
+   "primitive expressions combined by grouping (parentheses) and the",
+   "complement (not), conjunction (and) and disjunction (or) operators.",
+   "The C notation for logic operators (!, && and ||) can also be used.",
+   "",
+   "The following primitive Boolean expressions are supported:"]
+  ++ keywords
+  ++ ["", "Here are some examples:"]
+  ++ examples
+  where -- This type signature exists to appease GHC.
+        ps :: [(String, String, [String], String -> MatchFun Patch)]
+        ps = primitiveMatchers
+        keywords = [showKeyword k d | (k,d,_,_) <- ps]
+        examples = [showExample k e | (k,_,es,_) <- ps, e <- es]
+        showKeyword keyword description =
+            -- FIXME: it would be nice to have a variable name here:
+            -- "author REGEX - match against author (email address)"
+            -- or "exact STRING - match against exact patch name".
+            "  " ++ keyword ++ " - " ++ description ++ "."
+        showExample keyword example =
+            -- FIXME: this string is long, and its not a use case I've
+            -- ever seen in practice.  Can we use something else,
+            -- like "darcs changes --matches"? --twb, 2008-12-28
+            "  darcs annotate --summary --match "
+            ++ "'" ++ keyword ++ " " ++ example ++ "'"
 
 primitiveMatchers :: Patchy p => [(String, String, [String], String -> MatchFun p)]
 primitiveMatchers =
- [ ("exact", "checks a literal string against the patch name"
-           , ["\"my most excellent patch\""]
+ [ ("exact", "check a literal string against the patch name"
+           , ["\"Resolve issue17: use dynamic memory allocation.\""]
            , exactmatch )
- , ("name", "checks a regular expression against the patch name"
-          , ["[eE]xcellent"]
+ , ("name", "check a regular expression against the patch name"
+          , ["issue17", "\"^[Rr]esolve issue17\\>\""]
           , mymatch )
- , ("author", "checks a regular expression against the author name"
-            , ["foo@bar"]
+ , ("author", "check a regular expression against the author name"
+            , ["\"David Roundy\"", "droundy", "droundy@darcs.net"]
             , authormatch )
- , ("hash",  "matches the darcs hash for a patch"
+ , ("hash",  "match the darcs hash for a patch"
           ,  ["20040403105958-53a90-c719567e92c3b0ab9eddd5290b705712b8b918ef"]
           ,  hashmatch )
- , ("date", "matches the patch date"
-          , ["\"tea time yesterday\"", "\"2006-04-02 22:41\""]
+ , ("date", "match the patch date"
+          , ["\"2006-04-02 22:41\"", "\"tea time yesterday\""]
           , datematch )
- , ("touch", "matches file paths for a patch"
-          , ["\"foo|bar|splotz.*(c|h)\"", "\"some/thing/\""]
+ , ("touch", "match file paths for a patch"
+          , ["src/foo.c", "src/", "\"src/*.(c|h)\""]
           , touchmatch ) ]
 
 parens :: CharParser st (MatchFun p)
diff --git a/src/Darcs/Patch/Prim.lhs b/src/Darcs/Patch/Prim.lhs
--- a/src/Darcs/Patch/Prim.lhs
+++ b/src/Darcs/Patch/Prim.lhs
@@ -116,14 +116,12 @@
 is_identity (Move old new) | old == new = unsafeCoerce# IsEq
 is_identity Identity = IsEq
 is_identity _ = NotEq
-\end{code}
 
-%FIXME: The following code needs to be moved.  It is a function
-%``is\_similar'' which tells you if two patches are in the same category
-%human-wise.  Currently it just returns true if they are filepatches on the
-%same file.
+-- FIXME: The following code needs to be moved.
 
-\begin{code}
+-- | Tells you if two patches are in the same category, human-wise.
+-- Currently just returns true if they are filepatches on the same
+-- file.
 is_similar :: Prim C(x y) -> Prim C(a b) -> Bool
 is_similar (FP f _) (FP f' _) = f == f'
 is_similar (DP f _) (DP f' _) = f == f'
diff --git a/src/Darcs/Repository/Cache.hs b/src/Darcs/Repository/Cache.hs
--- a/src/Darcs/Repository/Cache.hs
+++ b/src/Darcs/Repository/Cache.hs
@@ -71,7 +71,7 @@
 repo2cache :: String -> Cache
 repo2cache r = Ca [Cache Repo NotWritable r]
 
--- This function computes the cache hash (i.e. filename) of a packed string.
+-- | 'cacheHash' computes the cache hash (i.e. filename) of a packed string.
 cacheHash :: B.ByteString -> String
 cacheHash ps = case show (B.length ps) of
                  x | l > 10 -> sha256sum ps
@@ -116,11 +116,16 @@
 writable (Cache _ NotWritable _) = False
 writable (Cache _ Writable _) = True
 
+-- | @hashedFilePath cachelocation subdir hash@ returns the physical filename of
+-- hash @hash@ in the @subdir@ section of @cachelocation@.
 hashedFilePath :: CacheLoc -> HashedDir -> String -> String
 hashedFilePath (Cache Directory _ d) s f = d ++ "/" ++ (hashedDir s) ++ "/" ++ f
 hashedFilePath (Cache Repo _ r) s f =
     r ++ "/"++darcsdir++"/" ++ (hashedDir s) ++ "/" ++ f
 
+-- | @peekInCache cache subdir hash@ tells whether @cache@ and
+-- contains an object with hash @hash@ in a writable position.
+-- Florent: why do we want it to be in a writable position?
 peekInCache :: Cache -> HashedDir -> String -> IO Bool
 peekInCache (Ca cache) subdir f = cacheHasIt cache `catchall` return False
     where cacheHasIt [] = return False
@@ -130,8 +135,9 @@
                                                    else cacheHasIt cs
           fn c = hashedFilePath c subdir f
 
--- |Note that the file is likely to be useful soon: pipelined downloads will
--- add it to the (low-priority) queue, for the rest it is a noop.
+-- | @speculateFileUsingCache cache subdirectory name@ takes note that
+-- the file @name@ is likely to be useful soon: pipelined downloads
+-- will add it to the (low-priority) queue, for the rest it is a noop.
 speculateFileUsingCache :: Cache -> HashedDir -> String -> IO ()
 speculateFileUsingCache c sd h = do debugMessage $ "Speculating on "++h
                                     copyFileUsingCache OnlySpeculate c sd h
@@ -220,10 +226,16 @@
     createDirectoryIfMissing True (d ++ "/" ++ (hashedDir subdir))
 createCache _ _ = return ()
 
+-- | @write compression filename content@ writes @content@ to the file @filename@ according
+-- to the policy given by @compression@.
 write :: Compression -> String -> B.ByteString -> IO ()
 write NoCompression = writeAtomicFilePS
 write GzipCompression = gzWriteAtomicFilePS
 
+-- | @writeFileUsingCache cache compression subdir contents@ write the string @contents@ to
+-- the directory subdir, except if it is already in the cache, in which case it is a noop.
+-- Warning (?) this means that in case of a hash collision, writing using writeFileUsingCache is
+-- a noop. The returned value is the filename that was given to the string.
 writeFileUsingCache :: Cache -> Compression -> HashedDir -> B.ByteString -> IO String
 writeFileUsingCache (Ca cache) compr subdir ps =
     (fetchFileUsingCachePrivate LocalOnly (Ca cache) subdir hash >> return hash) `catchall`
diff --git a/src/Darcs/Repository/Format.hs b/src/Darcs/Repository/Format.hs
--- a/src/Darcs/Repository/Format.hs
+++ b/src/Darcs/Repository/Format.hs
@@ -32,11 +32,19 @@
 #include "impossible.h"
 
 data RepoProperty = Darcs1_0 | Darcs2 | HashedInventory
+
+-- | @RepoFormat@ is the representation of the format of a
+-- repository. Each sublist corresponds to a line in the format
+-- file. Each line is decomposed into words.
 newtype RepoFormat = RF [[B.ByteString]] deriving ( Show )
 
+-- | The file where the format information should be.
 df :: FilePath
 df = darcsdir++"/format"
 
+-- | @identifyRepoFormat URL@ identifies the format of the repository
+-- at the given address. Return @Left reason@ if it fails, where
+-- @reason@ explains why we weren't able to identify the format.
 identifyRepoFormat :: String -> IO (Either String RepoFormat)
 identifyRepoFormat repo =
  do let k = "Identifying repository "++repo
@@ -57,7 +65,7 @@
           doesRemoteFileExist x = (fmap Right) (drfe x) `catchNonSignal`
                                   (\e -> return (Left (prettyException e)))
 
-
+-- | @writeRepoFormat@ writes the repo format to the given file.
 writeRepoFormat :: RepoFormat -> FilePath -> IO ()
 writeRepoFormat (RF rf) loc = writeBinFile loc $ unlines $
                               map (BC.unpack . BU.intercalate (BC.singleton '|')) rf
@@ -66,6 +74,7 @@
 parse_repo_format ps =
     RF $ map (BC.split '|') $ filter (not . B.null) $ linesPS ps
 
+-- | The repo format we assume if we do not find a format file.
 default_repo_format :: RepoFormat
 default_repo_format = RF [[rp2ps Darcs1_0]]
 
@@ -81,7 +90,8 @@
                    then []
                    else [[rp2ps Darcs2]]
 
--- Nothing means we can write
+-- | @write_problem from@ tells if we can write to a repo in format @form@.
+-- it returns @Nothing@ if there's no problem writing to such a repository.
 write_problem :: RepoFormat -> Maybe String
 write_problem rf | isJust $ read_problem rf = read_problem rf
 write_problem (RF ks) = unlines `fmap` justsOrNothing (map wp ks)
@@ -90,12 +100,19 @@
           wp x = Just $ unwords $ "Can't write repository format: " :
                  map BC.unpack (filter (not . is_known) x)
 
+
+-- | @write_problem from@ tells if we can read and write to a repo in
+-- format @form@.  it returns @Nothing@ if there's no problem reading
+-- and writing to such a repository.
 readfrom_and_writeto_problem :: RepoFormat -> RepoFormat -> Maybe String
 readfrom_and_writeto_problem inrf outrf
     | format_has Darcs2 inrf /= format_has Darcs2 outrf
         = Just "Cannot mix darcs-2 repositories with older formats" 
     | otherwise = msum [read_problem inrf, write_problem outrf]
 
+
+-- | @read_problem from@ tells if we can write to a repo in format @form@.
+-- it returns @Nothing@ if there's no problem reading from such a repository.
 read_problem :: RepoFormat -> Maybe String
 read_problem rf | format_has Darcs1_0 rf && format_has Darcs2 rf
                     = Just "Invalid repositoryformat:  format 2 is incompatible with format 1"
@@ -105,9 +122,13 @@
           rp x = Just $ unwords $
                  "Can't understand repository format:" : map BC.unpack x
 
+
+-- | Does this version of darcs know how to handle this property?
 is_known :: B.ByteString -> Bool
 is_known p = p `elem` map rp2ps known_properties
 
+-- | This is the list of properties which this version of darcs knows
+-- how to handle.
 known_properties :: [RepoProperty]
 known_properties = [Darcs1_0, Darcs2, HashedInventory]
 
diff --git a/src/Darcs/Repository/HashedIO.hs b/src/Darcs/Repository/HashedIO.hs
--- a/src/Darcs/Repository/HashedIO.hs
+++ b/src/Darcs/Repository/HashedIO.hs
@@ -56,6 +56,8 @@
 
 import SHA1 ( sha1PS )
 
+-- | @readHashFile c subdir hash@ reads the file with hash @hash@ in dir subdir,
+-- fetching it from 'Cache' @c@ if needed.
 readHashFile :: Cache -> HashedDir -> String -> IO (String,B.ByteString)
 readHashFile c subdir hash =
     do debugMessage $ "Reading hash file "++hash++" from "++(hashedDir subdir)++"/"
@@ -233,6 +235,8 @@
 
 data ObjType = F | D deriving Eq
 
+-- | @geta objtype name stuff@ tries to get an object of type @objtype@ named @name@
+-- in @stuff@.
 geta :: ObjType -> FileName -> [(ObjType, FileName, String)] -> Maybe String
 geta o f c = do (o',h) <- getany f c
                 if o == o' then Just h else Nothing
@@ -327,7 +331,7 @@
 grab _ (Slurpy _ (SlurpFile _ _)) = Nothing
 grab fn (Slurpy _ (SlurpDir _ ss)) = fmap (Slurpy fn) $ Map.lookup fn ss
 
--- |Update timestamps on pristine files to match those in the working directory
+-- | Update timestamps on pristine files to match those in the working directory
 -- (which is passed to this function in form of a Slurpy). It needed for the
 -- mtime-based unsafeDiff optimisation to work efficiently.
 syncHashedPristine :: Cache -> Slurpy -> String -> IO ()
@@ -384,7 +388,7 @@
                                     lift $ writeAtomicFilePS (fn2fp f) ps
                    Nothing -> return ()
 
--- Seems to list all hashes reachable from "root".
+-- | Seems to list all hashes reachable from "root".
 listHashedContents :: String -> Cache -> String -> IO [String]
 listHashedContents k c root =
     do beginTedious k
diff --git a/src/Darcs/Repository/Motd.lhs b/src/Darcs/Repository/Motd.lhs
--- a/src/Darcs/Repository/Motd.lhs
+++ b/src/Darcs/Repository/Motd.lhs
@@ -19,7 +19,7 @@
 \begin{code}
 module Darcs.Repository.Motd (get_motd, show_motd) where
 import Control.Monad ( unless )
-import Darcs.Flags ( DarcsFlag( Quiet ) )
+import Darcs.Flags ( DarcsFlag( Quiet, XMLOutput ) )
 import Darcs.External ( fetchFilePS, Cachable(..) )
 import Darcs.Global ( darcsdir )
 import qualified Data.ByteString as B (null, hPut, empty, ByteString)
@@ -39,9 +39,9 @@
                      `catchall` return B.empty
 
 -- | Display the message of the day for a given repository,
---   unless the 'Quiet' flag is passed in
+--   unless either the 'XMLOutput' or the 'Quiet' flags are passed in
 show_motd :: [DarcsFlag] -> String -> IO ()
-show_motd opts repo = unless (Quiet `elem` opts) $ do
+show_motd opts repo = unless (Quiet `elem` opts || XMLOutput `elem` opts) $ do
   motd <- get_motd repo
   unless (B.null motd)
       $ do B.hPut stdout motd
diff --git a/src/Exec.hs b/src/Exec.hs
--- a/src/Exec.hs
+++ b/src/Exec.hs
@@ -35,7 +35,6 @@
 import System.IO	( stdin )
 #else
 import Control.Exception ( catchJust, Exception(IOException) )
--- WARNING: isInfixOf is not present in ghc 6.4.2!
 import Data.List ( isInfixOf )
 #endif
 
diff --git a/src/best_practices.tex b/src/best_practices.tex
--- a/src/best_practices.tex
+++ b/src/best_practices.tex
@@ -3,8 +3,6 @@
 
 \chapter{Best practices}
 
-\section{Introduction}
-
 This chapter is intended to review various scenarios and describe in each
 case effective ways of using darcs.  There is no one ``best practice'', and
 darcs is a sufficiently low-level tool that there are many high-level ways
diff --git a/src/building_darcs.tex b/src/building_darcs.tex
--- a/src/building_darcs.tex
+++ b/src/building_darcs.tex
@@ -78,34 +78,34 @@
 If you get darcs from a tarball, the procedure (after unpacking the tarball
 itself) is as follows:
 \begin{verbatim}
-% ./configure
-% make
+$ ./configure
+$ make
 # Optional, but recommended
-% make test
-% make install
+$ make test
+$ make install
 \end{verbatim}
 
 There are options to configure that you may want to check out with
 \begin{verbatim}
-% ./configure --help
+$ ./configure --help
 \end{verbatim}
 
 If your header files are installed in a non-standard location, you may need
 to define the \verb!CFLAGS! and \verb!CPPFLAGS! environment variables to
 include the path to the headers.  e.g. on NetBSD, you may need to run
 \begin{verbatim}
-% CFLAGS=-I/usr/pkg/include CPPFLAGS=-I/usr/pkg/include ./configure
+$ CFLAGS=-I/usr/pkg/include CPPFLAGS=-I/usr/pkg/include ./configure
 \end{verbatim}
 
 \section{Building darcs from the repository}
 To build the latest darcs from its repository, you will first need a
 working copy of Darcs 2. You can get darcs using:
 \begin{verbatim}
-% darcs get -v http://darcs.net/
+$ darcs get -v http://darcs.net/
 \end{verbatim}
 and once you have the darcs repository you can bring it up to date with a
 \begin{verbatim}
-% darcs pull
+$ darcs pull
 \end{verbatim}
 
 The repository doesn't hold automatically generated files, which include
@@ -121,10 +121,10 @@
 
 If you want to create readable documentation you'll need to have latex installed.
 \begin{verbatim}
-% autoconf
-% ./configure
-% make
-% make install
+$ autoconf
+$ ./configure
+$ make
+$ make install
 \end{verbatim}
 
 If you want to tweak the configure options, you'll need to run {\tt
@@ -139,18 +139,18 @@
 
 To do so, just record your changes (which you made in the darcs repository)
 \begin{verbatim}
-% darcs record --no-test
+$ darcs record --no-test
 \end{verbatim}
 making sure to give the patch a nice descriptive name.  The
 \verb!--no-test! options keeps darcs from trying to run the unit tests,
 which can be rather time-consuming.  Then you can send the patch to the
 darcs-devel mailing list by email by
 \begin{verbatim}
-% darcs send
+$ darcs send
 \end{verbatim}
 If you are using darcs 2.0.0 or earlier, please use
 \begin{verbatim}
-% darcs send -u
+$ darcs send -u
 \end{verbatim}
 instead.
 The darcs repository stores the email address to which patches should be
diff --git a/src/preproc.hs b/src/preproc.hs
--- a/src/preproc.hs
+++ b/src/preproc.hs
@@ -37,9 +37,7 @@
     do rest <- preproc ss
        ah <- am_html
        if ah then return $ "\\usepackage{html}" : rest
-             else return $ "\\newcommand{\\htmladdnormallink}[2]{#1}" :
-                  "\\newcommand{\\htmladdnormallinkfoot}[2]{#1\\footnotetext{\\tt #2}}"
-                  : rest
+             else return $ "\\usepackage{hyperref}" : rest
 preproc ("\\begin{code}":ss) = ignore ss
 preproc ("\\begin{options}":ss) =
     do rest <- preproc ss
diff --git a/tests/optimize_relink.sh b/tests/optimize_relink.sh
--- a/tests/optimize_relink.sh
+++ b/tests/optimize_relink.sh
@@ -34,7 +34,7 @@
 echo "hi" > z1/foo
 mkdir z2
 if ! ln z1/foo z2/foo ; then
-  echo No ln command for `pwd`; assuming no hard links.
+  echo No ln command for `pwd` - assuming no hard links.
   exit 0
 fi
 if ! compare z1 z2 ; then
diff --git a/tests/rollback.sh b/tests/rollback.sh
--- a/tests/rollback.sh
+++ b/tests/rollback.sh
@@ -4,6 +4,7 @@
 
 range="0 1 2"
 
+rm -rf temp1 temp2              # clean up when previous run crashed
 mkdir temp1 && cd temp1 && darcs init
 touch f && darcs add f
 for i in $range
