-- Copyright (C) 2003-2004 David Roundy
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2, or (at your option)
-- any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; see the file COPYING.  If not, write to
-- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-- Boston, MA 02110-1301, USA.

{- | Definitions used in this module:

[Explicit dependencies]: The set of patches that a (named) patch depends on
  "by name", i.e. irrespective of (non-)commutation (non commuting patches are
  implicit dependencies). The most important example are tags, but non-tag
  patches can also have explicit dependencies by recording them with
  --ask-deps.

[Covered]: A patch @p@ is covered by a tag @t@ if @t@ explicitly depends on
  @p@ or a tag covered by @t@ explicitly depends on @p@. In other words, the
  transitive closure of the relation "is depended on", restricted to
  situations where the right hand side is a tag. Note that it does /not/ take
  explicit dependencies of non-tag patches into account at all.

[Clean]: A tag @t@ in a repository is clean if all patches prior to the tag are
  covered by @t@. Tags normally start out as clean tags (the exception is
  if --ask-deps is used). It typically becomes unclean when it is merged into
  another repo (here the exceptions are if --reorder-patches is used, or if
  the target repo is actually a subset of the source repo).
-}

module Darcs.Patch.Depends
    ( getUncovered
    , areUnrelatedRepos
    , findCommonAndUncommon
    , mergeThem
    , findCommonWithThem
    , countUsThem
    , removeFromPatchSet
    , slightlyOptimizePatchset
    , splitOnTag
    , patchSetUnion
    , patchSetIntersection
    , findUncommon
    , cleanLatestTag
    , contextPatches
    ) where

import Darcs.Prelude

import Data.List ( delete, intersect, (\\) )
import Data.Maybe ( fromMaybe )

import Darcs.Patch.Named ( getdeps )
import Darcs.Patch.Commute ( Commute )
import Darcs.Patch.Ident ( fastRemoveSubsequenceRL, merge2FL )
import Darcs.Patch.Info ( PatchInfo, isTag, displayPatchInfo )
import Darcs.Patch.Merge ( Merge )
import Darcs.Patch.Permutations ( partitionFL, partitionRL )
import Darcs.Patch.PatchInfoAnd( PatchInfoAnd, hopefully, hopefullyM, info )
import Darcs.Patch.Set
    ( PatchSet(..)
    , Tagged(..)
    , SealedPatchSet
    , patchSet2RL
    , appendPSFL
    , patchSetSplit
    , Origin
    )
import Darcs.Patch.Progress ( progressRL )
import Darcs.Patch.Witnesses.Unsafe ( unsafeCoerceP, unsafeCoercePStart )
import Darcs.Patch.Witnesses.Eq ( Eq2 )
import Darcs.Patch.Witnesses.Ordered
    ( (:\/:)(..), (:/\:)(..), (:>)(..), Fork(..),
    (+<<+), mapFL, RL(..), FL(..), isShorterThanRL, breakRL,
    (+<+), reverseFL, reverseRL, mapRL )
import Darcs.Patch.Witnesses.Sealed
    ( Sealed(..), seal )

import Darcs.Util.Printer ( renderString, vcat )

{-|
Find clean tags that are common to both argument 'PatchSet's and return a
'Fork' with the common clean tags and whatever remains of the 'PatchSet's.
The two "uncommon" sequences may still have patches in common, even clean
tags, since we look only at the "known clean" tags of the second argument,
i.e. those that are the head of a 'Tagged' section.

This is a pretty efficient function, because it makes use of the
already-broken-up nature of 'PatchSet's.

Note that the first argument should be the repository that is more cheaply
accessed (i.e. local), as 'taggedIntersection' does its best to reduce the
number of inventories that are accessed from its second argument.
-}
taggedIntersection :: forall rt p wX wY . Commute p
                   => PatchSet rt p Origin wX -> PatchSet rt p Origin wY ->
                      Fork (RL (Tagged rt p))
                           (RL (PatchInfoAnd rt p))
                           (RL (PatchInfoAnd rt p)) Origin wX wY
taggedIntersection :: forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
Commute p =>
PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     Origin
     wX
     wY
taggedIntersection (PatchSet RL (Tagged rt p) Origin wX
NilRL RL (PatchInfoAnd rt p) wX wX
ps1) PatchSet rt p Origin wY
s2 = forall (common :: * -> * -> *) (left :: * -> * -> *)
       (right :: * -> * -> *) wA wX wY wU.
common wA wU
-> left wU wX -> right wU wY -> Fork common left right wA wX wY
Fork forall (a :: * -> * -> *) wX. RL a wX wX
NilRL RL (PatchInfoAnd rt p) wX wX
ps1 (forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchSet rt p wStart wX -> RL (PatchInfoAnd rt p) wStart wX
patchSet2RL PatchSet rt p Origin wY
s2)
taggedIntersection PatchSet rt p Origin wX
s1 (PatchSet RL (Tagged rt p) Origin wX
NilRL RL (PatchInfoAnd rt p) wX wY
ps2) = forall (common :: * -> * -> *) (left :: * -> * -> *)
       (right :: * -> * -> *) wA wX wY wU.
common wA wU
-> left wU wX -> right wU wY -> Fork common left right wA wX wY
Fork forall (a :: * -> * -> *) wX. RL a wX wX
NilRL (forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchSet rt p wStart wX -> RL (PatchInfoAnd rt p) wStart wX
patchSet2RL PatchSet rt p Origin wX
s1) RL (PatchInfoAnd rt p) wX wY
ps2
taggedIntersection PatchSet rt p Origin wX
s1 (PatchSet (RL (Tagged rt p) Origin wY
_ :<: Tagged PatchInfoAnd rt p wY wX
t2 Maybe String
_ RL (PatchInfoAnd rt p) wY wY
_) RL (PatchInfoAnd rt p) wX wY
ps2)
    -- If t2 is the head of any of the Tagged sections of s1,
    -- unwrap everything in s1 after t2 and be done with it.
    | Just (PatchSet RL (Tagged rt p) Origin wX
ts1 RL (PatchInfoAnd rt p) wX wX
ps1) <- forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchInfo
-> PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
maybeSplitSetOnTag (forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wX
t2) PatchSet rt p Origin wX
s1 =
        forall (common :: * -> * -> *) (left :: * -> * -> *)
       (right :: * -> * -> *) wA wX wY wU.
common wA wU
-> left wU wX -> right wU wY -> Fork common left right wA wX wY
Fork RL (Tagged rt p) Origin wX
ts1 RL (PatchInfoAnd rt p) wX wX
ps1 (forall (a :: * -> * -> *) wX1 wY wX2. a wX1 wY -> a wX2 wY
unsafeCoercePStart RL (PatchInfoAnd rt p) wX wY
ps2)
taggedIntersection PatchSet rt p Origin wX
s1 s2 :: PatchSet rt p Origin wY
s2@(PatchSet (RL (Tagged rt p) Origin wY
ts2 :<: Tagged PatchInfoAnd rt p wY wX
t2 Maybe String
_ RL (PatchInfoAnd rt p) wY wY
t2ps) RL (PatchInfoAnd rt p) wX wY
ps2) =
    -- Same case as before but now we know that t2 is not the head of any
    -- Tagged section of s1. If t2 has already been fully retrieved, then
    -- we know that the next Tagged section of s2 is available without
    -- opening another remote inventory; in this case we recurse i.e.
    -- we unwrap t2 and its patches and continue with the next Tagged of s2.
    -- Otherwise we try to make t2 clean in s1 by looking at s1's trailing
    -- patch list, too.
    -- Question by bf: Wouldn't it be better to call splitOnTag /before/ we
    -- test if t2 has already been opened? If it succeeds, then we'd get
    -- more common Tagged sections and still don't have to open a remote
    -- inventory.
    case forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> Maybe (p wA wB)
hopefullyM PatchInfoAnd rt p wY wX
t2 of
        Just Named p wY wX
_ ->
            forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
Commute p =>
PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     Origin
     wX
     wY
taggedIntersection PatchSet rt p Origin wX
s1 (forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wY
ts2 (RL (PatchInfoAnd rt p) wY wY
t2ps forall (a :: * -> * -> *) wX wX wZ.
RL a wX wX -> a wX wZ -> RL a wX wZ
:<: PatchInfoAnd rt p wY wX
t2 forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> RL a wY wZ -> RL a wX wZ
+<+ RL (PatchInfoAnd rt p) wX wY
ps2))
        Maybe (Named p wY wX)
Nothing ->
            case forall (p :: * -> * -> *) (rt :: RepoType) wStart wX.
Commute p =>
PatchInfo
-> PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
splitOnTag (forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wX
t2) PatchSet rt p Origin wX
s1 of
                Just (PatchSet RL (Tagged rt p) Origin wX
com RL (PatchInfoAnd rt p) wX wX
us) ->
                      forall (common :: * -> * -> *) (left :: * -> * -> *)
       (right :: * -> * -> *) wA wX wY wU.
common wA wU
-> left wU wX -> right wU wY -> Fork common left right wA wX wY
Fork RL (Tagged rt p) Origin wX
com RL (PatchInfoAnd rt p) wX wX
us (forall (a :: * -> * -> *) wX1 wY wX2. a wX1 wY -> a wX2 wY
unsafeCoercePStart RL (PatchInfoAnd rt p) wX wY
ps2)
                Maybe (PatchSet rt p Origin wX)
Nothing -> forall (common :: * -> * -> *) (left :: * -> * -> *)
       (right :: * -> * -> *) wA wX wY wU.
common wA wU
-> left wU wX -> right wU wY -> Fork common left right wA wX wY
Fork forall (a :: * -> * -> *) wX. RL a wX wX
NilRL (forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchSet rt p wStart wX -> RL (PatchInfoAnd rt p) wStart wX
patchSet2RL PatchSet rt p Origin wX
s1) (forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchSet rt p wStart wX -> RL (PatchInfoAnd rt p) wStart wX
patchSet2RL PatchSet rt p Origin wY
s2)

-- |'maybeSplitSetOnTag' takes a tag's 'PatchInfo', @t0@, and a 'PatchSet' and
-- attempts to find @t0@ in one of the 'Tagged's in the PatchSet. If the tag is
-- found, the 'PatchSet' is split up, on that tag, such that all later patches
-- are in the "since last tag" patch list. If the tag is not found, 'Nothing'
-- is returned.
-- This is a simpler version of 'splitOnTag' that only looks at the heads
-- of 'Tagged' sections and does not commute any patches.
maybeSplitSetOnTag :: PatchInfo -> PatchSet rt p wStart wX
                   -> Maybe (PatchSet rt p wStart wX)
maybeSplitSetOnTag :: forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchInfo
-> PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
maybeSplitSetOnTag PatchInfo
t0 origSet :: PatchSet rt p wStart wX
origSet@(PatchSet (RL (Tagged rt p) Origin wY
ts :<: Tagged PatchInfoAnd rt p wY wX
t Maybe String
_ RL (PatchInfoAnd rt p) wY wY
pst) RL (PatchInfoAnd rt p) wX wX
ps)
    | PatchInfo
t0 forall a. Eq a => a -> a -> Bool
== forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wX
t = forall a. a -> Maybe a
Just PatchSet rt p wStart wX
origSet
    | Bool
otherwise = do
        PatchSet RL (Tagged rt p) Origin wX
ts' RL (PatchInfoAnd rt p) wX wX
ps' <- forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchInfo
-> PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
maybeSplitSetOnTag PatchInfo
t0 (forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wY
ts (RL (PatchInfoAnd rt p) wY wY
pst forall (a :: * -> * -> *) wX wX wZ.
RL a wX wX -> a wX wZ -> RL a wX wZ
:<: PatchInfoAnd rt p wY wX
t))
        forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wX
ts' (RL (PatchInfoAnd rt p) wX wX
ps' forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> RL a wY wZ -> RL a wX wZ
+<+ RL (PatchInfoAnd rt p) wX wX
ps)
maybeSplitSetOnTag PatchInfo
_ PatchSet rt p wStart wX
_ = forall a. Maybe a
Nothing

-- | Take a tag's 'PatchInfo', and a 'PatchSet', and attempt to find the tag in
-- the 'PatchSet'. If found, return a new 'PatchSet', in which the tag is now
-- clean (and the last of the 'Tagged' list), while all patches that are not
-- covered by the tag are in the trailing list of patches.
-- If the tag is not in the 'PatchSet', we return 'Nothing'.
splitOnTag :: Commute p => PatchInfo -> PatchSet rt p wStart wX
           -> Maybe (PatchSet rt p wStart wX)
-- If the tag we are looking for is the first Tagged tag of the patchset, just
-- separate out the patchset's patches.
splitOnTag :: forall (p :: * -> * -> *) (rt :: RepoType) wStart wX.
Commute p =>
PatchInfo
-> PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
splitOnTag PatchInfo
t s :: PatchSet rt p wStart wX
s@(PatchSet (RL (Tagged rt p) Origin wY
_ :<: Tagged PatchInfoAnd rt p wY wX
hp Maybe String
_ RL (PatchInfoAnd rt p) wY wY
_) RL (PatchInfoAnd rt p) wX wX
_) | forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wX
hp forall a. Eq a => a -> a -> Bool
== PatchInfo
t = forall a. a -> Maybe a
Just PatchSet rt p wStart wX
s
-- If the tag is the most recent patch in the set, we check if the patch is the
-- only non-depended-on patch in the set (i.e. it is a clean tag); creating a
-- new Tagged out of the patches and tag, and adding it to the patchset, if
-- this is the case. Otherwise, we try to make the tag clean.
splitOnTag PatchInfo
t patchset :: PatchSet rt p wStart wX
patchset@(PatchSet RL (Tagged rt p) Origin wX
ts hps :: RL (PatchInfoAnd rt p) wX wX
hps@(RL (PatchInfoAnd rt p) wX wY
ps :<: PatchInfoAnd rt p wY wX
hp)) | forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wX
hp forall a. Eq a => a -> a -> Bool
== PatchInfo
t =
    if forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchSet rt p wStart wX -> [PatchInfo]
getUncovered PatchSet rt p wStart wX
patchset forall a. Eq a => a -> a -> Bool
== [PatchInfo
t]
        -- If t is the only patch not covered by any tag...
        then forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet (RL (Tagged rt p) Origin wX
ts forall (a :: * -> * -> *) wX wX wZ.
RL a wX wX -> a wX wZ -> RL a wX wZ
:<: forall (rt :: RepoType) (p :: * -> * -> *) wX wZ wX.
PatchInfoAnd rt p wX wZ
-> Maybe String
-> RL (PatchInfoAnd rt p) wX wX
-> Tagged rt p wX wZ
Tagged PatchInfoAnd rt p wY wX
hp forall a. Maybe a
Nothing RL (PatchInfoAnd rt p) wX wY
ps) forall (a :: * -> * -> *) wX. RL a wX wX
NilRL
        else case forall (p :: * -> * -> *) wX wY.
Commute p =>
(forall wU wV. p wU wV -> Bool)
-> RL p wX wY -> (:>) (RL p) (RL p) wX wY
partitionRL ((forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` (PatchInfo
t forall a. a -> [a] -> [a]
: forall (p :: * -> * -> *) wX wY.
HasDeps p =>
p wX wY -> [PatchInfo]
getdeps (forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> p wA wB
hopefully PatchInfoAnd rt p wY wX
hp))) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info) RL (PatchInfoAnd rt p) wX wX
hps of
            -- Partition hps by those that are the tag and its explicit deps.
            tagAndDeps :: RL (PatchInfoAnd rt p) wX wZ
tagAndDeps@(RL (PatchInfoAnd rt p) wX wY
ds' :<: PatchInfoAnd rt p wY wZ
hp') :> RL (PatchInfoAnd rt p) wZ wX
nonDeps ->
                -- If @ds@ doesn't contain the tag of the first Tagged, that
                -- tag will also be returned by the call to getUncovered - so
                -- we need to unwrap the next Tagged in order to expose it to
                -- being partitioned out in the recursive call to splitOnTag.
                if forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchSet rt p wStart wX -> [PatchInfo]
getUncovered (forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wX
ts RL (PatchInfoAnd rt p) wX wZ
tagAndDeps) forall a. Eq a => a -> a -> Bool
== [PatchInfo
t]
                    then let tagged :: Tagged rt p wX wZ
tagged = forall (rt :: RepoType) (p :: * -> * -> *) wX wZ wX.
PatchInfoAnd rt p wX wZ
-> Maybe String
-> RL (PatchInfoAnd rt p) wX wX
-> Tagged rt p wX wZ
Tagged PatchInfoAnd rt p wY wZ
hp' forall a. Maybe a
Nothing RL (PatchInfoAnd rt p) wX wY
ds' in
                         forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet (RL (Tagged rt p) Origin wX
ts forall (a :: * -> * -> *) wX wX wZ.
RL a wX wX -> a wX wZ -> RL a wX wZ
:<: Tagged rt p wX wZ
tagged) RL (PatchInfoAnd rt p) wZ wX
nonDeps
                    else do
                        PatchSet rt p Origin wZ
unfolded <- forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
PatchSet rt p wX wY -> Maybe (PatchSet rt p wX wY)
unwrapOneTagged forall a b. (a -> b) -> a -> b
$ forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wX
ts RL (PatchInfoAnd rt p) wX wZ
tagAndDeps
                        PatchSet RL (Tagged rt p) Origin wX
xx RL (PatchInfoAnd rt p) wX wZ
yy <- forall (p :: * -> * -> *) (rt :: RepoType) wStart wX.
Commute p =>
PatchInfo
-> PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
splitOnTag PatchInfo
t PatchSet rt p Origin wZ
unfolded
                        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wX
xx (RL (PatchInfoAnd rt p) wX wZ
yy forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> RL a wY wZ -> RL a wX wZ
+<+ RL (PatchInfoAnd rt p) wZ wX
nonDeps)
            (:>) (RL (PatchInfoAnd rt p)) (RL (PatchInfoAnd rt p)) wX wX
_ -> forall a. HasCallStack => String -> a
error String
"impossible case"
-- We drop the leading patch, to try and find a non-Tagged tag.
splitOnTag PatchInfo
t (PatchSet RL (Tagged rt p) Origin wX
ts (RL (PatchInfoAnd rt p) wX wY
ps :<: PatchInfoAnd rt p wY wX
p)) = do
    PatchSet RL (Tagged rt p) Origin wX
ns RL (PatchInfoAnd rt p) wX wY
xs <- forall (p :: * -> * -> *) (rt :: RepoType) wStart wX.
Commute p =>
PatchInfo
-> PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
splitOnTag PatchInfo
t (forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wX
ts RL (PatchInfoAnd rt p) wX wY
ps)
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wX
ns (RL (PatchInfoAnd rt p) wX wY
xs forall (a :: * -> * -> *) wX wX wZ.
RL a wX wX -> a wX wZ -> RL a wX wZ
:<: PatchInfoAnd rt p wY wX
p)
-- If there are no patches left, we "unfold" the next Tagged, and try again.
splitOnTag PatchInfo
t0 patchset :: PatchSet rt p wStart wX
patchset@(PatchSet (RL (Tagged rt p) Origin wY
_ :<: Tagged PatchInfoAnd rt p wY wX
_ Maybe String
_ RL (PatchInfoAnd rt p) wY wY
_s) RL (PatchInfoAnd rt p) wX wX
NilRL) =
    forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
PatchSet rt p wX wY -> Maybe (PatchSet rt p wX wY)
unwrapOneTagged PatchSet rt p wStart wX
patchset forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (p :: * -> * -> *) (rt :: RepoType) wStart wX.
Commute p =>
PatchInfo
-> PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
splitOnTag PatchInfo
t0
-- If we've checked all the patches, but haven't found the tag, return Nothing.
splitOnTag PatchInfo
_ (PatchSet RL (Tagged rt p) Origin wX
NilRL RL (PatchInfoAnd rt p) wX wX
NilRL) = forall a. Maybe a
Nothing

-- | Reorder a 'PatchSet' such that the latest tag becomes clean.
cleanLatestTag :: Commute p
               => PatchSet rt p wStart wX
               -> PatchSet rt p wStart wX
cleanLatestTag :: forall (p :: * -> * -> *) (rt :: RepoType) wStart wX.
Commute p =>
PatchSet rt p wStart wX -> PatchSet rt p wStart wX
cleanLatestTag inp :: PatchSet rt p wStart wX
inp@(PatchSet RL (Tagged rt p) Origin wX
ts RL (PatchInfoAnd rt p) wX wX
ps) =
  case forall (p :: * -> * -> *) wX wY.
(forall wA wB. p wA wB -> Bool)
-> RL p wX wY -> (:>) (RL p) (RL p) wX wY
breakRL (PatchInfo -> Bool
isTag forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info) RL (PatchInfoAnd rt p) wX wX
ps of
    RL (PatchInfoAnd rt p) wX wZ
NilRL :> RL (PatchInfoAnd rt p) wZ wX
_ -> PatchSet rt p wStart wX
inp -- no tag among the ps -> we are done
    (left :: RL (PatchInfoAnd rt p) wX wZ
left@(RL (PatchInfoAnd rt p) wX wY
_ :<: PatchInfoAnd rt p wY wZ
t) :> RL (PatchInfoAnd rt p) wZ wX
right) ->
      case forall (p :: * -> * -> *) (rt :: RepoType) wStart wX.
Commute p =>
PatchInfo
-> PatchSet rt p wStart wX -> Maybe (PatchSet rt p wStart wX)
splitOnTag (forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wZ
t) (forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wX
ts RL (PatchInfoAnd rt p) wX wZ
left) of
        Just (PatchSet RL (Tagged rt p) Origin wX
ts' RL (PatchInfoAnd rt p) wX wZ
ps') -> forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wX
ts' (RL (PatchInfoAnd rt p) wX wZ
ps' forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> RL a wY wZ -> RL a wX wZ
+<+ RL (PatchInfoAnd rt p) wZ wX
right)
        Maybe (PatchSet rt p Origin wZ)
_ -> forall a. HasCallStack => String -> a
error String
"impossible case" -- because t is in left

-- |'unwrapOneTagged' unfolds a single Tagged object in a PatchSet, adding the
-- tag and patches to the PatchSet's patch list.
unwrapOneTagged :: PatchSet rt p wX wY -> Maybe (PatchSet rt p wX wY)
unwrapOneTagged :: forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
PatchSet rt p wX wY -> Maybe (PatchSet rt p wX wY)
unwrapOneTagged (PatchSet (RL (Tagged rt p) Origin wY
ts :<: Tagged PatchInfoAnd rt p wY wX
t Maybe String
_ RL (PatchInfoAnd rt p) wY wY
tps) RL (PatchInfoAnd rt p) wX wY
ps) =
    forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wY
ts (RL (PatchInfoAnd rt p) wY wY
tps forall (a :: * -> * -> *) wX wX wZ.
RL a wX wX -> a wX wZ -> RL a wX wZ
:<: PatchInfoAnd rt p wY wX
t forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> RL a wY wZ -> RL a wX wZ
+<+ RL (PatchInfoAnd rt p) wX wY
ps)
unwrapOneTagged PatchSet rt p wX wY
_ = forall a. Maybe a
Nothing

-- | Return the 'PatchInfo' for all the patches in a 'PatchSet'
-- that are not depended on by any tag (in the given 'PatchSet').
--
-- This is exactly the set of patches that a new tag recorded on top
-- of the 'PatchSet' would explicitly depend on.
getUncovered :: PatchSet rt p wStart wX -> [PatchInfo]
getUncovered :: forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchSet rt p wStart wX -> [PatchInfo]
getUncovered PatchSet rt p wStart wX
patchset = case PatchSet rt p wStart wX
patchset of
    (PatchSet RL (Tagged rt p) Origin wX
NilRL RL (PatchInfoAnd rt p) wX wX
ps) -> [(PatchInfo, Maybe [PatchInfo])] -> [PatchInfo]
findUncovered (forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
PatchInfoAnd rt p wX wY -> (PatchInfo, Maybe [PatchInfo])
infoAndExplicitDeps RL (PatchInfoAnd rt p) wX wX
ps)
    (PatchSet (RL (Tagged rt p) Origin wY
_ :<: Tagged PatchInfoAnd rt p wY wX
t Maybe String
_ RL (PatchInfoAnd rt p) wY wY
_) RL (PatchInfoAnd rt p) wX wX
ps) ->
        [(PatchInfo, Maybe [PatchInfo])] -> [PatchInfo]
findUncovered (forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
PatchInfoAnd rt p wX wY -> (PatchInfo, Maybe [PatchInfo])
infoAndExplicitDeps (forall (a :: * -> * -> *) wX. RL a wX wX
NilRL forall (a :: * -> * -> *) wX wX wZ.
RL a wX wX -> a wX wZ -> RL a wX wZ
:<: PatchInfoAnd rt p wY wX
t forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> RL a wY wZ -> RL a wX wZ
+<+ RL (PatchInfoAnd rt p) wX wX
ps))
  where
    findUncovered :: [(PatchInfo, Maybe [PatchInfo])] -> [PatchInfo]
    findUncovered :: [(PatchInfo, Maybe [PatchInfo])] -> [PatchInfo]
findUncovered [] = []
    findUncovered ((PatchInfo
pi, Maybe [PatchInfo]
Nothing) : [(PatchInfo, Maybe [PatchInfo])]
rest) = PatchInfo
pi forall a. a -> [a] -> [a]
: [(PatchInfo, Maybe [PatchInfo])] -> [PatchInfo]
findUncovered [(PatchInfo, Maybe [PatchInfo])]
rest
    findUncovered ((PatchInfo
pi, Just [PatchInfo]
deps) : [(PatchInfo, Maybe [PatchInfo])]
rest) =
        PatchInfo
pi forall a. a -> [a] -> [a]
: [(PatchInfo, Maybe [PatchInfo])] -> [PatchInfo]
findUncovered ([PatchInfo]
-> [(PatchInfo, Maybe [PatchInfo])]
-> [(PatchInfo, Maybe [PatchInfo])]
dropDepsIn [PatchInfo]
deps [(PatchInfo, Maybe [PatchInfo])]
rest)

    -- |dropDepsIn traverses the list of patches, dropping any patches that
    -- occur in the dependency list; when a patch is dropped, its dependencies
    -- are added to the dependency list used for later patches.
    dropDepsIn :: [PatchInfo] -> [(PatchInfo, Maybe [PatchInfo])]
               -> [(PatchInfo, Maybe [PatchInfo])]
    dropDepsIn :: [PatchInfo]
-> [(PatchInfo, Maybe [PatchInfo])]
-> [(PatchInfo, Maybe [PatchInfo])]
dropDepsIn [] [(PatchInfo, Maybe [PatchInfo])]
pps = [(PatchInfo, Maybe [PatchInfo])]
pps
    dropDepsIn [PatchInfo]
_  []  = []
    dropDepsIn [PatchInfo]
ds ((PatchInfo, Maybe [PatchInfo])
hp : [(PatchInfo, Maybe [PatchInfo])]
pps)
        | forall a b. (a, b) -> a
fst (PatchInfo, Maybe [PatchInfo])
hp forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [PatchInfo]
ds =
            let extraDeps :: [PatchInfo]
extraDeps = forall a. a -> Maybe a -> a
fromMaybe [] forall a b. (a -> b) -> a -> b
$ forall a b. (a, b) -> b
snd (PatchInfo, Maybe [PatchInfo])
hp in
            [PatchInfo]
-> [(PatchInfo, Maybe [PatchInfo])]
-> [(PatchInfo, Maybe [PatchInfo])]
dropDepsIn ([PatchInfo]
extraDeps forall a. [a] -> [a] -> [a]
++ forall a. Eq a => a -> [a] -> [a]
delete (forall a b. (a, b) -> a
fst (PatchInfo, Maybe [PatchInfo])
hp) [PatchInfo]
ds) [(PatchInfo, Maybe [PatchInfo])]
pps
        | Bool
otherwise = (PatchInfo, Maybe [PatchInfo])
hp forall a. a -> [a] -> [a]
: [PatchInfo]
-> [(PatchInfo, Maybe [PatchInfo])]
-> [(PatchInfo, Maybe [PatchInfo])]
dropDepsIn [PatchInfo]
ds [(PatchInfo, Maybe [PatchInfo])]
pps

    -- |infoAndExplicitDeps returns the patch info and (for tags only) the list
    -- of explicit dependencies of a patch.
    infoAndExplicitDeps :: PatchInfoAnd rt p wX wY
                        -> (PatchInfo, Maybe [PatchInfo])
    infoAndExplicitDeps :: forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
PatchInfoAnd rt p wX wY -> (PatchInfo, Maybe [PatchInfo])
infoAndExplicitDeps PatchInfoAnd rt p wX wY
p
        | PatchInfo -> Bool
isTag (forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wX wY
p) = (forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wX wY
p, forall (p :: * -> * -> *) wX wY.
HasDeps p =>
p wX wY -> [PatchInfo]
getdeps forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> Maybe (p wA wB)
hopefullyM PatchInfoAnd rt p wX wY
p)
        | Bool
otherwise = (forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wX wY
p, forall a. Maybe a
Nothing)

-- | Create a new 'Tagged' section for the most recent clean tag found in the
-- tail of un-'Tagged' patches without re-ordering patches. Note that earlier
-- tags may remain un-'Tagged' even if they are actually clean.
slightlyOptimizePatchset :: PatchSet rt p wStart wX -> PatchSet rt p wStart wX
slightlyOptimizePatchset :: forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchSet rt p wStart wX -> PatchSet rt p wStart wX
slightlyOptimizePatchset (PatchSet RL (Tagged rt p) Origin wX
ts0 RL (PatchInfoAnd rt p) wX wX
ps0) =
    forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchSet rt p wStart wX -> PatchSet rt p wStart wX
go forall a b. (a -> b) -> a -> b
$ forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wX
ts0 (forall (a :: * -> * -> *) wX wY. String -> RL a wX wY -> RL a wX wY
progressRL String
"Optimizing inventory" RL (PatchInfoAnd rt p) wX wX
ps0)
  where
    go :: PatchSet rt p wStart wY -> PatchSet rt p wStart wY
    go :: forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchSet rt p wStart wX -> PatchSet rt p wStart wX
go (PatchSet RL (Tagged rt p) Origin wX
ts RL (PatchInfoAnd rt p) wX wY
NilRL) = forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wX
ts forall (a :: * -> * -> *) wX. RL a wX wX
NilRL
    go s :: PatchSet rt p wStart wY
s@(PatchSet RL (Tagged rt p) Origin wX
ts (RL (PatchInfoAnd rt p) wX wY
ps :<: PatchInfoAnd rt p wY wY
hp))
        | PatchInfo -> Bool
isTag (forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wY
hp)
        , [forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wY wY
hp] forall a. Eq a => a -> a -> Bool
== forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchSet rt p wStart wX -> [PatchInfo]
getUncovered PatchSet rt p wStart wY
s =
            forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet (RL (Tagged rt p) Origin wX
ts forall (a :: * -> * -> *) wX wX wZ.
RL a wX wX -> a wX wZ -> RL a wX wZ
:<: forall (rt :: RepoType) (p :: * -> * -> *) wX wZ wX.
PatchInfoAnd rt p wX wZ
-> Maybe String
-> RL (PatchInfoAnd rt p) wX wX
-> Tagged rt p wX wZ
Tagged PatchInfoAnd rt p wY wY
hp forall a. Maybe a
Nothing RL (PatchInfoAnd rt p) wX wY
ps) forall (a :: * -> * -> *) wX. RL a wX wX
NilRL
        | Bool
otherwise = forall (rt :: RepoType) (p :: * -> * -> *) wStart wX wY.
PatchSet rt p wStart wX
-> FL (PatchInfoAnd rt p) wX wY -> PatchSet rt p wStart wY
appendPSFL (forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchSet rt p wStart wX -> PatchSet rt p wStart wX
go (forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wX
ts RL (PatchInfoAnd rt p) wX wY
ps)) (PatchInfoAnd rt p wY wY
hp forall (a :: * -> * -> *) wX wX wZ.
a wX wX -> FL a wX wZ -> FL a wX wZ
:>: forall (a :: * -> * -> *) wX. FL a wX wX
NilFL)

removeFromPatchSet :: (Commute p, Eq2 p) => FL (PatchInfoAnd rt p) wX wY
                   -> PatchSet rt p wStart wY -> Maybe (PatchSet rt p wStart wX)
removeFromPatchSet :: forall (p :: * -> * -> *) (rt :: RepoType) wX wY wStart.
(Commute p, Eq2 p) =>
FL (PatchInfoAnd rt p) wX wY
-> PatchSet rt p wStart wY -> Maybe (PatchSet rt p wStart wX)
removeFromPatchSet FL (PatchInfoAnd rt p) wX wY
bad (PatchSet RL (Tagged rt p) Origin wX
ts RL (PatchInfoAnd rt p) wX wY
ps) | forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info RL (PatchInfoAnd rt p) wX wY
ps) (forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> FL a wX wY -> [b]
mapFL forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info FL (PatchInfoAnd rt p) wX wY
bad) = do
    RL (PatchInfoAnd rt p) wX wX
ps' <- forall (p :: * -> * -> *) wY wZ wX.
(Commute p, Ident p) =>
RL p wY wZ -> RL p wX wZ -> Maybe (RL p wX wY)
fastRemoveSubsequenceRL (forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> RL a wX wZ
reverseFL FL (PatchInfoAnd rt p) wX wY
bad) RL (PatchInfoAnd rt p) wX wY
ps
    forall (m :: * -> *) a. Monad m => a -> m a
return (forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wX
ts RL (PatchInfoAnd rt p) wX wX
ps')
removeFromPatchSet FL (PatchInfoAnd rt p) wX wY
_ (PatchSet RL (Tagged rt p) Origin wX
NilRL RL (PatchInfoAnd rt p) wX wY
_) = forall a. Maybe a
Nothing
removeFromPatchSet FL (PatchInfoAnd rt p) wX wY
bad (PatchSet (RL (Tagged rt p) Origin wY
ts :<: Tagged PatchInfoAnd rt p wY wX
t Maybe String
_ RL (PatchInfoAnd rt p) wY wY
tps) RL (PatchInfoAnd rt p) wX wY
ps) =
    forall (p :: * -> * -> *) (rt :: RepoType) wX wY wStart.
(Commute p, Eq2 p) =>
FL (PatchInfoAnd rt p) wX wY
-> PatchSet rt p wStart wY -> Maybe (PatchSet rt p wStart wX)
removeFromPatchSet FL (PatchInfoAnd rt p) wX wY
bad (forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wY
ts (RL (PatchInfoAnd rt p) wY wY
tps forall (a :: * -> * -> *) wX wX wZ.
RL a wX wX -> a wX wZ -> RL a wX wZ
:<: PatchInfoAnd rt p wY wX
t forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> RL a wY wZ -> RL a wX wZ
+<+ RL (PatchInfoAnd rt p) wX wY
ps))

findCommonAndUncommon :: forall rt p wX wY . Commute p
                      => PatchSet rt p Origin wX -> PatchSet rt p Origin wY
                      -> Fork (PatchSet rt p)
                              (FL (PatchInfoAnd rt p))
                              (FL (PatchInfoAnd rt p)) Origin wX wY
findCommonAndUncommon :: forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
Commute p =>
PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> Fork
     (PatchSet rt p)
     (FL (PatchInfoAnd rt p))
     (FL (PatchInfoAnd rt p))
     Origin
     wX
     wY
findCommonAndUncommon PatchSet rt p Origin wX
us PatchSet rt p Origin wY
them = case forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
Commute p =>
PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     Origin
     wX
     wY
taggedIntersection PatchSet rt p Origin wX
us PatchSet rt p Origin wY
them of
    Fork RL (Tagged rt p) Origin wU
common RL (PatchInfoAnd rt p) wU wX
us' RL (PatchInfoAnd rt p) wU wY
them' ->
        case forall (p :: * -> * -> *) wX wY.
Commute p =>
(forall wU wV. p wU wV -> Bool)
-> FL p wX wY -> (:>) (FL p) (FL p :> FL p) wX wY
partitionFL (forall {rt :: RepoType} {p :: * -> * -> *} {wX} {wY}
       {rt :: RepoType} {p :: * -> * -> *} {wA} {wB}.
RL (PatchInfoAndG rt p) wX wY -> PatchInfoAndG rt p wA wB -> Bool
infoIn RL (PatchInfoAnd rt p) wU wY
them') forall a b. (a -> b) -> a -> b
$ forall (a :: * -> * -> *) wX wZ. RL a wX wZ -> FL a wX wZ
reverseRL RL (PatchInfoAnd rt p) wU wX
us' of
            FL (PatchInfoAnd rt p) wU wZ
_ :> bad :: FL (PatchInfoAnd rt p) wZ wZ
bad@(PatchInfoAnd rt p wZ wY
_ :>: FL (PatchInfoAnd rt p) wY wZ
_) :> FL (PatchInfoAnd rt p) wZ wX
_ ->
                forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"Failed to commute common patches:\n"
                      forall a. [a] -> [a] -> [a]
++ Doc -> String
renderString
                          ([Doc] -> Doc
vcat forall a b. (a -> b) -> a -> b
$ forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL (PatchInfo -> Doc
displayPatchInfo forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info) forall a b. (a -> b) -> a -> b
$ forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> RL a wX wZ
reverseFL FL (PatchInfoAnd rt p) wZ wZ
bad)
            (FL (PatchInfoAnd rt p) wU wZ
common2 :> FL (PatchInfoAnd rt p) wZ wZ
NilFL :> FL (PatchInfoAnd rt p) wZ wX
only_ours) ->
                case forall (p :: * -> * -> *) wX wY.
Commute p =>
(forall wU wV. p wU wV -> Bool)
-> FL p wX wY -> (:>) (FL p) (FL p :> FL p) wX wY
partitionFL (forall {rt :: RepoType} {p :: * -> * -> *} {wX} {wY}
       {rt :: RepoType} {p :: * -> * -> *} {wA} {wB}.
RL (PatchInfoAndG rt p) wX wY -> PatchInfoAndG rt p wA wB -> Bool
infoIn RL (PatchInfoAnd rt p) wU wX
us') forall a b. (a -> b) -> a -> b
$ forall (a :: * -> * -> *) wX wZ. RL a wX wZ -> FL a wX wZ
reverseRL RL (PatchInfoAnd rt p) wU wY
them' of
                    FL (PatchInfoAnd rt p) wU wZ
_ :> bad :: FL (PatchInfoAnd rt p) wZ wZ
bad@(PatchInfoAnd rt p wZ wY
_ :>: FL (PatchInfoAnd rt p) wY wZ
_) :> FL (PatchInfoAnd rt p) wZ wY
_ ->
                        forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"Failed to commute common patches:\n"
                            forall a. [a] -> [a] -> [a]
++ Doc -> String
renderString ([Doc] -> Doc
vcat forall a b. (a -> b) -> a -> b
$
                                forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL (PatchInfo -> Doc
displayPatchInfo forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info) forall a b. (a -> b) -> a -> b
$ forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> RL a wX wZ
reverseFL FL (PatchInfoAnd rt p) wZ wZ
bad)
                    FL (PatchInfoAnd rt p) wU wZ
_ :> FL (PatchInfoAnd rt p) wZ wZ
NilFL :> FL (PatchInfoAnd rt p) wZ wY
only_theirs ->
                        forall (common :: * -> * -> *) (left :: * -> * -> *)
       (right :: * -> * -> *) wA wX wY wU.
common wA wU
-> left wU wX -> right wU wY -> Fork common left right wA wX wY
Fork (forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wU
common (forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> RL a wX wZ
reverseFL FL (PatchInfoAnd rt p) wU wZ
common2))
                            FL (PatchInfoAnd rt p) wZ wX
only_ours (forall (a :: * -> * -> *) wX1 wY wX2. a wX1 wY -> a wX2 wY
unsafeCoercePStart FL (PatchInfoAnd rt p) wZ wY
only_theirs)
  where
    infoIn :: RL (PatchInfoAndG rt p) wX wY -> PatchInfoAndG rt p wA wB -> Bool
infoIn RL (PatchInfoAndG rt p) wX wY
inWhat = (forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info RL (PatchInfoAndG rt p) wX wY
inWhat) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info

findCommonWithThem :: Commute p
                   => PatchSet rt p Origin wX
                   -> PatchSet rt p Origin wY
                   -> (PatchSet rt p :> FL (PatchInfoAnd rt p)) Origin wX
findCommonWithThem :: forall (p :: * -> * -> *) (rt :: RepoType) wX wY.
Commute p =>
PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> (:>) (PatchSet rt p) (FL (PatchInfoAnd rt p)) Origin wX
findCommonWithThem PatchSet rt p Origin wX
us PatchSet rt p Origin wY
them = case forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
Commute p =>
PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     Origin
     wX
     wY
taggedIntersection PatchSet rt p Origin wX
us PatchSet rt p Origin wY
them of
    Fork RL (Tagged rt p) Origin wU
common RL (PatchInfoAnd rt p) wU wX
us' RL (PatchInfoAnd rt p) wU wY
them' ->
        case forall (p :: * -> * -> *) wX wY.
Commute p =>
(forall wU wV. p wU wV -> Bool)
-> FL p wX wY -> (:>) (FL p) (FL p :> FL p) wX wY
partitionFL ((forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info RL (PatchInfoAnd rt p) wU wY
them') forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info) forall a b. (a -> b) -> a -> b
$ forall (a :: * -> * -> *) wX wZ. RL a wX wZ -> FL a wX wZ
reverseRL RL (PatchInfoAnd rt p) wU wX
us' of
            FL (PatchInfoAnd rt p) wU wZ
_ :> bad :: FL (PatchInfoAnd rt p) wZ wZ
bad@(PatchInfoAnd rt p wZ wY
_ :>: FL (PatchInfoAnd rt p) wY wZ
_) :> FL (PatchInfoAnd rt p) wZ wX
_ ->
                forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"Failed to commute common patches:\n"
                      forall a. [a] -> [a] -> [a]
++ Doc -> String
renderString
                          ([Doc] -> Doc
vcat forall a b. (a -> b) -> a -> b
$ forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL (PatchInfo -> Doc
displayPatchInfo forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info) forall a b. (a -> b) -> a -> b
$ forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> RL a wX wZ
reverseFL FL (PatchInfoAnd rt p) wZ wZ
bad)
            FL (PatchInfoAnd rt p) wU wZ
common2 :> FL (PatchInfoAnd rt p) wZ wZ
_nilfl :> FL (PatchInfoAnd rt p) wZ wX
only_ours ->
                forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wU
common (forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> RL a wX wZ
reverseFL FL (PatchInfoAnd rt p) wU wZ
common2) forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wX wZ -> a2 wZ wY -> (:>) a1 a2 wX wY
:> forall (a :: * -> * -> *) wX wY wB wC. a wX wY -> a wB wC
unsafeCoerceP FL (PatchInfoAnd rt p) wZ wX
only_ours

findUncommon :: Commute p
             => PatchSet rt p Origin wX -> PatchSet rt p Origin wY
             -> (FL (PatchInfoAnd rt p) :\/: FL (PatchInfoAnd rt p)) wX wY
findUncommon :: forall (p :: * -> * -> *) (rt :: RepoType) wX wY.
Commute p =>
PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> (:\/:) (FL (PatchInfoAnd rt p)) (FL (PatchInfoAnd rt p)) wX wY
findUncommon PatchSet rt p Origin wX
us PatchSet rt p Origin wY
them =
    case forall (p :: * -> * -> *) (rt :: RepoType) wX wY.
Commute p =>
PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> (:>) (PatchSet rt p) (FL (PatchInfoAnd rt p)) Origin wX
findCommonWithThem PatchSet rt p Origin wX
us PatchSet rt p Origin wY
them of
        PatchSet rt p Origin wZ
_common :> FL (PatchInfoAnd rt p) wZ wX
us' -> case forall (p :: * -> * -> *) (rt :: RepoType) wX wY.
Commute p =>
PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> (:>) (PatchSet rt p) (FL (PatchInfoAnd rt p)) Origin wX
findCommonWithThem PatchSet rt p Origin wY
them PatchSet rt p Origin wX
us of
            PatchSet rt p Origin wZ
_ :> FL (PatchInfoAnd rt p) wZ wY
them' -> forall (a :: * -> * -> *) wX1 wY wX2. a wX1 wY -> a wX2 wY
unsafeCoercePStart FL (PatchInfoAnd rt p) wZ wX
us' forall (a1 :: * -> * -> *) (a2 :: * -> * -> *) wX wY wZ.
a1 wZ wX -> a2 wZ wY -> (:\/:) a1 a2 wX wY
:\/: FL (PatchInfoAnd rt p) wZ wY
them'

countUsThem :: Commute p
            => PatchSet rt p Origin wX
            -> PatchSet rt p Origin wY
            -> (Int, Int)
countUsThem :: forall (p :: * -> * -> *) (rt :: RepoType) wX wY.
Commute p =>
PatchSet rt p Origin wX -> PatchSet rt p Origin wY -> (Int, Int)
countUsThem PatchSet rt p Origin wX
us PatchSet rt p Origin wY
them =
    case forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
Commute p =>
PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     Origin
     wX
     wY
taggedIntersection PatchSet rt p Origin wX
us PatchSet rt p Origin wY
them of
        Fork RL (Tagged rt p) Origin wU
_ RL (PatchInfoAnd rt p) wU wX
us' RL (PatchInfoAnd rt p) wU wY
them' -> let uu :: [PatchInfo]
uu = forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info RL (PatchInfoAnd rt p) wU wX
us'
                                tt :: [PatchInfo]
tt = forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info RL (PatchInfoAnd rt p) wU wY
them' in
                            (forall (t :: * -> *) a. Foldable t => t a -> Int
length forall a b. (a -> b) -> a -> b
$ [PatchInfo]
uu forall a. Eq a => [a] -> [a] -> [a]
\\ [PatchInfo]
tt, forall (t :: * -> *) a. Foldable t => t a -> Int
length forall a b. (a -> b) -> a -> b
$ [PatchInfo]
tt forall a. Eq a => [a] -> [a] -> [a]
\\ [PatchInfo]
uu)

mergeThem :: (Commute p, Merge p)
          => PatchSet rt p Origin wX -> PatchSet rt p Origin wY
          -> Sealed (FL (PatchInfoAnd rt p) wX)
mergeThem :: forall (p :: * -> * -> *) (rt :: RepoType) wX wY.
(Commute p, Merge p) =>
PatchSet rt p Origin wX
-> PatchSet rt p Origin wY -> Sealed (FL (PatchInfoAnd rt p) wX)
mergeThem PatchSet rt p Origin wX
us PatchSet rt p Origin wY
them =
    case forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
Commute p =>
PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     Origin
     wX
     wY
taggedIntersection PatchSet rt p Origin wX
us PatchSet rt p Origin wY
them of
        Fork RL (Tagged rt p) Origin wU
_ RL (PatchInfoAnd rt p) wU wX
us' RL (PatchInfoAnd rt p) wU wY
them' ->
            case forall (p :: * -> * -> *) wX wY wZ.
(Commute p, Merge p, Ident p) =>
FL p wX wY -> FL p wX wZ -> (:/\:) (FL p) (FL p) wY wZ
merge2FL (forall (a :: * -> * -> *) wX wZ. RL a wX wZ -> FL a wX wZ
reverseRL RL (PatchInfoAnd rt p) wU wX
us') (forall (a :: * -> * -> *) wX wZ. RL a wX wZ -> FL a wX wZ
reverseRL RL (PatchInfoAnd rt p) wU wY
them') of
               FL (PatchInfoAnd rt p) wX wZ
them'' :/\: FL (PatchInfoAnd rt p) wY wZ
_ -> forall (a :: * -> *) wX. a wX -> Sealed a
Sealed FL (PatchInfoAnd rt p) wX wZ
them''

patchSetIntersection :: Commute p
                   => [SealedPatchSet rt p Origin]
                   -> SealedPatchSet rt p Origin
patchSetIntersection :: forall (p :: * -> * -> *) (rt :: RepoType).
Commute p =>
[SealedPatchSet rt p Origin] -> SealedPatchSet rt p Origin
patchSetIntersection [] = forall (a :: * -> *) wX. a wX -> Sealed a
seal forall a b. (a -> b) -> a -> b
$ forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet forall (a :: * -> * -> *) wX. RL a wX wX
NilRL forall (a :: * -> * -> *) wX. RL a wX wX
NilRL
patchSetIntersection [SealedPatchSet rt p Origin
x] = SealedPatchSet rt p Origin
x
patchSetIntersection (Sealed PatchSet rt p Origin wX
y : [SealedPatchSet rt p Origin]
ys) =
    case forall (p :: * -> * -> *) (rt :: RepoType).
Commute p =>
[SealedPatchSet rt p Origin] -> SealedPatchSet rt p Origin
patchSetIntersection [SealedPatchSet rt p Origin]
ys of
        Sealed PatchSet rt p Origin wX
z -> case forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
Commute p =>
PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     Origin
     wX
     wY
taggedIntersection PatchSet rt p Origin wX
y PatchSet rt p Origin wX
z of
            Fork RL (Tagged rt p) Origin wU
common RL (PatchInfoAnd rt p) wU wX
a RL (PatchInfoAnd rt p) wU wX
b -> case forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info RL (PatchInfoAnd rt p) wU wX
a forall a. Eq a => [a] -> [a] -> [a]
`intersect` forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info RL (PatchInfoAnd rt p) wU wX
b of
                [PatchInfo]
morecommon ->
                    case forall (p :: * -> * -> *) wX wY.
Commute p =>
(forall wU wV. p wU wV -> Bool)
-> RL p wX wY -> (:>) (RL p) (RL p) wX wY
partitionRL (\PatchInfoAnd rt p wU wV
e -> forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info PatchInfoAnd rt p wU wV
e forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [PatchInfo]
morecommon) RL (PatchInfoAnd rt p) wU wX
a of
                        RL (PatchInfoAnd rt p) wU wZ
commonps :> RL (PatchInfoAnd rt p) wZ wX
_ -> forall (a :: * -> *) wX. a wX -> Sealed a
seal forall a b. (a -> b) -> a -> b
$ forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wU
common RL (PatchInfoAnd rt p) wU wZ
commonps

patchSetUnion :: (Commute p, Merge p, Eq2 p)
            => [SealedPatchSet rt p Origin]
            -> SealedPatchSet rt p Origin
patchSetUnion :: forall (p :: * -> * -> *) (rt :: RepoType).
(Commute p, Merge p, Eq2 p) =>
[SealedPatchSet rt p Origin] -> SealedPatchSet rt p Origin
patchSetUnion [] = forall (a :: * -> *) wX. a wX -> Sealed a
seal forall a b. (a -> b) -> a -> b
$ forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet forall (a :: * -> * -> *) wX. RL a wX wX
NilRL forall (a :: * -> * -> *) wX. RL a wX wX
NilRL
patchSetUnion [SealedPatchSet rt p Origin
x] = SealedPatchSet rt p Origin
x
patchSetUnion (Sealed y :: PatchSet rt p Origin wX
y@(PatchSet RL (Tagged rt p) Origin wX
tsy RL (PatchInfoAnd rt p) wX wX
psy) : Sealed PatchSet rt p Origin wX
y2 : [SealedPatchSet rt p Origin]
ys) =
    case forall (p :: * -> * -> *) (rt :: RepoType) wX wY.
(Commute p, Merge p) =>
PatchSet rt p Origin wX
-> PatchSet rt p Origin wY -> Sealed (FL (PatchInfoAnd rt p) wX)
mergeThem PatchSet rt p Origin wX
y PatchSet rt p Origin wX
y2 of
        Sealed FL (PatchInfoAnd rt p) wX wX
p2 ->
            forall (p :: * -> * -> *) (rt :: RepoType).
(Commute p, Merge p, Eq2 p) =>
[SealedPatchSet rt p Origin] -> SealedPatchSet rt p Origin
patchSetUnion forall a b. (a -> b) -> a -> b
$ forall (a :: * -> *) wX. a wX -> Sealed a
seal (forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
RL (Tagged rt p) Origin wX
-> RL (PatchInfoAnd rt p) wX wY -> PatchSet rt p Origin wY
PatchSet RL (Tagged rt p) Origin wX
tsy (RL (PatchInfoAnd rt p) wX wX
psy forall (p :: * -> * -> *) wX wY wZ.
RL p wX wY -> FL p wY wZ -> RL p wX wZ
+<<+ FL (PatchInfoAnd rt p) wX wX
p2)) forall a. a -> [a] -> [a]
: [SealedPatchSet rt p Origin]
ys

areUnrelatedRepos :: Commute p
                  => PatchSet rt p Origin wX
                  -> PatchSet rt p Origin wY -> Bool
areUnrelatedRepos :: forall (p :: * -> * -> *) (rt :: RepoType) wX wY.
Commute p =>
PatchSet rt p Origin wX -> PatchSet rt p Origin wY -> Bool
areUnrelatedRepos PatchSet rt p Origin wX
us PatchSet rt p Origin wY
them =
    case forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
Commute p =>
PatchSet rt p Origin wX
-> PatchSet rt p Origin wY
-> Fork
     (RL (Tagged rt p))
     (RL (PatchInfoAnd rt p))
     (RL (PatchInfoAnd rt p))
     Origin
     wX
     wY
taggedIntersection PatchSet rt p Origin wX
us PatchSet rt p Origin wY
them of
        Fork RL (Tagged rt p) Origin wU
c RL (PatchInfoAnd rt p) wU wX
u RL (PatchInfoAnd rt p) wU wY
t -> forall {rt :: RepoType} {p :: * -> * -> *} {wX} {wZ}
       {rt :: RepoType} {p :: * -> * -> *} {wX} {wY} {rt :: RepoType}
       {p :: * -> * -> *} {wX} {wY}.
RL (Tagged rt p) wX wZ
-> RL (PatchInfoAndG rt p) wX wY
-> RL (PatchInfoAndG rt p) wX wY
-> Bool
checkit RL (Tagged rt p) Origin wU
c RL (PatchInfoAnd rt p) wU wX
u RL (PatchInfoAnd rt p) wU wY
t
  where
    checkit :: RL (Tagged rt p) wX wZ
-> RL (PatchInfoAndG rt p) wX wY
-> RL (PatchInfoAndG rt p) wX wY
-> Bool
checkit (RL (Tagged rt p) wX wY
_ :<: Tagged{}) RL (PatchInfoAndG rt p) wX wY
_ RL (PatchInfoAndG rt p) wX wY
_ = Bool
False
    checkit RL (Tagged rt p) wX wZ
_ RL (PatchInfoAndG rt p) wX wY
u RL (PatchInfoAndG rt p) wX wY
t | RL (PatchInfoAndG rt p) wX wY
t forall (a :: * -> * -> *) wX wY. RL a wX wY -> Int -> Bool
`isShorterThanRL` Int
5 = Bool
False
                  | RL (PatchInfoAndG rt p) wX wY
u forall (a :: * -> * -> *) wX wY. RL a wX wY -> Int -> Bool
`isShorterThanRL` Int
5 = Bool
False
                  | Bool
otherwise = forall (t :: * -> *) a. Foldable t => t a -> Bool
null forall a b. (a -> b) -> a -> b
$ forall a. Eq a => [a] -> [a] -> [a]
intersect (forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info RL (PatchInfoAndG rt p) wX wY
u) (forall (a :: * -> * -> *) b wX wY.
(forall wW wZ. a wW wZ -> b) -> RL a wX wY -> [b]
mapRL forall (rt :: RepoType) (p :: * -> * -> *) wA wB.
PatchInfoAndG rt p wA wB -> PatchInfo
info RL (PatchInfoAndG rt p) wX wY
t)

-- | Split a 'PatchSet' at the latest clean tag. The left part is what comes
-- before the tag, the right part is the tag and its non-dependencies.
contextPatches :: PatchSet rt p wX wY
               -> (PatchSet rt p :> RL (PatchInfoAnd rt p)) wX wY
contextPatches :: forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
PatchSet rt p wX wY
-> (:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wX wY
contextPatches = forall (rt :: RepoType) (p :: * -> * -> *) wX wY.
PatchSet rt p wX wY
-> (:>) (PatchSet rt p) (RL (PatchInfoAnd rt p)) wX wY
patchSetSplit forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (rt :: RepoType) (p :: * -> * -> *) wStart wX.
PatchSet rt p wStart wX -> PatchSet rt p wStart wX
slightlyOptimizePatchset