summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2012-06-25 20:16:30 -0400
committerGravatar Joey Hess <joey@kitenet.net>2012-06-25 20:16:30 -0400
commit05c4dfb9411e54c21aa4c0d49e3662117ac2f549 (patch)
tree91d37a10387066185250c99c93fba85d753f5e72
parent14015036bce2d6a4cf57775ccfc5310f0ec96082 (diff)
fixup merges now done when needed
-rw-r--r--Assistant/Threads/Merger.hs8
-rw-r--r--Assistant/Threads/Pusher.hs17
-rw-r--r--doc/design/assistant/syncing.mdwn2
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