logo       
Google Custom Search
    AddThis Social Bookmark Button
-->

darcs patch: replace write_pending with "with_new_pending".: msg#00169

Subject: darcs patch: replace write_pending with "with_new_pending".
Hi Ian,

I'm not sure that there is a bug to be fixed here, but I think that in
principle there *could* be.  I've tried to create a scenario where one
would run into trouble, but have failed.

The potential bug here (in Pull, as also discussed below) is that we create
the new pending in pull using as one of its components the following
get_unrecorded:

      mp <- get_unrecorded repository (AnyOrder:opts)

This is of course a lazy operation, which lazily reads the pristine and
working directories.

We then update the pristine cache with a

          repairable $ applyToPristine repository pc

and only after that is the first case where we touch mp:

          unless (isNothing mp && pw_resolved `eq_patches` pc) $
               write_pending repository $ join_patches
                   [invert pc, fromMaybePatch mp, pw_resolved]

At this stage, the lazily computed mp is actually computed (reading the
already-modified pristine cache), and used as part of the new pending
patch.  The resulting patch is probably almost always invalid, but we don't
notice, since write_pending normally filters out all the hunk patches, etc,
through its sift_for_pending.  However, there are times when hunk patches
can't be filtered out (i.e. if there are other interesting changes that
don't commute with the hunks--replaces, for example).  Add and remove
patches are all no problem, since slurp isn't lazy in its directory
reading, and this is most of what keeps the code from being *severely*
buggy.

My solution is to remove the easily-abused-in-this-way write_pending
function, similar to what you did with your write_pending_then.  I also add
a add_to_pending function, which is easier to use in the case where we
aren't modifying the pristine cache, and just want to add a new patch
(i.e. setpref, add, remove, mv and replace).

I think that this interface change will make it much harder to write an
incorrect pending.  Ideally, we would write a single function that updates
both the pristine cache, pending and (optionally?) the working directory.
This interface would also be the most flexible if we introduce other
aspects to our repository (e.g. storing hashes of pristine files, or
perhaps inode numbers of files in the working directory that are identical
to their copies in the pristine cache).

Comments are welcome.  And btw, I don't really like the namespace aspect of
my FilePathUtils module.  It's more than a bit ugly, but I haven't had a
better idea.

Fri Jul 22 08:57:25 EDT 2005  David Roundy <droundy@xxxxxxxxxxxxxxx>
  * replace write_pending with "with_new_pending".
  This patch is basically an extension of Ian's earlier patch that created a
  "write_pending_then" function.  This one creates two functions,
  with_new_pending and add_to_pending.
  
  The idea is that we can't check if a new pending is valid until after we've
  updated the pristine cache.  But it's possible that the pending patch
  itself was lazily generated with get_unrecorded, in which case it's not
  safe to modify the pristine cache until after we've written pending.  This
  new interface makes it much harder to make this kind of mistake.  I also
  think it's pretty intuitive.

New patches:

[replace write_pending with "with_new_pending".
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050722125725
 This patch is basically an extension of Ian's earlier patch that created a
 "write_pending_then" function.  This one creates two functions,
 with_new_pending and add_to_pending.
 
 The idea is that we can't check if a new pending is valid until after we've
 updated the pristine cache.  But it's possible that the pending patch
 itself was lazily generated with get_unrecorded, in which case it's not
 safe to modify the pristine cache until after we've written pending.  This
 new interface makes it much harder to make this kind of mistake.  I also
 think it's pretty intuitive.
] 
<
> {
hunk ./Add.lhs 33
 import DarcsUtils ( withCurrentDirectory, nubsort )
 import IsoDate ( getIsoDateTime )
 import Repository ( amInRepository, withRepoLock,
-                    slurp_pending, read_pending, write_pending )
-import Patch ( Patch, is_null_patch, apply_to_slurpy, addfile, adddir, move,
-               join_patches, flatten,
-             )
+                    slurp_pending, add_to_pending )
+import Patch ( Patch, apply_to_slurpy, addfile, adddir, move, join_patches )
 import SlurpDirectory ( Slurpy, slurp_has_anycase, slurp_has,
                         isFileReallySymlink, doesDirectoryReallyExist, 
                         doesFileReallyExist, slurp_hasdir,
hunk ./Add.lhs 118
     ps <- addp msgs opts date cur $ nboring flist
     when (null ps && not (null args)) $ do
         fail "No files were added"
-    when (not gotDryRun) $ do
-        pend <- read_pending repository
-        case pend of
-            Nothing -> write_pending repository $ join_patches
-                     $ filter (not . is_null_patch) ps
-            Just op -> write_pending repository $ join_patches $
-                       flatten $ join_patches [op,join_patches ps]
+    when (not gotDryRun) $ add_to_pending repository (join_patches ps)
   where
     gotDryRun = DryRun `elem` opts
     msgs | gotDryRun = dryRunMessages
hunk ./AmendRecord.lhs 26
 import SignalHandler ( withSignalsBlocked )
 import Repository ( PatchSet,
                     withRepoLock, get_unrecorded, slurp_recorded,
-                    write_pending, sync_repo,
+                    with_new_pending, sync_repo,
                   )
 import DarcsRepo ( read_repo,
                    add_to_inventory, write_patch,
hunk ./AmendRecord.lhs 132
                                     exitWith $ ExitFailure 1
                        write_patch opts $ newp
                        remove_from_unrevert_context [oldp]
-                       withSignalsBlocked $ do
+                       withSignalsBlocked $
+                         with_new_pending repository (join_patches unrec) $ do
                          pris <- identifyPristine
                          applyPristine pris (join_patches chs) `catch`
                              \e -> fail ("Bizarre error in amend-recording:\n" 
++ show e)
hunk ./AmendRecord.lhs 142
                          write_inventory "." $ rempatch oldp patches'
                          add_to_inventory "."
                                          [(fromJust $ patch2patchinfo newp)]
-                         write_pending repository $ join_patches unrec
-                         sync_repo repository
-                         putStrLn "Finished amending patch:"
-                         putDocLn $ human_friendly $ fromJust
-                                  $ patch2patchinfo newp
+                       sync_repo repository
+                       putStrLn "Finished amending patch:"
+                       putDocLn $ human_friendly $ fromJust
+                                    $ patch2patchinfo newp
 \end{code}
 
 If you configure darcs to run a test suite, darcs will run this test on the
hunk ./Apply.lhs 23
 import Prelude hiding ( catch )
 import IO ( hClose, stdin, stdout, stderr )
 import Control.Exception ( catch, throw, Exception( ExitException ) )
-import Monad ( when, unless, liftM )
+import Monad ( when, liftM )
 import DarcsUtils ( nubsort )
hunk ./Apply.lhs 25
-import Maybe ( catMaybes, isNothing )
+import Maybe ( catMaybes )
 
 import SignalHandler ( withSignalsBlocked )
 import DarcsCommands ( DarcsCommand(..) )
hunk ./Apply.lhs 45
 import qualified DarcsArguments ( cc )
 import Repository ( PatchSet, withRepoLock, amInRepository,
                     get_unrecorded, slurp_pending, slurp_recorded,
-                    write_pending, sync_repo, read_repo, updateInventory,
+                    with_new_pending, sync_repo, read_repo, updateInventory,
                     applyToPristine,
                   )
 import Patch ( Patch, patch2patchinfo, invert, list_touched_files,
hunk ./Apply.lhs 49
-               join_patches, unjoin_patches, eq_patches, null_patch,
+               join_patches, unjoin_patches, null_patch,
              )
 import qualified Patch (apply)
 import PatchInfo ( human_friendly )
hunk ./Apply.lhs 180
               exitWith $ ExitFailure 1
     tokens <- save_patches repository opts $ unjoin_patches us_patch
     mp <- get_unrecorded repository (AnyOrder:opts)
-    withSignalsBlocked $ do
+    let npend = join_patches [invert us_patch, fromMaybePatch mp, pw_resolved]
+    withSignalsBlocked $ with_new_pending repository npend $ do
       applyToPristine repository us_patch `catch` \e ->
           fail ("Error applying patch to recorded!\nRunning 'darcs repair' on 
the target repo may help.\n" ++ show e)
       wait_a_moment -- so work will be more recent than rec
hunk ./Apply.lhs 188
       updateInventory repository tokens
       Patch.apply pw_resolved `catch` \e ->
           fail ("Error applying patch to working dir:\n" ++ show e)
-      unless (isNothing mp && pw_resolved `eq_patches` us_patch) $
-           write_pending repository $ join_patches
-               [invert us_patch, fromMaybePatch mp, pw_resolved]
     sync_repo repository
     putStrLn "Finished applying..."
     exitWith ExitSuccess
hunk ./DarcsRepo.lhs 54
                     withRecorded,
                     slurp_all_but_darcs,
                     surely_slurp_Pristine,
-                    read_pending, write_pending,
+                    read_pending, with_new_pending,
                     write_inventory, add_to_inventory, read_repo,
                     lazily_read_repo, sync_repo,
                     get_markedup_file,
hunk ./DarcsRepo.lhs 69
 
 import Directory ( createDirectory, setCurrentDirectory, doesFileExist,
                    doesDirectoryExist )
-import Workaround ( getCurrentDirectory )
+import Workaround ( getCurrentDirectory, renameFile )
 import DarcsUtils ( withCurrentDirectory, bugDoc )
 import System.IO ( hPutStrLn, stderr )
 import System.IO.Unsafe ( unsafeInterleaveIO )
hunk ./DarcsRepo.lhs 74
 import Monad ( liftM, when, unless )
-import Maybe ( maybeToList )
+import Maybe ( maybeToList, isNothing )
 import SignalHandler ( withSignalsBlocked )
 import FastPackedString ( PackedString, packString, gzReadFilePS,
                           breakOnPS, nullPS )
hunk ./DarcsRepo.lhs 167
 
 \begin{code}
 read_pending :: String -> IO (Maybe Patch)
-write_pending :: String -> Patch -> Slurpy -> IO ()
-
 read_pending name = do
   pend <- gzReadFilePS name `catch`
           (\_ -> return $ packString "")
hunk ./DarcsRepo.lhs 174
     Nothing -> return Nothing
     Just (p,_) -> return $ if is_null_patch p then Nothing else Just p
 
-write_pending name origp cur =
- let p = sift_for_pending origp in
- if is_null_patch p
- then writePatch name p
- else do
-  case apply_to_slurpy p cur of
-    Just _ -> writePatch name p
-    Nothing -> do
-      writeBinFile (name ++ "_buggy") ""
-      writePatch (name ++ "_buggy") p
+with_new_pending :: String -> Patch -> IO Slurpy -> IO ()
+with_new_pending name origp job =
+ do let p = sift_for_pending origp
+        newname = name ++ ".new"
+    writePatch newname p
+    mp <- read_pending newname
+    cur <- job
+    unless (isNothing mp) $
+      when (isNothing $ apply_to_slurpy (fromJust mp) cur) $ do
+      let buggyname = name ++ "_buggy"
+      renameFile newname buggyname
       bugDoc $ text "There was an attempt to write an invalid pending!"
hunk ./DarcsRepo.lhs 186
-            $$ text "If possible, please send the contents of 
_darcs/patches/pending_buggy"
+            $$ text "If possible, please send the contents of"
+               <+> text buggyname
             $$ text "along with a bug report."
hunk ./DarcsRepo.lhs 189
+    renameFile newname name
 
 sift_for_pending :: Patch -> Patch
 sift_for_pending patch =
hunk ./Mv.lhs 30
 import Directory ( renameDirectory )
 import Workaround ( renameFile )
 import Repository ( identifyRepository, withRepoLock, amInRepository,
-                    slurp_pending, read_pending, write_pending,
+                    slurp_pending, add_to_pending,
                   )
hunk ./Mv.lhs 32
-import Patch ( join_patches, flatten, move )
+import Patch ( join_patches, move )
 import SlurpDirectory ( Slurpy, slurp, slurp_has,
                         slurp_hasdir, slurp_hasfile, slurp_has_anycase )
 import FileName ( fp2fn, fn2fp, super_name )
hunk ./Mv.lhs 96
    then move_to_dir opts [old] new
    else do
     cur <- slurp_pending repository
-    pend <- read_pending repository
     check_new_and_old_filenames opts cur work (old,new)
     withSignalsBlocked $ do
       move_file_or_dir work old new
hunk ./Mv.lhs 99
-      case pend of
-          Nothing -> write_pending repository $ move old new
-          Just op -> write_pending repository $ join_patches $
-                     flatten $ join_patches [op, move old new]
+      add_to_pending repository (move old new)
 \end{code}
 
 \begin{code}
hunk ./Mv.lhs 118
     repository <- identifyRepository "."
     cur <- slurp_pending repository
     work <- slurp "."
-    pend <- read_pending repository
     mapM_ (check_new_and_old_filenames opts cur work) $ zip moved movetargets
     withSignalsBlocked $ do
       sequence_ $ map2 (move_file_or_dir work) moved movetargets
hunk ./Mv.lhs 121
-      case pend of
-          Nothing -> write_pending repository $ join_patches movepatches
-          Just op -> write_pending repository $ join_patches $
-                     flatten $ join_patches (op: movepatches)
+      add_to_pending repository (join_patches movepatches)
 
 check_new_and_old_filenames
     :: [DarcsFlag] -> Slurpy -> Slurpy -> (FilePath, FilePath) -> IO ()
hunk ./Pull.lhs 22
               check_unrecorded_conflicts,
             ) where
 import System ( ExitCode(..), exitWith )
-import Monad ( when, unless, liftM )
-import Maybe ( catMaybes, isNothing )
+import Monad ( when, liftM )
+import Maybe ( catMaybes )
 
 import SignalHandler ( withSignalsBlocked )
 import DarcsCommands ( DarcsCommand(..) )
hunk ./Pull.lhs 41
                     amInRepository, withRepoLock,
                     slurp_recorded, slurp_recorded_and_unrecorded,
                     read_repo, absolute_dir, get_unrecorded,
-                    write_pending, read_pending, sync_repo,
+                    with_new_pending, read_pending, sync_repo,
                     applyToPristine, writePatch, updateInventory,
                   )
 import Patch ( Patch, join_patches, merge, patch2patchinfo,
hunk ./Pull.lhs 46
                unjoin_patches, list_touched_files,
-               invert, list_conflicted_files, eq_patches, null_patch,
+               invert, list_conflicted_files, null_patch,
                apply,
              )
 import SelectChanges ( promptChar )
hunk ./Pull.lhs 170
                   exitWith $ ExitFailure 1
       patchTokens <- save_patches repository opts $ unjoin_patches pc
       mp <- get_unrecorded repository (AnyOrder:opts)
-      withSignalsBlocked $ do
+      let newpend = join_patches [invert pc, fromMaybePatch mp, pw_resolved]
+      withSignalsBlocked $ with_new_pending repository newpend $ do
           repairable $ applyToPristine repository pc
             `catch` \e ->
                 fail ("Error applying patch to recorded.\nRunning 'darcs 
repair' on the target repo may help.\n" ++ show e)
hunk ./Pull.lhs 176
           updateInventory repository patchTokens
-          unless (isNothing mp && pw_resolved `eq_patches` pc) $
-               write_pending repository $ join_patches
-                   [invert pc, fromMaybePatch mp, pw_resolved]
           -- so work will be more recent than rec:
           revertable wait_a_moment
           revertable $ apply pw_resolved `catch` \e ->
hunk ./Record.lhs 40
 import Lock ( readBinFile, withTemp )
 import Repository ( amInRepository, identifyRepository, withRepoLock,
                     get_unrecorded,
-                    write_pending, sync_repo, read_repo,
+                    with_new_pending, sync_repo, read_repo,
                     slurp_recorded, updateInventory, writePatch,
                     applyToPristine, patchTokenToPatchFile,
                   )
hunk ./Record.lhs 205
                          Nothing -> return ()
                  when (Verbose `elem` opts) $
                      putStrLn "Applying to current..."
-                 withSignalsBlocked $ do
+                 withSignalsBlocked $
+                   with_new_pending repository (join_patches skipped) $ do
                    applyToPristine repository mypatch'
                    updateInventory repository [(myinfo, token)]
hunk ./Record.lhs 209
-                   write_pending repository $ join_patches skipped
                  when (Verbose `elem` opts) $
                      putStrLn "Syncing timestamps..."
                  sync_repo repository
hunk ./Remove.lhs 28
                         working_repo_dir,
                       )
 import Repository ( identifyRepository, withRepoLock, amInRepository,
-                    slurp_pending, read_pending, write_pending,
+                    slurp_pending, add_to_pending,
                   )
hunk ./Remove.lhs 30
-import Patch ( Patch, rmdir, join_patches, flatten )
+import Patch ( Patch, rmdir, join_patches )
 import SlurpDirectory ( slurp_removedir, slurp_removefile )
 import RepoPrefs ( filetype_function )
 import Diff ( smart_diff )
hunk ./Remove.lhs 77
 remove_cmd opts relargs = let args = map (fix_filepath opts) relargs in
     withRepoLock $ \repository -> do
     p <- make_remove_patch args
-    pend <- read_pending repository
-    case pend of
-        Nothing -> write_pending repository p
-        Just op -> write_pending repository $ join_patches $
-                   flatten $ join_patches [op,p]
+    add_to_pending repository p
 
 make_remove_patch :: [FilePath] -> IO Patch
 make_remove_patch files = do repository <- identifyRepository "."
hunk ./Replace.lhs 26
 import DarcsCommands
 import DarcsArguments
 import Repository ( withRepoLock,
-                    slurp_pending, read_pending, write_pending,
+                    slurp_pending, add_to_pending,
                   )
 import DarcsRepo ( am_in_repo, slurp_recorded_and_unrecorded
                  )
hunk ./Replace.lhs 31
 import Patch ( apply, apply_to_slurpy, tokreplace, force_replace_slurpy,
-               join_patches, flatten, Patch,
+               join_patches, Patch,
              )
 import SlurpDirectory ( slurp_hasfile, Slurpy )
 import FileName ( fp2fn )
hunk ./Replace.lhs 137
       fail $ "Can't do replace on working!\n"
           ++ "Perhaps one of the files already contains '"++ new++"'?\n"
           ++ show e
-  pend <- read_pending repository
-  write_pending repository $ join_patches $
-      maybe [] flatten pend ++ fst (unzip ps_and_pswork)
+  add_to_pending repository (join_patches $ fst $ unzip ps_and_pswork)
   where fs = map (fix_filepath opts) relfs
         ftf _ = TextFile
 
hunk ./Repository.lhs 23
                     slurp_recorded, slurp_recorded_and_unrecorded,
                     get_unrecorded, read_repo, sync_repo, absolute_dir,
                     prefsUrl,
-                    read_pending, write_pending, withRepoLock,
+                    read_pending, with_new_pending, add_to_pending,
+                    withRepoLock,
                     PatchToken, patchTokenToPatchFile,
                     writePatch, updateInventory, unrevertUrl,
                     applyToPristine,
hunk ./Repository.lhs 187
 read_pending (Repo r _ tp) =
     withCurrentDirectory r (DarcsRepo.read_pending (pendingName tp))
 
-write_pending :: Repository -> Patch -> IO ()
-write_pending repo@(Repo r _ tp) p =
-    do pristine <- slurp_recorded repo
-       withCurrentDirectory r
-           (DarcsRepo.write_pending (pendingName tp) p pristine)
+add_to_pending :: Repository -> Patch -> IO ()
+add_to_pending repo p =
+    do pend <- read_pending repo
+       let pnew = case pend of Nothing -> p
+                               Just pold -> join_patches [pold, p]
+       with_new_pending repo pnew (return ())
+
+with_new_pending :: Repository -> Patch -> IO () -> IO ()
+with_new_pending repo@(Repo r _ tp) p job =
+    withCurrentDirectory r $
+    DarcsRepo.with_new_pending (pendingName tp) p $ job >> slurp_recorded repo
 
 unempty :: [a] -> Maybe [a]
 unempty [] = Nothing
hunk ./Resolve.lhs 28
                         ignoretimes, verbose, working_repo_dir,
                       )
 import Repository ( withRepoLock, amInRepository,
-                    read_repo, sync_repo, get_unrecorded, write_pending,
+                    read_repo, sync_repo, get_unrecorded, with_new_pending,
                     )
 import Patch ( join_patches, invert, apply, is_null_patch )
 import Resolution ( patchset_conflict_resolutions )
hunk ./Resolve.lhs 85
                  apply (invert p) `catch` \e ->
                     bug ("Can't undo pending changes!" ++ show e)
                  sync_repo repository
-  withSignalsBlocked $
-      do apply res `catch` \e ->
-             bug ("Problem resolving conflicts in resolve!" ++ show e)
-         write_pending repository res
-         putStrLn "Finished resolving."
+  withSignalsBlocked $ with_new_pending repository res $
+      apply res `catch` \e ->
+      bug ("Problem resolving conflicts in resolve!" ++ show e)
+  putStrLn "Finished resolving."
 resolve_cmd _ _ = impossible
 \end{code}
 
hunk ./Revert.lhs 34
 import DarcsUtils ( askUser )
 import Repository ( withRepoLock,
                     get_unrecorded,
-                    write_pending, sync_repo,
+                    with_new_pending, sync_repo,
                     amInRepository, slurp_recorded_and_unrecorded,
                   )
 import Patch ( join_patches, invert, is_null_patch,
hunk ./Revert.lhs 111
                           _ -> exitWith $ ExitSuccess
              write_unrevert (join_patches skipped') p rec
              withSignalsBlocked $
-                 do apply (invert $ join_patches p) `catch` \e ->
-                        fail ("Unable to apply inverse patch!" ++ show e)
-                    write_pending repository $ join_patches skipped'
-             sync_repo repository
-             putStrLn "Finished reverting."
+                 with_new_pending repository (join_patches skipped')$
+                 apply (invert $ join_patches p) `catch` \e ->
+                 fail ("Unable to apply inverse patch!" ++ show e)
+  sync_repo repository
+  putStrLn "Finished reverting."
 \end{code}
 
hunk ./Rollback.lhs 26
                         verbose, working_repo_dir, nocompress,
                         match_one_nontag,
                       )
-import Repository ( amInRepository, withRepoLock, read_pending, write_pending,
+import Repository ( amInRepository, withRepoLock, read_pending,
+                    with_new_pending,
                     applyToPristine, writePatch, updateInventory,
                   )
 import Patch ( join_patches, invert, patch2patchinfo, null_patch, )
hunk ./Rollback.lhs 88
           fail "cannot roll back a 'tag' patch."
       Just pinfo | not (is_inverted pinfo) ->
           fail "cannot roll back a 'rollback' patch."
-      Just pinfo -> do (_, t) <- writePatch repository opts $ invert p
-                       withSignalsBlocked $
-                           do applyToPristine repository (invert p) `catch`
-                                  \e ->
-                                      fail ("Unable to apply inverse patch!\n"
-                                            ++ show e)
-                              write_pending repository $ join_patches [p, pend]
-                              updateInventory repository [(pinfo, t)]
-                       putStrLn "Finished rolling back."
+      Just pinfo ->
+          do (_, t) <- writePatch repository opts $ invert p
+             let newpend = join_patches [p, pend]
+             withSignalsBlocked $ with_new_pending repository newpend $
+               do applyToPristine repository (invert p) `catch` \e ->
+                      fail ("Unable to apply inverse patch!\n" ++ show e)
+                  updateInventory repository [(pinfo, t)]
+             putStrLn "Finished rolling back."
 \end{code}
 
hunk ./SetPref.lhs 25
 
 import DarcsCommands ( DarcsCommand(..), nodefaults )
 import DarcsArguments ( DarcsFlag, )
-import Repository ( identifyRepository, amInRepository,
-                    write_pending, read_pending )
-import Patch ( flatten, join_patches, changepref, )
+import Repository ( identifyRepository, amInRepository, add_to_pending )
+import Patch ( changepref )
 import RepoPrefs ( get_prefval, change_prefval, )
 #include "impossible.h"
 \end{code}
hunk ./SetPref.lhs 112
                       Nothing -> return ""
   change_prefval pref old val
   putStrLn $ "Changing value of "++pref++" from '"++old++"' to '"++val++"'"
-  pend <- read_pending repository
-  case pend of
-      Nothing -> write_pending repository $
-                     join_patches [changepref pref old val]
-      Just op -> write_pending repository $
-                     join_patches $ flatten op ++ [changepref pref old val]
+  add_to_pending repository (changepref pref old val)
 setpref_cmd _ _ = impossible
 \end{code}
 
hunk ./Unrecord.lhs 34
              )
 import Repository ( PatchSet, withRepoLock, slurp_recorded,
                     get_unrecorded,
-                    read_pending, write_pending, sync_repo,
+                    read_pending, with_new_pending, sync_repo,
                   )
 import DarcsRepo ( read_repo,
                    write_inventory, write_patch,
hunk ./Unrecord.lhs 155
        when (null to_unrecord) $ do putStrLn "No patches selected!"
                                     exitWith ExitSuccess
        remove_from_unrevert_context to_unrecord
-       withSignalsBlocked $ do
+       let newpend = join_patches (to_unrecord ++ pend)
+       withSignalsBlocked $ with_new_pending repository newpend $ do
           when (Verbose `elem` opts) $
                putStrLn "About to write out (potentially) modified patches..."
           let (_, skipped) = commute_to_end to_unrecord allpatches
hunk ./Unrecord.lhs 169
           pris <- identifyPristine
           applyPristine pris (invert $ join_patches to_unrecord) `catch` \e ->
               fail ("Unable to apply inverse patch!\n" ++ show e)
-          when (Verbose `elem` opts) $ putStrLn "Updating pending..."
-          write_pending repository $ join_patches (to_unrecord ++ pend)
           sync_repo repository
           putStrLn "Finished unrecording."
 
hunk ./Unrecord.lhs 295
         when (null ps) $ do putStrLn "No patches selected!"
                             exitWith ExitSuccess
         remove_from_unrevert_context ps
-        withSignalsBlocked $ do
+        withSignalsBlocked $ with_new_pending repository pend' $ do
            let (_, skipped) = commute_to_end ps allpatches
            sequence_ $ map (write_patch opts) skipped
            repo_patches <- read_repo "."
hunk ./Unrecord.lhs 305
                fail ("Unable to apply inverse patch!\n" ++ show e)
            apply (invert p_after_pending) `catch` \e ->
                fail ("Couldn't undo patch in working dir.\n" ++ show e)
-           write_pending repository pend'
-           sync_repo repository
-           putStrLn "Finished unpulling."
+        sync_repo repository
+        putStrLn "Finished unpulling."
 \end{code}
 
hunk ./Unrevert.lhs 31
 import Directory ( removeFile )
 import Repository ( PatchSet, identifyRepository, withRepoLock,
                     slurp_recorded, unrevertUrl,
-                    read_pending, write_pending,
+                    read_pending, with_new_pending,
                     sync_repo,
                     read_repo, amInRepository,
                     slurp_recorded_and_unrecorded,
hunk ./Unrevert.lhs 106
         let pend_and_p = case pend of
                          Nothing -> join_patches p
                          Just pending -> join_patches (pending : p)
-        withSignalsBlocked $
+        withSignalsBlocked $ with_new_pending repository pend_and_p $
           do
              apply (join_patches p) `catch` \e ->
                  fail ("Error applying unrevert to working directory...\n"
hunk ./Unrevert.lhs 112
                     ++ show e)
              write_unrevert pend_and_p skipped rec
-             write_pending repository pend_and_p
         sync_repo repository
         putStrLn "Finished unreverting."
 unrevert_cmd _ _ = impossible
}

Context:

[Make DarcsRepo.add_to_inventory take a list.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050720174029
 This avoids opening the inventory multiple times.  Thanks to Ian for the hint.
] 
[Use mapM_ instead of the comprehensible alternative.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050720164258
 Mentioning mapM_ always impresses people at dinner parties.  Thanks to
 Ian for the hint.
] 
[Move iterateGitTree out of the IO monad.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050720162841
 We're reading immutable on-disk data, it's safe to do it unsafely.
] 
[Clean up usage of interleaveIO in Git.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050720162251] 
[fix error in name of --reorder-patches flag.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050722110752] 
[TAG 1.0.4pre1
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050718112234] 
[make configure automatically guess the release state based on defaultrepo and 
tags.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050718112222] 
[Push and pull can now show the detailed diffs of patches
Jim Radford <radford@xxxxxxxxxxxxx>**20050717042645
 The same distinction is now made between --summary and --verbose
 as changes makes.
] 
[TAG 2005-07-18
Ian Lynagh <igloo@xxxxxxxx>**20050718193534] 
[fix write_problem to show all problems.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050717110628] 
[Rename bound variable in fromJust macro.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050716221705
 Avoids ``shadows existing variable'' warnings which for some reason are
 errors.
 
 Could we please use Lisp macros instead?
] 
[bugfix, make _darcs/prefs/defaults really override $HOME/.darcs/defaults
Tommy Pettersson <ptp@xxxxxxxxxxxxxx>**20050612174925
 Variants of the same flag from the two defaults files where just merged,
 and an ALL in the local defaults could not override an explicit command
 in the global defaults, as would be expected.
] 
[use AC_SEARCH_LIBS instead of AC_CHECK_LIB
Wim Lewis <wiml@xxxxxxxx>**20050707181811] 
[Update AC_PREREQ to 2.54
Wim Lewis <wiml@xxxxxxxx>**20050707181631
 The form of AC_C_BIGENDIAN used here didn't show up until 2.53 or 2.54.
 Also, no need to specify the third arg, since it defaults to erroring out 
anyway.
] 
[TAG 2005-007-16
Ian Lynagh <igloo@xxxxxxxx>**20050716181541] 
[don't import head and tail, which are in the prelude.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050716143547] 
[Keep file modes in dirty Git slurpies.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050716071846
 This prevents Darcs from resetting Git file permissions.
] 
[Update HEAD in place.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050716071116] 
[Generalise write_pending.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050716002145
 I missed this, which breaks add and remove.
] 
[Use emptyGitSlurpy in gitCommitToPatch'.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050715234115] 
[Fix parsing of Git merges with no common ancestor.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050715233226] 
[Implement emptyGitSlurpy.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050715233211] 
[Fix typo in applyF_direct (Git).
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050715233140] 
[Don't include ./ when generating patches from Git.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050715203248] 
[Generalise rollback.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050715194322] 
[Make histories that come from Git lazy in the presence of merges.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050715193440
 Use the fact that we know the length of the result of a merge to produce a
 spine-lazy list of patches.  This makes ``darcs changes'' never touch
 a blob.
] 
[Make darcs understand Git n-ary merges.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050715192333] 
[move read/write format checks into identifyRepository and withRepoLock.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050714105840] 
[Generalise Pull and Apply.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050712145643] 
[Generate Git PatchInfos from scratch.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050712123945
 patchtopatchinfo is not lazy enough.
] 
[Replace frobPatchFile with patchTokenToPatchFile.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050711045246] 
[Make writing of patches work in arbitrary directories.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050711021014] 
[Use impossible.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050711015640] 
[Make patch tokens opaque.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050711014829] 
[cleanups in RepoFormat as suggested by Ian.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050711125711] 
[fix typo in git prefsUrl.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050711100531] 
[generalize Revert and Unrevert.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050711100429] 
[fix bug where we failed to convert sha1 to hex.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050711092602] 
[Only read darcs/cgi.conf once.
Wim Lewis <wiml@xxxxxxxx>**20050623081319
 Modified read_conf() so it caches the parsed configuration values
 in a hash, instead of re-opening and re-reading the configuration
 file several times per CGI invocation. (A probably-unimportant side
 effect of this is that flag names can no longer contain spaces, but
 that shouldn't affect anybody.)
] 
[Make record repository-format agnostic.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050710034630] 
[Implement polymorphic write support.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050710034310] 
[Make withRepoLock polymorphic.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050710023802] 
[Make writePatch and updateInventory polymorphic.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050710021543] 
[Make sync_repo polymorphic.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050710021426] 
[Import GitRepo from darcs-git.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050710015221
 This version has write support and support for reverse-engineering
 Darcs merges from Git merges.
] 
[Add ``lax'' argument to applyToGitSlurpy.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050710014814
 When lax is true, we apply merger_equivalent to mergers.
] 
[Make read/write_pending polymorphic.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050710012515] 
[don't go through shell when execing darcs
Wim Lewis <wiml@xxxxxxxx>**20050710062743
 Use the LIST variant of exec to avoid exposing the arguments of the darcs
 command to shell interpretation. Also, pipe the output directly to where
 it's going instead of reading it in and writing it out again.
] 
[fix incorrectly quoted regexp
Wim Lewis <wiml@xxxxxxxx>**20050710051424
 Unquoted regexp evaluated to 0 or 1, which didn't immediately break the cgi
 because most hashes have those characters in them. Also fixed a bogus
 initializer caught by "perl -w".
] 
[update comments in darcs.cgi
Wim Lewis <wiml@xxxxxxxx>**20050710050226] 
[Use a pipe instead of a temp file
Wim Lewis <wiml@xxxxxxxx>**20050710005052
 Instead of storing the intermediate XML in a temporary file and then invoking
 xsltproc, just pipe the XML directly into the xslt processor on the fly.
] 
[use darcs_xml() where it simplifies things
Wim Lewis <wiml@xxxxxxxx>**20050709023659] 
[Fix make_changelog to work with David's new identifyRepository.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050710002419] 
[Fix typo in import of malloc.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050710001235] 
[Add comment about immutability of Git trees.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050709215815] 
[Fix location of HEAD in Git.updateHead.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050709215408] 
[implement missing DarcsIO methods in SlurpMonad.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050709192216] 
[clean up GitTreeIterator.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050709174440] 
[eliminate excess touching in Git.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050709170954] 
[make GitFileInfo a cleaner more haskellish data type.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050709170457] 
[add some typesafety to haskell cache_entry-related Git code.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050709153935] 
[add a bit of type safety to the pointers to git_tree_iterator.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050709153337] 
[make GitFile use the ffi more nicely.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050709152131] 
[replace fromSingleton with gitSingleCommitValue which gives better error 
message.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050709145616] 
[implement CString utility functions in FastPackedString.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050709145549] 
[use withSlurpy to implement apply_to_slurpy.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050709145517] 
[make darcs send look in the right place for target email address.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050709121505] 
[fix bug in Repository abstraction code that broke remote pulls.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050709120518
 This change adds to the Repository data object the URL of the repository in
 question, allowing us to use this abstraction with both remote and local
 repositories.
] 
[add support for repository format checking.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050709112017
 The idea being to be forward-compatible with repository format changes.
] 
[add an unused RepoFormat module.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050430123937] 
[Documentation nits & typos
Wim Lewis <wiml@xxxxxxxx>**20050618193852] 
[Merge conflicts in configure.ac, and add blank line to try to avoid future 
conflicts
Ian Lynagh <igloo@xxxxxxxx>**20050707160658] 
[TAG 1.0.3
Tomasz Zielonka <tomasz.zielonka@xxxxxxxxx>**20050524215127] 
[bump version to 1.0.3
Tomasz Zielonka <tomasz.zielonka@xxxxxxxxx>**20050524215115] 
[Revert an accidental Repository -> DarcsRepo change in a string
Ian Lynagh <igloo@xxxxxxxx>**20050707160431] 
[Revert "Cache pristine directory within NoPristine"
Ian Lynagh <igloo@xxxxxxxx>**20050707153500] 
[fixed a few typos in docs & comments
Wim Lewis <wiml@xxxxxxxx>**20050624070640] 
[make git support configurable (copied from Juliusz's patch).
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050701135046] 
[TAG another version that works in the git-merge saga.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050701133252] 
[fix errors from merging more darcs-git stuff.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050701133228] 
[resolve some more conflicts.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050701132446] 
[TAG working version in middle of darcs-git merge.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050701125730] 
[resolve conflicts between git and darcs-unstable.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050701125706] 
[Cache pristine directory within NoPristine.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050426172006] 
[eliminate unnecesary unsafePerformIOs in Git.
David Roundy <droundy@xxxxxxxxxxxxxxx>**20050701142312] 
[Move gitIsTree to C code.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050509235651] 
[Simplify gitBlobToPatches.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050509234445] 
[Remove obsolete comment.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050507195543] 
[Make ordering of trees Linus-compatible.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050507184412] 
[Don't sort when purifying Git slurpies.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050507024134
 The new ordering is preserved by purification.
] 
[Replace the definition of Ord on GitSlurpy with one that works.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050507023832
 This is still not Linus-compliant, as Haskell and C use different ordering
 conventions.
] 
[Fix typo in noname.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050506222328] 
[Make gitFooToPatches work with dirty trees.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050506200939] 
[Export GitSlurpy.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050506181048] 
[Implement a variant of gitCommitToPatch that takes a GitSlurpy reference.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050506180031] 
[Get rid of gitCommitToPIMP.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050505181603] 
[Move reading git commits out of the IO monad.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050505180609] 
[Simplify generation of PatchSets from Git repos.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050505170207] 
[Fix parsing of multiple parents in Git commits.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050505153025
 Multiple parents come in separate parent lines, not a single line as I
 thought.
] 
[Fix Git date handling.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050504233745] 
[Fix formatting of Git files.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050504211643] 
[Fix formatting of Git records.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050504210607] 
[Only free those names that were allocated in git_write_tree_done.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050504204933] 
[Free the right buffer in git_write_tree_done.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050504204910] 
[Estimate the size of a new tree correctly.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050504204850] 
[Actually create new .git/HEAD (blush).
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050504204825] 
[Use "." as root of GitSlurpies.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050504203304] 
[Implement updateHead.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050504193546] 
[Implement git_update_head.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050504193529] 
[Implement writeGitCommit.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050504192232] 
[Add type argument to writeGitFile.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050504185421] 
[Make slurpGitCommit return a GitSlurpy after all.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050504143935] 
[Implement make_git_file_info.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050504142613] 
[Implement purification of Git trees.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050504142042] 
[Actually implement purification of blobs.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050504125709] 
[Add repo argument to purify.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050503234432] 
[Partial implementation of purifyGitSlurpy.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050503232848] 
[Generalise trackdown.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050426233012] 
[Make whatsnew go through Repository.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050426162106
 This won't work for Git repositories until they implement slurp_recorded
 and get_recorded.
] 
[Implement git_format_time.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050504192053] 
[Export Slurpy constructors.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050426195817] 
[Export applyBinary and applyHunkLines.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050503224204] 
[Really don't include directories in slurpies.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050429235609] 
[Make dist work with git repositories.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050426203906] 
[Fix merge conflicts.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050425194100] 
[Remove unsafeConstructPS.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050509233129] 
[Declare Git's global variables as extern.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050507224710
 Silly GHCi doesn't grok common symbols.
] 
[Use RepoPrefs.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050506220257] 
[Implement repoPrefs.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050506220152] 
[Export PatchInfo constructor.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050504190531] 
[Implement applyToGitSlurpy.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050503231941] 
[Basic implementation of dirty Git slurpies.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050503222642] 
[Use the cache when slurping the pristine state.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050430000813] 
[Restructure patch generation from Git repos.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050427213320] 
[Don't store directories in slurpies.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050427000833] 
[Instance Show Slurpy.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050426235914] 
[Start slurping at ".".
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050426203853] 
[Implement slurping from git repositories.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050426195957] 
[Make pattern exhaustive.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050426195941] 
[Check for presence of .git/HEAD.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050426195914] 
[Move slurp_pending and slurp_recorded into Repository.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050426185425] 
[Move get_unrecorded to Repository.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050426175527] 
[Implement send for git repositories.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050425210728] 
[Implement changes for git repositories.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050425205329] 
[Use ForeignPtrs instead of raw pointers when useful.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050425180449
 Now I remember why I hate Haskell.
] 
[Some less IO monad hacking.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050425180207] 
[Fix handling of subtrees.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050425162405] 
[Implement subtrees.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050425063228] 
[Parse new-style git dates.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050425001902] 
[Initial implementation of pulling from git.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050424213832] 
[Add licence statements to Linus' files.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050426161330] 
[Implement constructPS.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050425180306
 I use touchForeignPtr in the finaliser when building a PS from a
 ForeignPtr.
] 
[Import parts of Linus' git 0.6.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050424213310] 
[Implement unsafeConstructPS.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050424212204] 
[Export diff_files from Diff.lhs.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050424212113] 
[Export emptyFileContents from SlurpDirectory.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050424212051] 
[First cut at remodularising repo access.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050424145002] 
[Change Repository to DarcsRepo.
Juliusz Chroboczek <jch@xxxxxxxxxxxxxx>**20050424140132] 
[TAG 2005-07-07
Ian Lynagh <igloo@xxxxxxxx>**20050707144607] 
Patch bundle hash:
b647a5a570dcc84353d1c9d597eaa9017ec9d917
_______________________________________________
darcs-devel mailing list
darcs-devel@xxxxxxxxx
http://www.abridgegame.org/cgi-bin/mailman/listinfo/darcs-devel
<Prev in Thread] Current Thread [Next in Thread>