1{- git merging 2 - 3 - Copyright 2012-2021 Joey Hess <id@joeyh.name> 4 - 5 - Licensed under the GNU AGPL version 3 or higher. 6 -} 7 8module Git.Merge ( 9 MergeConfig(..), 10 CommitMode(..), 11 merge, 12 merge', 13 mergeUnrelatedHistoriesParam, 14 stageMerge, 15) where 16 17import Common 18import Git 19import Git.Command 20import qualified Git.Version 21import Git.Branch (CommitMode(..)) 22 23data MergeConfig 24 = MergeNonInteractive 25 -- ^ avoids interactive merge with commit message edit 26 | MergeUnrelatedHistories 27 -- ^ avoids git's prevention of merging unrelated histories 28 | MergeQuiet 29 -- ^ avoids usual output when merging, but errors will still be 30 -- displayed 31 deriving (Eq) 32 33merge :: Ref -> [MergeConfig] -> CommitMode -> Repo -> IO Bool 34merge = merge' [] 35 36merge' :: [CommandParam] -> Ref -> [MergeConfig] -> CommitMode -> Repo -> IO Bool 37merge' extraparams branch mergeconfig commitmode r 38 | MergeNonInteractive `notElem` mergeconfig = 39 go [Param $ fromRef branch] 40 | otherwise = go [Param "--no-edit", Param $ fromRef branch] 41 where 42 go ps = merge'' (sp ++ [Param "merge"] ++ qp ++ ps ++ extraparams) mergeconfig r 43 sp 44 | commitmode == AutomaticCommit = 45 [Param "-c", Param "commit.gpgsign=false"] 46 | otherwise = [] 47 qp 48 | MergeQuiet `notElem` mergeconfig = [] 49 | otherwise = [Param "--quiet"] 50 51merge'' :: [CommandParam] -> [MergeConfig] -> Repo -> IO Bool 52merge'' ps mergeconfig r 53 | MergeUnrelatedHistories `elem` mergeconfig = do 54 up <- mergeUnrelatedHistoriesParam 55 go (ps ++ maybeToList up) 56 | otherwise = go ps 57 where 58 go ps' = runBool ps' r 59 60{- Git used to default to merging unrelated histories; newer versions need 61 - an option. -} 62mergeUnrelatedHistoriesParam :: IO (Maybe CommandParam) 63mergeUnrelatedHistoriesParam = ifM (Git.Version.older "2.9.0") 64 ( return Nothing 65 , return (Just (Param "--allow-unrelated-histories")) 66 ) 67 68{- Stage the merge into the index, but do not commit it.-} 69stageMerge :: Ref -> [MergeConfig] -> Repo -> IO Bool 70stageMerge branch = merge'' 71 [ Param "merge" 72 , Param "--quiet" 73 , Param "--no-commit" 74 -- Without this, a fast-forward merge is done, since it involves no 75 -- commit. 76 , Param "--no-ff" 77 , Param $ fromRef branch 78 ] 79