diff options
author | Joey Hess <joey@kitenet.net> | 2011-12-12 21:12:51 -0400 |
---|---|---|
committer | Joey Hess <joey@kitenet.net> | 2011-12-12 21:12:51 -0400 |
commit | 31a0c07ee91af9e3bf434f416a4d711d841aa223 (patch) | |
tree | f45a90aea7a22aa564ef4af9232d81db77108e9b /Git | |
parent | 543d0d250104c1f5908e1b7b258d36d95488a029 (diff) |
broke out Git/Branch.hs and reorganized
Diffstat (limited to 'Git')
-rw-r--r-- | Git/Branch.hs | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/Git/Branch.hs b/Git/Branch.hs new file mode 100644 index 000000000..e69e96f28 --- /dev/null +++ b/Git/Branch.hs @@ -0,0 +1,60 @@ +{- git branch stuff + - + - Copyright 2011 Joey Hess <joey@kitenet.net> + - + - Licensed under the GNU GPL version 3 or higher. + -} + +module Git.Branch where + +import qualified Data.ByteString.Lazy.Char8 as L + +import Common +import Git + +{- Checks if the second branch has any commits not present on the first + - branch. -} +changed :: Branch -> Branch -> Repo -> IO Bool +changed origbranch newbranch repo + | origbranch == newbranch = return False + | otherwise = not . L.null <$> diffs + where + diffs = Git.pipeRead + [ Param "log" + , Param (show origbranch ++ ".." ++ show newbranch) + , Params "--oneline -n1" + ] repo + +{- Given a set of refs that are all known to have commits not + - on the branch, tries to update the branch by a fast-forward. + - + - In order for that to be possible, one of the refs must contain + - every commit present in all the other refs. + -} +fastForward :: Branch -> [Ref] -> Repo -> IO Bool +fastForward _ [] _ = return True +fastForward branch (first:rest) repo = do + -- First, check that the branch does not contain any + -- new commits that are not in the first ref. If it does, + -- cannot fast-forward. + diverged <- changed first branch repo + if diverged + then no_ff + else maybe no_ff do_ff =<< findbest first rest + where + no_ff = return False + do_ff to = do + Git.run "update-ref" + [Param $ show branch, Param $ show to] repo + return True + findbest c [] = return $ Just c + findbest c (r:rs) + | c == r = findbest c rs + | otherwise = do + better <- changed c r repo + worse <- changed r c repo + case (better, worse) of + (True, True) -> return Nothing -- divergent fail + (True, False) -> findbest r rs -- better + (False, True) -> findbest c rs -- worse + (False, False) -> findbest c rs -- same |