diff --git a/Assistant/Threads/Merger.hs b/Assistant/Threads/Merger.hs index c79566349d..6e19218d98 100644 --- a/Assistant/Threads/Merger.hs +++ b/Assistant/Threads/Merger.hs @@ -89,7 +89,7 @@ mergeBranch = Git.Merge.mergeNonInteractive . Command.Sync.syncBranch - 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 :: (Maybe Git.Ref) -> [Remote] -> Annex () manualPull currentbranch remotes = do forM_ remotes $ \r -> inRepo $ Git.Command.runBool "fetch" [Param $ Remote.name r] diff --git a/Assistant/Threads/MountWatcher.hs b/Assistant/Threads/MountWatcher.hs index ca359a268c..18dfca42ca 100644 --- a/Assistant/Threads/MountWatcher.hs +++ b/Assistant/Threads/MountWatcher.hs @@ -161,18 +161,21 @@ handleMount st dstatus scanremotes dir = do debug thisThread ["detected mount of", dir] rs <- remotesUnder st dstatus dir unless (null rs) $ do - go rs =<< runThreadState st (inRepo Git.Branch.current) + let nonspecial = filter (Git.repoIsLocal . Remote.repo) rs + unless (null nonspecial) $ do + void $ alertWhile dstatus (syncMountAlert dir nonspecial) $ do + debug thisThread ["syncing with", show rs] + sync nonspecial =<< runThreadState st (inRepo Git.Branch.current) + addScanRemotes scanremotes nonspecial where - go _ Nothing = noop - go rs (Just branch) = do - let nonspecial = filter (Git.repoIsLocal . Remote.repo) rs - unless (null nonspecial) $ - void $ alertWhile dstatus (syncMountAlert dir nonspecial) $ do - debug thisThread ["syncing with", show nonspecial] - runThreadState st $ manualPull branch nonspecial - now <- getCurrentTime - pushToRemotes thisThread now st Nothing nonspecial - addScanRemotes scanremotes rs + sync rs (Just branch) = do + runThreadState st $ manualPull (Just branch) rs + now <- getCurrentTime + pushToRemotes thisThread now st Nothing rs + {- No local branch exists yet, but we can try pulling. -} + sync rs Nothing = do + runThreadState st $ manualPull Nothing rs + return True {- Finds remotes located underneath the mount point. - diff --git a/Assistant/Threads/Pusher.hs b/Assistant/Threads/Pusher.hs index 5e110b77d9..4753e355ad 100644 --- a/Assistant/Threads/Pusher.hs +++ b/Assistant/Threads/Pusher.hs @@ -118,5 +118,5 @@ pushToRemotes threadname now st mpushmap remotes = do retry branch g rs = do debug threadname [ "trying manual pull to resolve failed pushes" ] - runThreadState st $ manualPull branch rs + runThreadState st $ manualPull (Just branch) rs go False (Just branch) g rs diff --git a/Command/Sync.hs b/Command/Sync.hs index 7bf3048de4..ab29c82b66 100644 --- a/Command/Sync.hs +++ b/Command/Sync.hs @@ -123,7 +123,7 @@ pullRemote remote branch = do next $ do showOutput stopUnless fetch $ - next $ mergeRemote remote branch + next $ mergeRemote remote (Just branch) where fetch = inRepo $ Git.Command.runBool "fetch" [Param $ Remote.name remote] @@ -132,11 +132,17 @@ pullRemote remote branch = do - Which to merge from? Well, the master has whatever latest changes - were committed, while the synced/master may have changes that some - other remote synced to this remote. So, merge them both. -} -mergeRemote :: Remote -> Git.Ref -> CommandCleanup -mergeRemote remote branch = all id <$> (mapM merge =<< tomerge) +mergeRemote :: Remote -> (Maybe Git.Ref) -> CommandCleanup +mergeRemote remote b = case b of + Nothing -> do + branch <- inRepo Git.Branch.currentUnsafe + all id <$> (mapM merge $ branchlist branch) + Just _ -> all id <$> (mapM merge =<< tomerge (branchlist b)) where merge = mergeFrom . remoteBranch remote - tomerge = filterM (changed remote) [branch, syncBranch branch] + tomerge branches = filterM (changed remote) branches + branchlist Nothing = [] + branchlist (Just branch) = [branch, syncBranch branch] pushRemote :: Remote -> Git.Ref -> CommandStart pushRemote remote branch = go =<< needpush diff --git a/Git/Branch.hs b/Git/Branch.hs index 098aa1a1a2..f73ae5e2a3 100644 --- a/Git/Branch.hs +++ b/Git/Branch.hs @@ -23,13 +23,23 @@ import Git.Command -} current :: Repo -> IO (Maybe Git.Ref) current r = do - branch <- firstLine <$> pipeRead [Param "symbolic-ref", Param "HEAD"] r - if null branch - then return Nothing - else ifM (null <$> pipeRead [Param "show-ref", Param branch] r) - ( return Nothing - , return $ Just $ Git.Ref branch - ) + v <- currentUnsafe r + case v of + Nothing -> return Nothing + Just branch -> + ifM (null <$> pipeRead [Param "show-ref", Param $ show branch] r) + ( return Nothing + , return v + ) + +{- The current branch, which may not really exist yet. -} +currentUnsafe :: Repo -> IO (Maybe Git.Ref) +currentUnsafe r = parse . firstLine + <$> pipeRead [Param "symbolic-ref", Param "HEAD"] r + where + parse l + | null l = Nothing + | otherwise = Just $ Git.Ref l {- Checks if the second branch has any commits not present on the first - branch. -}