check if branches are up-to-date before merging, pushing

This optimises away the need to run anything in some common cases.
It's particularly useful on push; no need to push if the tracking branch
we just pulled is the same as the branch we're going to push.
This commit is contained in:
Joey Hess 2011-12-30 18:04:01 -04:00
parent 9d85baa314
commit f2fa29bf3b

View file

@ -15,6 +15,7 @@ import Command
import qualified Remote import qualified Remote
import qualified Annex.Branch import qualified Annex.Branch
import qualified Git.Command import qualified Git.Command
import qualified Git.Branch
import qualified Git.Config import qualified Git.Config
import qualified Git.Ref import qualified Git.Ref
import qualified Git import qualified Git
@ -34,7 +35,7 @@ seek args = do
return $ concat $ return $ concat $
[ [ commit ] [ [ commit ]
, [ mergeLocal branch ] , [ mergeLocal branch ]
, [ update remote branch | remote <- remotes ] , [ pullRemote remote branch | remote <- remotes ]
, [ mergeAnnex ] , [ mergeAnnex ]
, [ pushLocal syncbranch ] , [ pushLocal syncbranch ]
, [ pushRemote remote branch syncbranch | remote <- remotes ] , [ pushRemote remote branch syncbranch | remote <- remotes ]
@ -69,10 +70,13 @@ commit = do
return True return True
mergeLocal :: Git.Ref -> CommandStart mergeLocal :: Git.Ref -> CommandStart
mergeLocal branch = do mergeLocal branch = go =<< inRepo (Git.Branch.changed branch mergebranch)
let mergebranch = Git.Ref.under "refs/heads/synced" branch where
showStart "merge" $ Git.Ref.describe mergebranch mergebranch = Git.Ref.under "refs/heads/synced" branch
next $ next $ mergeFromIfExists mergebranch go False = stop
go True = do
showStart "merge" $ Git.Ref.describe mergebranch
next $ next $ mergeFromIfExists mergebranch
pushLocal :: Git.Ref -> CommandStart pushLocal :: Git.Ref -> CommandStart
pushLocal syncbranch = go =<< inRepo (Git.Ref.exists syncbranch) pushLocal syncbranch = go =<< inRepo (Git.Ref.exists syncbranch)
@ -99,9 +103,9 @@ mergeFromIfExists branch = go =<< inRepo (Git.Ref.exists branch)
" does not exist, not merging" " does not exist, not merging"
return False return False
update :: Remote.Remote Annex -> Git.Ref -> CommandStart pullRemote :: Remote.Remote Annex -> Git.Ref -> CommandStart
update remote branch = do pullRemote remote branch = do
showStart "update" (Remote.name remote) showStart "pull" (Remote.name remote)
next $ do next $ do
checkRemote remote checkRemote remote
showOutput showOutput
@ -115,18 +119,22 @@ mergeRemote remote = mergeFromIfExists .
Git.Ref.under ("refs/remotes/" ++ Remote.name remote ++ "/synced") Git.Ref.under ("refs/remotes/" ++ Remote.name remote ++ "/synced")
pushRemote :: Remote.Remote Annex -> Git.Ref -> Git.Ref -> CommandStart pushRemote :: Remote.Remote Annex -> Git.Ref -> Git.Ref -> CommandStart
pushRemote remote branch syncbranch = do pushRemote remote branch syncbranch = go =<< newer
showStart "push" (Remote.name remote) where
let syncbranchRemote = Git.Ref.under newer = inRepo $ Git.Branch.changed syncbranchRemote syncbranch
("refs/remotes/" ++ Remote.name remote) syncbranch go False = stop
let refspec = show (Git.Ref.base branch) ++ ":" ++ show (Git.Ref.base syncbranch) go True = do
ex <- inRepo $ Git.Ref.exists syncbranchRemote showStart "push" (Remote.name remote)
next $ next $ do ex <- inRepo $ Git.Ref.exists syncbranchRemote
showOutput next $ next $ do
inRepo $ Git.Command.runBool "push" $ showOutput
[ Param (Remote.name remote) inRepo $ Git.Command.runBool "push" $
, Param (show $ Annex.Branch.name) ] ++ [ Param (Remote.name remote)
[ Param refspec | ex ] , Param (show $ Annex.Branch.name) ] ++
[ Param refspec | ex ]
refspec = show (Git.Ref.base branch) ++ ":" ++ show (Git.Ref.base syncbranch)
syncbranchRemote = Git.Ref.under
("refs/remotes/" ++ Remote.name remote) syncbranch
currentBranch :: Annex Git.Ref currentBranch :: Annex Git.Ref
currentBranch = Git.Ref . firstLine . L.unpack <$> currentBranch = Git.Ref . firstLine . L.unpack <$>