diff options
author | Joey Hess <joey@kitenet.net> | 2013-01-16 21:31:06 -0400 |
---|---|---|
committer | Joey Hess <joey@kitenet.net> | 2013-01-16 21:31:06 -0400 |
commit | fb442da95e9f60a7fd5ee9e6c46792d256d2dca0 (patch) | |
tree | 13fcaa67a7988fe379e1ebe274a351e85747041a /Git/UnionMerge.hs | |
parent | 2fd0c120e18c2af234fd9a1a403d6ba3af850f83 (diff) |
union merge bugfix
Union merges involving two or more repositories could sometimes result in
data from one repository getting lost. This could result in the location
log data becoming wrong, and fsck being needed to fix it.
NB: I audited for any other occurrences of this problem. There are other
places than union merge where multiple changes are fed into update-index
in a stream, but they all involve working copy files being staged, or their
deletion being staged, and in this case it's fine for the later changes
to override the earlier ones.
Diffstat (limited to 'Git/UnionMerge.hs')
-rw-r--r-- | Git/UnionMerge.hs | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/Git/UnionMerge.hs b/Git/UnionMerge.hs index 05d512df3..464200af4 100644 --- a/Git/UnionMerge.hs +++ b/Git/UnionMerge.hs @@ -38,10 +38,16 @@ merge x y repo = do catFileStop h {- Merges a list of branches into the index. Previously staged changes in - - the index are preserved (and participate in the merge). -} + - the index are preserved (and participate in the merge). + - + - update-index is run once per ref in turn, so that each ref is merged on + - top of the merge for the previous ref. It would be more efficient, but + - harder to calculate a single union merge involving all the refs, as well + - as the index. + -} mergeIndex :: CatFileHandle -> Repo -> [Ref] -> IO () -mergeIndex h repo bs = - streamUpdateIndex repo $ map (\b -> mergeTreeIndex b h repo) bs +mergeIndex h repo bs = forM_ bs $ \b -> + streamUpdateIndex repo [mergeTreeIndex b h repo] {- For merging two trees. -} mergeTrees :: Ref -> Ref -> CatFileHandle -> Repo -> Streamer |