summaryrefslogtreecommitdiff
path: root/Annex/Direct.hs
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2013-05-20 13:37:52 -0400
committerGravatar Joey Hess <joey@kitenet.net>2013-05-20 13:41:09 -0400
commitcb8dac8816d91928f177e48282daf0a4296debe3 (patch)
tree7f3f4f796f158f47076eb9a5eb1da54c045f0b71 /Annex/Direct.hs
parent96584fef7e231772f81e8af981c0e22bbf9f8f47 (diff)
direct mode bug fix: After a conflicted merge was automatically resolved, the content of a file that was already present could incorrectly be replaced with a symlink.
The bug was in movein, which just replaceFile'd the file with a symlink, even if it already had the desired content, before trying to pull the content out of the annex and replace the symlink with it. That was ok-ish for non conflicted merges, where if the file existed it would be an old version of the content. But for conflicted merges, the automatic merge resolver has already run, and will have already put the desired content into the file for the local variant. Also, made removeDirect not trust that the associated files map is correct. Only if it can verify that another file has the content will it not move it into .git/annex/objects.
Diffstat (limited to 'Annex/Direct.hs')
-rw-r--r--Annex/Direct.hs18
1 files changed, 7 insertions, 11 deletions
diff --git a/Annex/Direct.hs b/Annex/Direct.hs
index 02fdb2430..1db046e7b 100644
--- a/Annex/Direct.hs
+++ b/Annex/Direct.hs
@@ -158,13 +158,10 @@ mergeDirectCleanup d oldsha newsha = do
nukeFile f
void $ tryIO $ removeDirectory $ parentDir f
- {- The symlink is created from the key, rather than moving in the
- - symlink created in the temp directory by the merge. This because
- - a conflicted merge will write to some other file in the temp
- - directory.
- -
- - Symlinks are replaced with their content, if it's available. -}
- movein k f = do
+ {- If the file is already present, with the right content for the
+ - key, it's left alone. Otherwise, create the symlink and then
+ - if possible, replace it with the content. -}
+ movein k f = unlessM (goodContent k f) $ do
l <- inRepo $ gitAnnexLink f k
replaceFile f $ makeAnnexLink l
toDirect k f
@@ -206,13 +203,12 @@ toDirectGen k f = do
liftIO . void . copyFileExternal loc
_ -> return Nothing
-{- Removes a direct mode file, while retaining its content. -}
+{- Removes a direct mode file, while retaining its content in the annex. -}
removeDirect :: Key -> FilePath -> Annex ()
removeDirect k f = do
locs <- removeAssociatedFile k f
- when (null locs) $
- whenM (isNothing <$> getAnnexLinkTarget f) $
- moveAnnex k f
+ unlessM (inAnnex k) $
+ moveAnnex k f
liftIO $ do
nukeFile f
void $ tryIO $ removeDirectory $ parentDir f