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.
This commit is contained in:
Joey Hess 2013-05-20 13:37:52 -04:00
parent 3bac3b5b51
commit f4ba19f2b8
2 changed files with 10 additions and 11 deletions

View file

@ -158,13 +158,10 @@ mergeDirectCleanup d oldsha newsha = do
nukeFile f nukeFile f
void $ tryIO $ removeDirectory $ parentDir f void $ tryIO $ removeDirectory $ parentDir f
{- The symlink is created from the key, rather than moving in the {- If the file is already present, with the right content for the
- symlink created in the temp directory by the merge. This because - key, it's left alone. Otherwise, create the symlink and then
- a conflicted merge will write to some other file in the temp - if possible, replace it with the content. -}
- directory. movein k f = unlessM (goodContent k f) $ do
-
- Symlinks are replaced with their content, if it's available. -}
movein k f = do
l <- inRepo $ gitAnnexLink f k l <- inRepo $ gitAnnexLink f k
replaceFile f $ makeAnnexLink l replaceFile f $ makeAnnexLink l
toDirect k f toDirect k f
@ -206,13 +203,12 @@ toDirectGen k f = do
liftIO . void . copyFileExternal loc liftIO . void . copyFileExternal loc
_ -> return Nothing _ -> 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 :: Key -> FilePath -> Annex ()
removeDirect k f = do removeDirect k f = do
locs <- removeAssociatedFile k f locs <- removeAssociatedFile k f
when (null locs) $ unlessM (inAnnex k) $
whenM (isNothing <$> getAnnexLinkTarget f) $ moveAnnex k f
moveAnnex k f
liftIO $ do liftIO $ do
nukeFile f nukeFile f
void $ tryIO $ removeDirectory $ parentDir f void $ tryIO $ removeDirectory $ parentDir f

3
debian/changelog vendored
View file

@ -12,6 +12,9 @@ git-annex (4.20130517) UNRELEASED; urgency=low
failing to link -lHSrts_thr failing to link -lHSrts_thr
* Temporarily build without webapp on kfreebsd-i386, until yesod is * Temporarily build without webapp on kfreebsd-i386, until yesod is
installable there again. 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 -- Joey Hess <joeyh@debian.org> Fri, 17 May 2013 11:17:03 -0400