{- management of the git-annex branch
-
- - Copyright 2011-2019 Joey Hess <id@joeyh.name>
+ - Copyright 2011-2020 Joey Hess <id@joeyh.name>
-
- Licensed under the GNU AGPL version 3 or higher.
-}
hasSibling,
siblingBranches,
create,
+ UpdateMade(..),
update,
forceUpdate,
updateTo,
{- Ensures that the branch and index are up-to-date; should be
- called before data is read from it. Runs only once per git-annex run. -}
update :: Annex BranchState
-update = runUpdateOnce $ void $ updateTo =<< siblingBranches
+update = runUpdateOnce $ journalClean <$$> updateTo =<< siblingBranches
{- Forces an update even if one has already been run. -}
-forceUpdate :: Annex Bool
+forceUpdate :: Annex UpdateMade
forceUpdate = updateTo =<< siblingBranches
+data UpdateMade = UpdateMade
+ { refsWereMerged :: Bool
+ , journalClean :: Bool
+ }
+
{- Merges the specified Refs into the index, if they have any changes not
- already in it. The Branch names are only used in the commit message;
- it's even possible that the provided Branches have not been updated to
-
- Returns True if any refs were merged in, False otherwise.
-}
-updateTo :: [(Git.Sha, Git.Branch)] -> Annex Bool
+updateTo :: [(Git.Sha, Git.Branch)] -> Annex UpdateMade
updateTo pairs = ifM (annexMergeAnnexBranches <$> Annex.getGitConfig)
( updateTo' pairs
- , return False
+ , return (UpdateMade False False)
)
-updateTo' :: [(Git.Sha, Git.Branch)] -> Annex Bool
+updateTo' :: [(Git.Sha, Git.Branch)] -> Annex UpdateMade
updateTo' pairs = do
-- ensure branch exists, and get its current ref
branchref <- getBranch
else do
mergedrefs <- getMergedRefs
filterM isnewer (excludeset mergedrefs unignoredrefs)
- if null tomerge
+ journalclean <- if null tomerge
{- Even when no refs need to be merged, the index
- may still be updated if the branch has gotten ahead
- of the index, or just if the journal is dirty. -}
- a commit needs to be done. -}
when dirty $
go branchref dirty [] jl
- , when dirty $
- lockJournal $ go branchref dirty []
+ return True
+ , if dirty
+ then ifM (annexAlwaysCommit <$> Annex.getGitConfig)
+ ( do
+ lockJournal $ go branchref dirty []
+ return True
+ , return False
+ )
+ else return True
)
- else lockJournal $ go branchref dirty tomerge
- return $ not $ null tomerge
+ else do
+ lockJournal $ go branchref dirty tomerge
+ return True
+ return $ UpdateMade
+ { refsWereMerged = not (null tomerge)
+ , journalClean = journalclean
+ }
where
excludeset s = filter (\(r, _) -> S.notMember r s)
isnewer (r, _) = inRepo $ Git.Branch.changed fullname r
changeState $ \s -> s { indexChecked = True }
{- Runs an action to update the branch, if it's not been updated before
- - in this run of git-annex. -}
-runUpdateOnce :: Annex () -> Annex BranchState
+ - in this run of git-annex.
+ -
+ - The action should return True if anything that was in the journal
+ - before got staged (or if the journal was empty). That lets an opmisation
+ - be done: The journal then does not need to be checked going forward,
+ - until new information gets written to it.
+ -}
+runUpdateOnce :: Annex Bool -> Annex BranchState
runUpdateOnce a = do
st <- getState
if branchUpdated st
then return st
else do
- a
+ journalstaged <- a
let stf = \st' -> st'
{ branchUpdated = True
- -- The update staged anything that was
- -- journalled before, so the journal
- -- does not need to be checked going
- -- forward, unless new information
- -- gets written to it, or unless
- -- this run of git-annex needs to notice
- -- changes journalled by other processes
- -- while it's running.
- , journalIgnorable = not $
- journalNeverIgnorable st'
+ , journalIgnorable = journalstaged
+ && not (journalNeverIgnorable st')
}
changeState stf
return (stf st)