automatic conflict resolution for assistant

This commit is contained in:
Joey Hess 2012-06-27 20:06:21 -04:00
parent 2e501364d4
commit 783bee285f

View file

@ -24,7 +24,7 @@ mergeThread st = do
g <- runThreadState st $ fromRepo id g <- runThreadState st $ fromRepo id
let dir = Git.localGitDir g </> "refs" </> "heads" </> "synced" let dir = Git.localGitDir g </> "refs" </> "heads" </> "synced"
createDirectoryIfMissing True dir createDirectoryIfMissing True dir
let hook a = Just $ runHandler g a let hook a = Just $ runHandler st g a
let hooks = mkWatchHooks let hooks = mkWatchHooks
{ addHook = hook onAdd { addHook = hook onAdd
, errHook = hook onErr , errHook = hook onErr
@ -32,21 +32,21 @@ mergeThread st = do
watchDir dir (const False) hooks id watchDir dir (const False) hooks id
where where
type Handler = Git.Repo -> FilePath -> Maybe FileStatus -> IO () type Handler = ThreadState -> Git.Repo -> FilePath -> Maybe FileStatus -> IO ()
{- Runs an action handler. {- Runs an action handler.
- -
- Exceptions are ignored, otherwise a whole thread could be crashed. - Exceptions are ignored, otherwise a whole thread could be crashed.
-} -}
runHandler :: Git.Repo -> Handler -> FilePath -> Maybe FileStatus -> IO () runHandler :: ThreadState -> Git.Repo -> Handler -> FilePath -> Maybe FileStatus -> IO ()
runHandler g handler file filestatus = void $ do runHandler st g handler file filestatus = void $ do
either print (const noop) =<< tryIO go either print (const noop) =<< tryIO go
where where
go = handler g file filestatus go = handler st g file filestatus
{- Called when there's an error with inotify. -} {- Called when there's an error with inotify. -}
onErr :: Handler onErr :: Handler
onErr _ msg _ = error msg onErr _ _ msg _ = error msg
{- Called when a new branch ref is written. {- Called when a new branch ref is written.
- -
@ -60,16 +60,21 @@ onErr _ msg _ = error msg
- ran are merged in. - ran are merged in.
-} -}
onAdd :: Handler onAdd :: Handler
onAdd g file _ onAdd st g file _
| ".lock" `isSuffixOf` file = noop | ".lock" `isSuffixOf` file = noop
| otherwise = do | otherwise = do
let branch = Git.Ref $ "refs" </> "heads" </> takeFileName file let changedbranch = Git.Ref $
"refs" </> "heads" </> takeFileName file
current <- Git.Branch.current g current <- Git.Branch.current g
when (Just branch == current) $ when (Just changedbranch == current) $
void $ mergeBranch branch g void $ mergeBranch st changedbranch g
mergeBranch :: Git.Ref -> Git.Repo -> IO Bool mergeBranch :: ThreadState -> Git.Ref -> Git.Repo -> IO Bool
mergeBranch = Git.Merge.mergeNonInteractive . Command.Sync.syncBranch mergeBranch st branch repo = do
ok <- Git.Merge.mergeNonInteractive (Command.Sync.syncBranch branch) repo
if ok
then return ok
else runThreadState st Command.Sync.resolveMerge
{- Manually pull from remotes and merge their branches. Called by the pusher {- 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 - when a push fails, which can happen due to a remote not having pushed