From 05c4dfb9411e54c21aa4c0d49e3662117ac2f549 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 25 Jun 2012 20:16:30 -0400 Subject: fixup merges now done when needed --- Assistant/Threads/Merger.hs | 8 ++++++++ Assistant/Threads/Pusher.hs | 17 +++++++++++++---- doc/design/assistant/syncing.mdwn | 2 +- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/Assistant/Threads/Merger.hs b/Assistant/Threads/Merger.hs index d2c8b9b76..77bf9f416 100644 --- a/Assistant/Threads/Merger.hs +++ b/Assistant/Threads/Merger.hs @@ -70,3 +70,11 @@ onAdd g file _ mergeBranch :: Git.Ref -> Git.Repo -> IO Bool mergeBranch = Git.Merge.mergeNonInteractive . Command.Sync.syncBranch + +{- Manually pull from remotes and merge their branches. Called by the pusher + - when a push fails, which can happen due to a remote not having pushed + - changes to us. That could be because it doesn't have us as a remote, or + - because the assistant is not running there, or other reasons. -} +manualPull :: Git.Ref -> [Remote] -> Annex () +manualPull currentbranch remotes = forM_ remotes $ \r -> + Command.Sync.mergeRemote r currentbranch diff --git a/Assistant/Threads/Pusher.hs b/Assistant/Threads/Pusher.hs index 6a4ae7838..82c37de5f 100644 --- a/Assistant/Threads/Pusher.hs +++ b/Assistant/Threads/Pusher.hs @@ -11,6 +11,7 @@ import Common.Annex import Assistant.Commits import Assistant.Pushes import Assistant.ThreadedMonad +import Assistant.Threads.Merger import qualified Command.Sync import Utility.ThreadScheduler import Utility.Parallel @@ -68,11 +69,19 @@ pushToRemotes :: UTCTime -> ThreadState -> FailedPushChan -> [Remote] -> IO () pushToRemotes now st pushchan remotes = do (g, branch) <- runThreadState st $ (,) <$> fromRepo id <*> Command.Sync.currentBranch - Command.Sync.updateBranch (Command.Sync.syncBranch branch) g - failed <- map (`FailedPush` now) <$> inParallel (push g branch) remotes - unless (null failed) $ - refillFailedPushes pushchan failed + go True branch g remotes where + go shouldretry branch g rs = do + Command.Sync.updateBranch (Command.Sync.syncBranch branch) g + failed <- inParallel (push g branch) rs + unless (null failed) $ + if shouldretry + then retry branch g rs + else refillFailedPushes pushchan $ + map (`FailedPush` now) failed push g branch remote = ifM (Command.Sync.pushBranch remote branch g) ( exitSuccess, exitFailure) + retry branch g rs = do + runThreadState st $ manualPull branch rs + go False branch g rs diff --git a/doc/design/assistant/syncing.mdwn b/doc/design/assistant/syncing.mdwn index a2b80eebc..3ece69638 100644 --- a/doc/design/assistant/syncing.mdwn +++ b/doc/design/assistant/syncing.mdwn @@ -15,7 +15,7 @@ all the other git clones, at both the git level and the key/value level. **done** 1. Periodically retry pushes that failed. **done** (every half an hour) 1. Also, detect if a push failed due to not being up-to-date, pull, - and repush. + and repush. **done** 2. Use a git merge driver that adds both conflicting files, so conflicts never break a sync. 3. Investigate the XMPP approach like dvcs-autosync does, or other ways of -- cgit v1.2.3