diff options
-rw-r--r-- | Command/Sync.hs | 31 | ||||
-rw-r--r-- | Test.hs | 18 | ||||
-rw-r--r-- | debian/changelog | 3 |
3 files changed, 42 insertions, 10 deletions
diff --git a/Command/Sync.hs b/Command/Sync.hs index c9493b2a4..331f5d03f 100644 --- a/Command/Sync.hs +++ b/Command/Sync.hs @@ -392,14 +392,10 @@ resolveMerge' u -- Our side is annexed, other side is not. (Just keyUs, Nothing) -> do ifM isDirect - -- Move newly added non-annexed object - -- out of direct mode merge directory. ( do removeoldfile keyUs makelink keyUs - d <- fromRepo gitAnnexMergeDir - liftIO $ rename (d </> file) file - -- cleaup tree after git merge + movefromdirectmerge file , do unstageoldfile makelink keyUs @@ -433,6 +429,31 @@ resolveMerge' u getKey select = case select (LsFiles.unmergedSha u) of Nothing -> return Nothing Just sha -> catKey sha symLinkMode + + {- Move something out of the direct mode merge directory and into + - the git work tree. + - + - On a filesystem not supporting symlinks, this is complicated + - because a directory may contain annex links, but just + - moving them into the work tree will not let git know they are + - symlinks. + - + - Also, if the content of the file is available, make it available + - in direct mode. + -} + movefromdirectmerge item = do + d <- fromRepo gitAnnexMergeDir + liftIO $ rename (d </> item) item + mapM_ setuplink =<< liftIO (dirContentsRecursive item) + setuplink f = do + v <- getAnnexLinkTarget f + case v of + Nothing -> noop + Just target -> do + unlessM (coreSymlinks <$> Annex.getGitConfig) $ + addAnnexLink target f + maybe noop (flip toDirect f) + (fileKey (takeFileName target)) {- git-merge moves conflicting files away to files - named something like f~HEAD or f~branch, but the @@ -187,8 +187,8 @@ unitTests note getenv = testGroup ("Unit Tests " ++ note) , check "sync" test_sync , check "union merge regression" test_union_merge_regression , check "conflict resolution" test_conflict_resolution_movein_bug - , check "sync push" test_sync_push , check "conflict_resolution (mixed directory and file)" test_mixed_conflict_resolution + , check "conflict_resolution (mixed directory and file) 2" test_mixed_conflict_resolution2 , check "map" test_map , check "uninit" test_uninit , check "uninit (in git-annex branch)" test_uninit_inbranch @@ -841,11 +841,19 @@ test_mixed_conflict_resolution env = do any (variantprefix `isPrefixOf`) l @? (what ++ " conflictor file missing in: " ++ show l ) -{- A windows-specific failure of mixed conflict resolution. -} -test_sync_push :: TestEnv -> Assertion -test_sync_push env = check >> check +{- + - During conflict resolution, one of the annexed files in git is + - accidentially converted from a symlink to a regular file. + - This only happens on crippled filesystems. + - + - This test case happens to detect the problem when it tries the next + - pass of conflict resolution, since it's unable to resolve a conflict + - between an annexed and non-annexed file. + -} +test_mixed_conflict_resolution2 :: TestEnv -> Assertion +test_mixed_conflict_resolution2 env = go >> go where - check = withtmpclonerepo env False $ \r1 -> + go = withtmpclonerepo env False $ \r1 -> withtmpclonerepo env False $ \r2 -> do indir env r1 $ do writeFile conflictor "conflictor" diff --git a/debian/changelog b/debian/changelog index e6607fdde..275bf96b3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -13,6 +13,9 @@ git-annex (5.20140128) UNRELEASED; urgency=medium Closes: #737480 * sync --content: Drop files from remotes that don't have them after getting them. + * sync: Fix bug in automatic merge conflict resolution code when used + on a filesystem not supporting symlinks, which resulted in it losing + track of the symlink bit of annexed files. * Added ways to configure rsync options to be used only when uploading or downloading from a remote. Useful to eg limit upload bandwidth. * Document in man page that sshcaching uses ssh ControlMaster. |