summaryrefslogtreecommitdiff
path: root/Annex
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2011-12-11 16:11:13 -0400
committerGravatar Joey Hess <joey@kitenet.net>2011-12-11 16:14:59 -0400
commitcfbbda99f4dd3e510e52dbb499d132300ad203e4 (patch)
tree0d3a392a631e982b1ccba1c3bc390ece9f39e98a /Annex
parent8680c415dedcc1fdbbcc0b9cdd7e37e860b22130 (diff)
optimize index updating
The last branch ref that the index was updated to is stored in .git/annex/index.lck, and the index only updated when the current branch ref differs. (The .lck file should later be used for locking too.) Some more optimization is still needed, since there is some redundancy in calls to git show-ref.
Diffstat (limited to 'Annex')
-rw-r--r--Annex/Branch.hs54
1 files changed, 43 insertions, 11 deletions
diff --git a/Annex/Branch.hs b/Annex/Branch.hs
index be19a9be0..52e82e25c 100644
--- a/Annex/Branch.hs
+++ b/Annex/Branch.hs
@@ -61,9 +61,26 @@ mergeIndex branches = do
inRepo $ \g -> Git.UnionMerge.merge_index h g branches
{- Updates the branch's index to reflect the current contents of the branch.
- - Any changes staged in the index will be preserved. -}
+ - Any changes staged in the index will be preserved.
+ -
+ - Compares the ref stored in the lock file with the current
+ - ref of the branch to see if an update is needed.
+ -}
updateIndex :: Annex ()
-updateIndex = withIndex $ mergeIndex [fullname]
+updateIndex = do
+ lock <- fromRepo gitAnnexIndexLock
+ lockref <- firstRef <$> liftIO (catchDefaultIO (readFileStrict lock) "")
+ branchref <- getRef fullname
+ when (lockref /= branchref) $ do
+ withIndex $ mergeIndex [fullname]
+ setIndexRef branchref
+
+{- Record that the branch's index has been updated to correspond to a
+ - given ref of the branch. -}
+setIndexRef :: Git.Ref -> Annex ()
+setIndexRef ref = do
+ lock <- fromRepo gitAnnexIndexLock
+ liftIO $ writeFile lock $ show ref ++ "\n"
{- Runs an action using the branch's index file. -}
withIndex :: Annex a -> Annex a
@@ -109,12 +126,13 @@ getCache file = getState >>= go
{- Creates the branch, if it does not already exist. -}
create :: Annex ()
-create = unlessM hasBranch $ do
- e <- hasOrigin
- if e
- then inRepo $ Git.run "branch"
- [Param $ show name, Param $ show originname]
- else withIndex' True $
+create = unlessM hasBranch $ hasOrigin >>= go >>= setIndexRef
+ where
+ go True = do
+ inRepo $ Git.run "branch"
+ [Param $ show name, Param $ show originname]
+ getRef fullname
+ go False = withIndex' True $
inRepo $ Git.commit "branch created" fullname []
{- Stages the journal, and commits staged changes to the branch. -}
@@ -122,7 +140,8 @@ commit :: String -> Annex ()
commit message = whenM journalDirty $ lockJournal $ do
updateIndex
stageJournalFiles
- withIndex $ inRepo $ Git.commit message fullname [fullname]
+ withIndex $
+ setIndexRef =<< inRepo (Git.commit message fullname [fullname])
{- Ensures that the branch and index are is up-to-date; should be
- called before data is read from it. Runs only once per git-annex run.
@@ -159,8 +178,9 @@ update = onceonly $ do
showSideAction merge_desc
mergeIndex branches
ff <- if dirty then return False else tryFastForwardTo refs
- unless ff $ inRepo $
- Git.commit merge_desc fullname (nub $ fullname:refs)
+ unless ff $
+ setIndexRef =<<
+ inRepo (Git.commit merge_desc fullname (nub $ fullname:refs))
invalidateCache
where
onceonly a = unlessM (branchUpdated <$> getState) $ do
@@ -253,6 +273,18 @@ siblingBranches = do
gen l = (Git.Ref $ head l, Git.Ref $ last l)
uref (a, _) (b, _) = a == b
+{- Get the ref of a branch. -}
+getRef :: Git.Ref -> Annex Git.Ref
+getRef branch = firstRef . L.unpack <$> showref
+ where
+ showref = inRepo $ Git.pipeRead [Param "show-ref",
+ Param "--hash", -- get the hash
+ Param "--verify", -- only exact match
+ Param $ show branch]
+
+firstRef :: String-> Git.Ref
+firstRef = Git.Ref . takeWhile (/= '\n')
+
{- Applies a function to modifiy the content of a file.
-
- Note that this does not cause the branch to be merged, it only