summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2011-10-07 13:17:54 -0400
committerGravatar Joey Hess <joey@kitenet.net>2011-10-07 13:36:48 -0400
commit3acdba3995941907028905a7c18362309af924b5 (patch)
tree73defda86adbd59c19f7e23eed8581d97f6aa69a
parent5414bbce58041aa92f2a50a8e721507879000f77 (diff)
faster union merge of multiple branches into index
only write index once
-rw-r--r--Annex/Branch.hs28
-rw-r--r--Git/UnionMerge.hs17
-rw-r--r--git-union-merge.hs2
3 files changed, 21 insertions, 26 deletions
diff --git a/Annex/Branch.hs b/Annex/Branch.hs
index 0b4bea051..db4379243 100644
--- a/Annex/Branch.hs
+++ b/Annex/Branch.hs
@@ -139,8 +139,18 @@ update = do
- from the branches.
-}
unless (null fs) $ stageJournalFiles fs
- mapM_ mergeref refs
g <- gitRepo
+ unless (null refs) $ do
+ showSideAction $ "merging " ++
+ (unwords $ map Git.refDescribe refs) ++
+ " into " ++ name
+ {- Note: This merges the branches into the index.
+ - Any unstaged changes in the git-annex branch
+ - (if it's checked out) will be removed. So,
+ - documentation advises users not to directly
+ - modify the branch.
+ -}
+ liftIO $ Git.UnionMerge.merge_index g refs
liftIO $ Git.commit g "update" fullname (fullname:refs)
Annex.changeState $ \s -> s { Annex.branchstate = state { branchUpdated = True } }
invalidateCache
@@ -155,22 +165,6 @@ update = do
Params "--oneline -n1"
]
return $ not $ L.null diffs
- mergeref ref = do
- showSideAction $ "merging " ++
- Git.refDescribe ref ++ " into " ++ name
- {- By passing only one ref, it is actually
- - merged into the index, preserving any
- - changes that may already be staged.
- -
- - However, any changes in the git-annex
- - branch that are *not* reflected in the
- - index will be removed. So, documentation
- - advises users not to directly modify the
- - branch.
- -}
- g <- gitRepo
- liftIO $ Git.UnionMerge.merge g [ref]
- return $ Just ref
{- Checks if a git ref exists. -}
refExists :: GitRef -> Annex Bool
diff --git a/Git/UnionMerge.hs b/Git/UnionMerge.hs
index ac002b374..859a66ca0 100644
--- a/Git/UnionMerge.hs
+++ b/Git/UnionMerge.hs
@@ -7,6 +7,7 @@
module Git.UnionMerge (
merge,
+ merge_index,
update_index,
update_index_line,
ls_tree
@@ -18,24 +19,24 @@ import Data.Maybe
import Data.String.Utils
import qualified Data.ByteString.Lazy.Char8 as L
+import Common
import Git
-import Utility.SafeCommand
{- Performs a union merge between two branches, staging it in the index.
- Any previously staged changes in the index will be lost.
-
- - When only one branch is specified, it is merged into the index.
- - In this case, previously staged changes in the index are preserved.
- -
- Should be run with a temporary index file configured by Git.useIndex.
-}
-merge :: Repo -> [String] -> IO ()
-merge g (x:y:[]) = do
+merge :: Repo -> String -> String -> IO ()
+merge g x y = do
a <- ls_tree g x
b <- merge_trees g x y
update_index g (a++b)
-merge g [x] = merge_tree_index g x >>= update_index g
-merge _ _ = error "wrong number of branches to merge"
+
+{- Merges a list of branches into the index. Previously staged changed in
+ - the index are preserved (and participate in the merge). -}
+merge_index :: Repo -> [String] -> IO ()
+merge_index g bs = update_index g =<< concat <$> mapM (merge_tree_index g) bs
{- Feeds a list into update-index. Later items in the list can override
- earlier ones, so the list can be generated from any combination of
diff --git a/git-union-merge.hs b/git-union-merge.hs
index 34f22d06f..0d1d0819d 100644
--- a/git-union-merge.hs
+++ b/git-union-merge.hs
@@ -41,6 +41,6 @@ main = do
g <- Git.configRead =<< Git.repoFromCwd
_ <- Git.useIndex (tmpIndex g)
setup g
- Git.UnionMerge.merge g [aref, bref]
+ Git.UnionMerge.merge g aref bref
Git.commit g "union merge" newref [aref, bref]
cleanup g