@@ -70,7 +70,7 @@ import qualified Unison.Codebase as Codebase1
7070import Unison.Codebase.Branch (Branch (.. ))
7171import qualified Unison.Codebase.Branch as Branch
7272import qualified Unison.Codebase.Causal as Causal
73- import Unison.Codebase.Editor.Git (gitIn , gitTextIn , pullBranch )
73+ import Unison.Codebase.Editor.Git (gitIn , gitTextIn , pullRepo , withIsolatedRepo )
7474import Unison.Codebase.Editor.RemoteRepo (ReadRemoteNamespace , WriteRepo (WriteGitRepo ), printWriteRepo , writeToRead )
7575import qualified Unison.Codebase.GitError as GitError
7676import qualified Unison.Codebase.Init as Codebase
@@ -91,7 +91,7 @@ import Unison.DataDeclaration (Decl)
9191import qualified Unison.DataDeclaration as Decl
9292import Unison.Hash (Hash )
9393import Unison.Parser.Ann (Ann )
94- import Unison.Prelude ( MaybeT ( runMaybeT ), fromMaybe , isJust , trace , traceM )
94+ import Unison.Prelude
9595import Unison.Reference (Reference )
9696import qualified Unison.Reference as Reference
9797import qualified Unison.Referent as Referent
@@ -110,6 +110,7 @@ import qualified UnliftIO
110110import UnliftIO.Directory (canonicalizePath , createDirectoryIfMissing , doesDirectoryExist , doesFileExist )
111111import UnliftIO.STM
112112import UnliftIO.Exception (catch , bracket )
113+ import Data.Either.Extra (mapLeft )
113114
114115debug , debugProcessBranches , debugCommitFailedTransaction :: Bool
115116debug = False
@@ -124,7 +125,7 @@ v2dir root = root </> ".unison" </> "v2"
124125
125126init :: HasCallStack => (MonadUnliftIO m ) => Codebase. Init m Symbol Ann
126127init = Codebase. Init
127- { withOpenCodebase= getCodebaseOrError
128+ { withOpenCodebase= withCodebaseOrError
128129 , withCreatedCodebase= createCodebaseOrError
129130 , codebasePath= v2dir
130131 }
@@ -176,7 +177,7 @@ createCodebaseOrError' debugName path action = do
176177withOpenOrCreateCodebaseConnection ::
177178 (MonadUnliftIO m ) =>
178179 Codebase. DebugName ->
179- FilePath ->
180+ CodebasePath ->
180181 (Connection -> m r ) ->
181182 m r
182183withOpenOrCreateCodebaseConnection debugName path action = do
@@ -186,14 +187,14 @@ withOpenOrCreateCodebaseConnection debugName path action = do
186187 withConnection debugName path action
187188
188189-- get the codebase in dir
189- getCodebaseOrError ::
190+ withCodebaseOrError ::
190191 forall m r .
191192 (MonadUnliftIO m ) =>
192193 Codebase. DebugName ->
193194 CodebasePath ->
194195 (Codebase m Symbol Ann -> m r ) ->
195196 m (Either Codebase1. Pretty r )
196- getCodebaseOrError debugName dir action = do
197+ withCodebaseOrError debugName dir action = do
197198 prettyDir <- liftIO $ P. string <$> canonicalizePath dir
198199 let prettyError v = P. wrap $ " I don't know how to handle " <> P. shown v <> " in" <> P. backticked' prettyDir " ."
199200 doesFileExist (dir </> codebasePath) >>= \ case
@@ -1047,7 +1048,7 @@ viewRemoteBranch' ::
10471048 m (Either C. GitError r )
10481049viewRemoteBranch' (repo, sbh, path) action = UnliftIO. try do
10491050 -- set up the cache dir
1050- remotePath <- UnliftIO. fromEitherM . runExceptT . withExceptT C. GitProtocolError . time " Git fetch" $ pullBranch repo
1051+ remotePath <- UnliftIO. fromEitherM . runExceptT . withExceptT C. GitProtocolError . time " Git fetch" $ pullRepo repo
10511052
10521053 -- Tickle the database before calling into `sqliteCodebase`; this covers the case that the database file either
10531054 -- doesn't exist at all or isn't a SQLite database file, but does not cover the case that the database file itself is
@@ -1112,44 +1113,45 @@ pushGitBranch srcConn branch repo (PushGitBranchOpts setRoot _syncMode) = runExc
11121113 -- otherwise, proceed: release the savepoint (commit it), clean up, and git-push the result
11131114
11141115 -- set up the cache dir
1115- remotePath <- time " Git fetch" $ withExceptT C. GitProtocolError $ pullBranch (writeToRead repo)
1116- ExceptT . withOpenOrCreateCodebaseConnection " push.dest" remotePath $ \ destConn -> do
1117- flip runReaderT destConn $ Q. savepoint " push"
1118- flip State. execStateT emptySyncProgressState $
1119- syncInternal syncProgress srcConn destConn (Branch. transform lift branch)
1120- flip runReaderT destConn do
1121- result <- if setRoot
1122- then do
1123- let newRootHash = Branch. headHash branch
1124- -- the call to runDB "handles" the possible DB error by bombing
1125- (fmap . fmap ) Cv. branchHash2to1 (runDB destConn Ops. loadMaybeRootCausalHash) >>= \ case
1126- Nothing -> do
1127- setRepoRoot newRootHash
1128- Q. release " push"
1129- pure $ Right ()
1130- Just oldRootHash -> do
1131- before oldRootHash newRootHash >>= \ case
1132- Nothing ->
1133- error $
1134- " I couldn't find the hash " ++ show newRootHash
1135- ++ " that I just synced to the cached copy of "
1136- ++ repoString
1137- ++ " in "
1138- ++ show remotePath
1139- ++ " ."
1140- Just False -> do
1141- Q. rollbackRelease " push"
1142- pure . Left . C. GitProtocolError $ GitError. PushDestinationHasNewStuff repo
1143- Just True -> do
1116+ pathToCachedRemote <- time " Git fetch" $ withExceptT C. GitProtocolError $ pullRepo (writeToRead repo)
1117+ _ . withIsolatedRepo pathToCachedRemote $ \ tempRemotePath -> do
1118+ withConnection " push.cached" pathToCachedRemote $ \ cachedRemoteConn -> do
1119+ copyCodebase cachedRemoteConn tempRemotePath
1120+ withConnection " push.dest" repoPath $ \ destConn -> do
1121+ flip runReaderT destConn $ Q. savepoint " push"
1122+ flip State. execStateT emptySyncProgressState $
1123+ syncInternal syncProgress srcConn destConn (Branch. transform lift branch)
1124+ flip runReaderT destConn do
1125+ result <- if setRoot
1126+ then do
1127+ let newRootHash = Branch. headHash branch
1128+ -- the call to runDB "handles" the possible DB error by bombing
1129+ (fmap . fmap ) Cv. branchHash2to1 (runDB destConn Ops. loadMaybeRootCausalHash) >>= \ case
1130+ Nothing -> do
11441131 setRepoRoot newRootHash
11451132 Q. release " push"
11461133 pure $ Right ()
1147- else do
1148- Q. release " push"
1149- pure $ Right ()
1150-
1151- Q. setJournalMode JournalMode. DELETE
1152- pure result
1134+ Just oldRootHash -> do
1135+ before oldRootHash newRootHash >>= \ case
1136+ Nothing ->
1137+ error $
1138+ " I couldn't find the hash " ++ show newRootHash
1139+ ++ " that I just synced to the cached copy of "
1140+ ++ repoString
1141+ ++ " in "
1142+ ++ show remotePath
1143+ ++ " ."
1144+ Just False -> do
1145+ Q. rollbackRelease " push"
1146+ pure . Left . C. GitProtocolError $ GitError. PushDestinationHasNewStuff repo
1147+ Just True -> do
1148+ setRepoRoot newRootHash
1149+ Q. release " push"
1150+ pure $ Right ()
1151+ else do
1152+ Q. release " push"
1153+ pure $ Right ()
1154+ pure result
11531155 liftIO do
11541156 void $ push remotePath repo
11551157 where
@@ -1232,3 +1234,15 @@ pushGitBranch srcConn branch repo (PushGitBranchOpts setRoot _syncMode) = runExc
12321234 -- Push our changes to the repo
12331235 gitIn remotePath [" push" , " --quiet" , url]
12341236 pure True
1237+
1238+
1239+ -- -- | Execute the given block over an isolated instance of the given codebase.
1240+ -- -- The codebase is ephemeral and will be deleted after the block is completed.
1241+ -- withIsolatedRemote :: MonadUnliftIO m => Codebase.DebugName -> FilePath -> (Connection -> m r) -> m (Either C.GitError r)
1242+ -- withIsolatedRemote debugName repoPath action = mapLeft C.GitProtocolError <$> do
1243+ -- withIsolatedRepo repoPath $ \repoPath -> do
1244+ -- withConnection debugName repoPath $ action
1245+
1246+ copyCodebase :: MonadIO m => Connection -> CodebasePath -> m ()
1247+ copyCodebase srcConn destPath = runDB srcConn $ do
1248+ Q. vacuumInto (destPath </> codebasePath)
0 commit comments