darcs-2.18.1: a distributed, interactive, smart revision control system
Maintainerdarcs-devel@darcs.net
Stabilityexperimental
Portabilityportable
Safe HaskellSafe-Inferred
LanguageHaskell2010

Darcs.Patch.Merge

Description

 
Synopsis

Classes

class CleanMerge p where Source #

Class of patches that can, possibly, be merged cleanly, that is, without conflict.

Every patch type can be made an instance of CleanMerge in a trivial way by defining cleanMerge _ = Nothing, which vacuously conforms to all required laws.

Instances should obey the following laws:

symmetry
cleanMerge (p :\/: q) == Just (q' :/\: p') <=> cleanMerge (q :\/: p) == Just (p' :/\: q')

If an instance Commute p exists, then we also require

merge-commute
cleanMerge (p :\/: q) == Just (q' :/\: p') ==> commute (p :> q') == Just (q :> p')

that is, the two branches of a clean merge commute to each other.

If an instance Invert p exists, then we also require

square-merge
cleanMerge (p :\/: q) == Just (q' :/\: p') => cleanMerge (invert p :\/: q') == Just (q :/\: invert p')

Here is a picture that explains why we call this square-merge:

    A---p--->X          A<--p^---X
    |        |          |        |
    |        |          |        |
    q        q'   =>    q        q'
    |        |          |        |
    v        v          v        v
    Y---p'-->B          Y<--p'^--B

Methods

cleanMerge :: (p :\/: p) wX wY -> Maybe ((p :/\: p) wX wY) Source #

Instances

Instances details
CleanMerge Prim Source # 
Instance details

Defined in Darcs.Patch.Prim.FileUUID.Commute

Methods

cleanMerge :: (Prim :\/: Prim) wX wY -> Maybe ((Prim :/\: Prim) wX wY) Source #

CleanMerge Prim Source # 
Instance details

Defined in Darcs.Patch.Prim.V1.Commute

Methods

cleanMerge :: (Prim :\/: Prim) wX wY -> Maybe ((Prim :/\: Prim) wX wY) Source #

CleanMerge Prim Source # 
Instance details

Defined in Darcs.Patch.V1.Prim

Methods

cleanMerge :: (Prim :\/: Prim) wX wY -> Maybe ((Prim :/\: Prim) wX wY) Source #

CleanMerge Prim Source # 
Instance details

Defined in Darcs.Patch.V2.Prim

Methods

cleanMerge :: (Prim :\/: Prim) wX wY -> Maybe ((Prim :/\: Prim) wX wY) Source #

CleanMerge p => CleanMerge (Named p) Source # 
Instance details

Defined in Darcs.Patch.Named

Methods

cleanMerge :: (Named p :\/: Named p) wX wY -> Maybe ((Named p :/\: Named p) wX wY) Source #

(PatchId p ~ PatchInfo, CleanMerge p) => CleanMerge (PatchInfoAndG p) Source # 
Instance details

Defined in Darcs.Patch.PatchInfoAnd

PrimPatch prim => CleanMerge (RepoPatchV1 prim) Source # 
Instance details

Defined in Darcs.Patch.V1.Commute

Methods

cleanMerge :: (RepoPatchV1 prim :\/: RepoPatchV1 prim) wX wY -> Maybe ((RepoPatchV1 prim :/\: RepoPatchV1 prim) wX wY) Source #

PrimPatch prim => CleanMerge (RepoPatchV2 prim) Source # 
Instance details

Defined in Darcs.Patch.V2.RepoPatch

Methods

cleanMerge :: (RepoPatchV2 prim :\/: RepoPatchV2 prim) wX wY -> Maybe ((RepoPatchV2 prim :/\: RepoPatchV2 prim) wX wY) Source #

CleanMerge p => CleanMerge (FL p) Source # 
Instance details

Defined in Darcs.Patch.Merge

Methods

cleanMerge :: (FL p :\/: FL p) wX wY -> Maybe ((FL p :/\: FL p) wX wY) Source #

(SignedId name, CleanMerge p) => CleanMerge (PrimWithName name p) Source # 
Instance details

Defined in Darcs.Patch.Prim.WithName

Methods

cleanMerge :: (PrimWithName name p :\/: PrimWithName name p) wX wY -> Maybe ((PrimWithName name p :/\: PrimWithName name p) wX wY) Source #

(SignedId name, StorableId name, PrimPatch prim) => CleanMerge (RepoPatchV3 name prim) Source # 
Instance details

Defined in Darcs.Patch.V3.Core

Methods

cleanMerge :: (RepoPatchV3 name prim :\/: RepoPatchV3 name prim) wX wY -> Maybe ((RepoPatchV3 name prim :/\: RepoPatchV3 name prim) wX wY) Source #

class CleanMerge p => Merge p where Source #

Patches that can always be merged, even if they conflict.

Instances should obey the following laws:

symmetry
merge (p :\/: q) == q' :/\: p' <=> merge (q :\/: p) == p' :/\: q'
merge-commute
merge (p :\/: q) == q' :/\: p' ==> commute (p :> q') == Just (q :> p')

that is, the two branches of a merge commute to each other.

extension
cleanMerge (p :\/: q) == Just (q' :/\: p') => merge (p :\/: q) == q' :/\: p'

that is, merge is an extension of cleanMerge.

Methods

merge :: (p :\/: p) wX wY -> (p :/\: p) wX wY Source #

Instances

Instances details
Merge p => Merge (Named p) Source # 
Instance details

Defined in Darcs.Patch.Named

Methods

merge :: (Named p :\/: Named p) wX wY -> (Named p :/\: Named p) wX wY Source #

(PatchId p ~ PatchInfo, Merge p) => Merge (PatchInfoAndG p) Source # 
Instance details

Defined in Darcs.Patch.PatchInfoAnd

PrimPatch prim => Merge (RepoPatchV1 prim) Source # 
Instance details

Defined in Darcs.Patch.V1.Commute

Methods

merge :: (RepoPatchV1 prim :\/: RepoPatchV1 prim) wX wY -> (RepoPatchV1 prim :/\: RepoPatchV1 prim) wX wY Source #

PrimPatch prim => Merge (RepoPatchV2 prim) Source # 
Instance details

Defined in Darcs.Patch.V2.RepoPatch

Methods

merge :: (RepoPatchV2 prim :\/: RepoPatchV2 prim) wX wY -> (RepoPatchV2 prim :/\: RepoPatchV2 prim) wX wY Source #

Merge p => Merge (FL p) Source # 
Instance details

Defined in Darcs.Patch.Merge

Methods

merge :: (FL p :\/: FL p) wX wY -> (FL p :/\: FL p) wX wY Source #

(SignedId name, StorableId name, PrimPatch prim) => Merge (RepoPatchV3 name prim) Source # 
Instance details

Defined in Darcs.Patch.V3.Core

Methods

merge :: (RepoPatchV3 name prim :\/: RepoPatchV3 name prim) wX wY -> (RepoPatchV3 name prim :/\: RepoPatchV3 name prim) wX wY Source #

Functions

selfMerger :: Merge p => MergeFn p p Source #

Synonym for merge.

swapMerger :: MergeFn p q -> MergeFn q p Source #

Swap the two patches, apply an arbitrary merge function, then swap again.

mergerIdFL :: MergeFn p q -> MergeFn p (FL q) Source #

Lift a merge function over p :/: q to a merge function over p :/: FL q

mergerFLId :: MergeFn p q -> MergeFn (FL p) q Source #

Lift a merge function over p :/: q to a merge function over FL p :/: q

mergerFLFL :: MergeFn p q -> MergeFn (FL p) (FL q) Source #

Lift a merge function over p :/: q to a merge function over FL p :/: FL q

cleanMergeFL :: CleanMerge p => PartialMergeFn p (FL p) Source #

Cleanly merge a single patch with an FL of patches.

mergeFL :: Merge p => (p :\/: FL p) wX wY -> (FL p :/\: p) wX wY Source #

swapMerge :: Merge p => (p :\/: p) wX wY -> (p :/\: p) wX wY Source #

Swap the two patches, merge, then swap again. Used to exploit prop_mergeSymmetric when defining merge.

swapCleanMerge :: CleanMerge p => (p :\/: p) wX wY -> Maybe ((p :/\: p) wX wY) Source #

Swap the two patches, cleanMerge, then swap again. Used to exploit prop_cleanMergeSymmetric when defining cleanMerge.

mergeList :: CleanMerge p => [Sealed (FL p wX)] -> Either (Sealed (FL p wX), Sealed (FL p wX)) (Sealed (FL p wX)) Source #

Combine a list of patch sequences, all starting at the same state, into a single sequence that also starts at the same state, using cleanMerge. If the merge fails, we return the two sequences that could not be merged so we can issue more detailed error messages.

Properties

prop_mergeSymmetric :: (Eq2 p, Merge p) => (p :\/: p) wX wY -> Bool Source #

Whether the given pair of patches satisfies the symmetry law.

prop_mergeCommute :: (Commute p, Eq2 p, Merge p) => (p :\/: p) wX wY -> Bool Source #

Whether the given pair of patches satisfies the merge-commute law.