[darcs-devel] Darcs-git and merges

Juliusz Chroboczek Juliusz.Chroboczek at pps.jussieu.fr
Mon May 9 10:23:29 PDT 2005


Hi,

As you may have noted from a previous message, I've implemented
handling of merges in Darcs-git based on the way David outlined.
Given a changeset C with parents D1 and D2, we compute the common
ancestor E of D1 and D2, then we compute the patch sequences

  p1 = d(E, D1)
  p2 = d(E, D2)

We then merge p2 with p1 in order to get

  p1.p2' = d(E, C')

for some tree C', which we then use to compute a patch

  q = d(C', C)

in order to produce the final result

  p1.p2'.q = d(E, C)

If you want to have a look at the code, please see

  http://www.pps.jussieu.fr/~jch/software/repos/darcs-git/GitRepo.lhs

The net effect is that darcs-git is unusable ;-) Every command that
needs to compute history degenerates into a loop of patch commutation
as soon as it sees a nontrivial merge (trivial merges work fine, thank
you very much).

Now the trouble is that we need to compute p2' just in order to get
the history.  But most commands (for example whatsnew and send) don't
actually need p2'; they only need to compute the equivalent of

  map (fromJust . patch2patchinfo) p2'

which happens to be equal to

  map (fromJust . patch2patchinfo) p2

I've tried (really hard) to only compute the latter and to keep the
patches themselves in a lazy data structure; I'm appending one of my
attempts to this message.  However, in all cases somebody still
touched my patches, leading to the nasty reading of repository
contents and commuting that I'm trying to avoid.

Unfortunately, I don't know of a way to find out where a given thunk
is being forced.  Any help with debugging that issue would be great.

                                        Juliusz

--- old-darcs-git/GitRepo.lhs   2005-05-08 02:00:13.000000000 +0200
+++ new-darcs-git/GitRepo.lhs   2005-05-08 02:17:04.000000000 +0200
@@ -32,6 +32,7 @@
 import System.IO.Unsafe ( unsafePerformIO )
 import Maybe ( fromJust )
 import Monad ( liftM )
+import GHC.Base ( lazy )
 
 #include "impossible.h"
 
@@ -114,7 +115,10 @@
 merge_patches_after_patches :: [Patch] -> [Patch] -> [Patch]
 merge_patches_after_patches l1 l2 =
     let (Just ((ComP l), _)) = merge ((ComP l1), (ComP l2))
-    in l
+    in (make_lazy_list (length l1) l)
+  where make_lazy_list 0 _ = []
+        make_lazy_list n l =
+            (lazy (head l)) : (make_lazy_list (n - 1) (tail l))
 
 merge_subsequences :: GitSubsequence -> GitSubsequence -> GitSubsequence
 merge_subsequences l1 l2 | length l2 < length l1 =





More information about the darcs-devel mailing list