summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Command/Sync.hs31
-rw-r--r--Test.hs18
-rw-r--r--debian/changelog3
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
diff --git a/Test.hs b/Test.hs
index 3402b2831..3def4a2ad 100644
--- a/Test.hs
+++ b/Test.hs
@@ -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.