withAltRepo needs a separate queue of changes

The queue could potentially contain changes from before withAltRepo, and
get flushed inside the call, which would apply the changes to the modified
repo.

Or, changes could be queued in withAltRepo that were intended to affect
the modified repo, but don't get flushed until later.

I don't know of any cases where either happens, but better safe than sorry.

Note that this affect withIndexFile, which is used in git-annex branch
updates. So, it potentially makes things slower. Should not be by much;
the overhead consists only of querying the current queue a couple of times,
and potentially flushing changes queued within withAltRepo earlier, that
could have maybe been bundled with other later changes.

Notice in particular that the existing queue is not flushed when calling
withAltRepo. So eg when git annex add needs to stage files in the index,
it will still bundle them together efficiently.
This commit is contained in:
Joey Hess 2016-06-03 13:48:14 -04:00
parent 5ed3e6df3c
commit 8148ee3d4b
Failed to extract signature
2 changed files with 16 additions and 4 deletions

View file

@ -15,6 +15,7 @@ import Git.Types
import Git.Index import Git.Index
import Git.Env import Git.Env
import qualified Annex import qualified Annex
import qualified Annex.Queue
{- Runs an action using a different git index file. -} {- Runs an action using a different git index file. -}
withIndexFile :: FilePath -> Annex a -> Annex a withIndexFile :: FilePath -> Annex a -> Annex a
@ -71,8 +72,18 @@ withAltRepo
withAltRepo modrepo unmodrepo a = do withAltRepo modrepo unmodrepo a = do
g <- gitRepo g <- gitRepo
g' <- liftIO $ modrepo g g' <- liftIO $ modrepo g
r <- tryNonAsync $ do q <- Annex.Queue.get
Annex.changeState $ \s -> s { Annex.repo = g' } v <- tryNonAsync $ do
Annex.changeState $ \s -> s
{ Annex.repo = g'
-- Start a separate queue for any changes made
-- with the modified repo.
, Annex.repoqueue = Nothing
}
a a
Annex.changeState $ \s -> s { Annex.repo = unmodrepo g (Annex.repo s) } void $ tryNonAsync Annex.Queue.flush
either E.throw return r Annex.changeState $ \s -> s
{ Annex.repo = unmodrepo g (Annex.repo s)
, Annex.repoqueue = Just q
}
either E.throw return v

View file

@ -13,6 +13,7 @@ module Annex.Queue (
flush, flush,
flushWhenFull, flushWhenFull,
size, size,
get,
mergeFrom, mergeFrom,
) where ) where