summaryrefslogtreecommitdiff
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
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.
-rw-r--r--Annex/Direct.hs18
-rw-r--r--debian/changelog3
2 files changed, 10 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
diff --git a/debian/changelog b/debian/changelog
index a68b62dd9..c302f55b5 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -12,6 +12,9 @@ git-annex (4.20130517) UNRELEASED; urgency=low
failing to link -lHSrts_thr
* Temporarily build without webapp on kfreebsd-i386, until yesod is
installable there again.
+ * 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.
-- Joey Hess <joeyh@debian.org> Fri, 17 May 2013 11:17:03 -0400