avoid double commit during transition

The second commit had some bad refs which resulted in the race detection
code running. But that commit was unnecessary anyway, it only was there to
merge in the other refs.
This commit is contained in:
Joey Hess 2013-09-03 16:31:32 -04:00
parent b51dffa46d
commit 4079f9cfe8
2 changed files with 26 additions and 33 deletions

View file

@ -162,17 +162,13 @@ updateTo pairs = do
showSideAction merge_desc showSideAction merge_desc
mergeIndex refs mergeIndex refs
let commitrefs = nub $ fullname:refs let commitrefs = nub $ fullname:refs
transitioned <- handleTransitions localtransitions commitrefs unlessM (handleTransitions localtransitions commitrefs) $ do
case transitioned of ff <- if dirty
Nothing -> do then return False
ff <- if dirty else inRepo $ Git.Branch.fastForward fullname refs
then return False if ff
else inRepo $ Git.Branch.fastForward fullname refs then updateIndex branchref
if ff else commitBranch branchref merge_desc commitrefs
then updateIndex branchref
else commitBranch branchref merge_desc commitrefs
Just (branchref', commitrefs') ->
commitBranch branchref' merge_desc commitrefs'
liftIO cleanjournal liftIO cleanjournal
{- Gets the content of a file, which may be in the journal, or in the index {- Gets the content of a file, which may be in the journal, or in the index
@ -251,7 +247,8 @@ commitBranch' branchref message parents = do
committedref <- inRepo $ Git.Branch.commit message fullname parents committedref <- inRepo $ Git.Branch.commit message fullname parents
setIndexSha committedref setIndexSha committedref
parentrefs <- commitparents <$> catObject committedref parentrefs <- commitparents <$> catObject committedref
when (racedetected branchref parentrefs) $ when (racedetected branchref parentrefs) $ do
liftIO $ print ("race detected", branchref, parentrefs, "committing", (branchref, parents))
fixrace committedref parentrefs fixrace committedref parentrefs
where where
-- look for "parent ref" lines and return the refs -- look for "parent ref" lines and return the refs
@ -394,34 +391,33 @@ stageJournal = withIndex $ do
{- This is run after the refs have been merged into the index, {- This is run after the refs have been merged into the index,
- but before the result is committed to the branch. - but before the result is committed to the branch.
- Which is why it's passed the contents of the local branches's - (Which is why it's passed the contents of the local branches's
- transition log before that merge took place. - transition log before that merge took place.)
- -
- When the refs contain transitions that have not yet been done locally, - When the refs contain transitions that have not yet been done locally,
- the transitions are performed on the index, and a new branch - the transitions are performed on the index, and a new branch
- is created from the result, and returned. - is created from the result.
- -
- When there are transitions recorded locally that have not been done - When there are transitions recorded locally that have not been done
- to the remote refs, the transitions are performed in the index, - to the remote refs, the transitions are performed in the index,
- and the existing branch is returned. In this case, the untransitioned - and committed to the existing branch. In this case, the untransitioned
- remote refs cannot be merged into the branch (since transitions - remote refs cannot be merged into the branch (since transitions
- throw away history), so none of them are included in the returned - throw away history), so they are added to the list of refs to ignore,
- list of refs, and they are added to the list of refs to ignore,
- to avoid re-merging content from them again. - to avoid re-merging content from them again.
-} -}
handleTransitions :: Transitions -> [Git.Ref] -> Annex (Maybe (Git.Branch, [Git.Ref])) handleTransitions :: Transitions -> [Git.Ref] -> Annex Bool
handleTransitions localts refs = do handleTransitions localts refs = do
m <- M.fromList <$> mapM getreftransition refs m <- M.fromList <$> mapM getreftransition refs
let remotets = M.elems m let remotets = M.elems m
if all (localts ==) remotets if all (localts ==) remotets
then return Nothing then return False
else do else do
let allts = combineTransitions (localts:remotets) let allts = combineTransitions (localts:remotets)
let (transitionedrefs, untransitionedrefs) = let (transitionedrefs, untransitionedrefs) =
partition (\r -> M.lookup r m == Just allts) refs partition (\r -> M.lookup r m == Just allts) refs
transitionedbranch <- performTransitions allts (localts /= allts) performTransitions allts (localts /= allts) transitionedrefs
ignoreRefs untransitionedrefs ignoreRefs untransitionedrefs
return $ Just (transitionedbranch, transitionedrefs) return True
where where
getreftransition ref = do getreftransition ref = do
ts <- parseTransitionsStrictly "remote" . L.unpack ts <- parseTransitionsStrictly "remote" . L.unpack
@ -444,10 +440,9 @@ getIgnoredRefs = S.fromList . mapMaybe Git.Sha.extractSha . lines <$> content
liftIO $ catchDefaultIO "" $ readFile f liftIO $ catchDefaultIO "" $ readFile f
{- Performs the specified transitions on the contents of the index file, {- Performs the specified transitions on the contents of the index file,
- commits it to the branch, or creates a new branch, and returns - commits it to the branch, or creates a new branch. -}
- the branch's ref. -} performTransitions :: Transitions -> Bool -> [Ref] -> Annex ()
performTransitions :: Transitions -> Bool -> Annex Git.Ref performTransitions ts neednewlocalbranch transitionedrefs = do
performTransitions ts neednewbranch = do
-- For simplicity & speed, we're going to use the Annex.Queue to -- For simplicity & speed, we're going to use the Annex.Queue to
-- update the git-annex branch, while it usually holds changes -- update the git-annex branch, while it usually holds changes
-- for the head branch. Flush any such changes. -- for the head branch. Flush any such changes.
@ -455,18 +450,16 @@ performTransitions ts neednewbranch = do
withIndex $ do withIndex $ do
run $ mapMaybe getTransitionCalculator $ transitionList ts run $ mapMaybe getTransitionCalculator $ transitionList ts
Annex.Queue.flush Annex.Queue.flush
if neednewbranch if neednewlocalbranch
then do then do
committedref <- inRepo $ Git.Branch.commit message fullname [] committedref <- inRepo $ Git.Branch.commit message fullname transitionedrefs
setIndexSha committedref setIndexSha committedref
return committedref
else do else do
ref <- getBranch ref <- getBranch
commitBranch ref message [fullname] commitBranch ref message (nub $ fullname:transitionedrefs)
getBranch
where where
message message
| neednewbranch = "new branch for transition " ++ tdesc | neednewlocalbranch && null transitionedrefs = "new branch for transition " ++ tdesc
| otherwise = "continuing transition " ++ tdesc | otherwise = "continuing transition " ++ tdesc
tdesc = show $ map describeTransition $ transitionList ts tdesc = show $ map describeTransition $ transitionList ts

View file

@ -45,7 +45,7 @@ perform ts True = do
recordTransitions Branch.change ts recordTransitions Branch.change ts
-- get branch committed before contining with the transition -- get branch committed before contining with the transition
Branch.update Branch.update
void $ Branch.performTransitions ts True void $ Branch.performTransitions ts True []
next $ return True next $ return True
perform _ False = do perform _ False = do
showLongNote "To forget git-annex branch history, you must specify --force. This deletes metadata!" showLongNote "To forget git-annex branch history, you must specify --force. This deletes metadata!"