diff --git a/Remote/Git.hs b/Remote/Git.hs index 0fecf1ed19..4187a5178d 100644 --- a/Remote/Git.hs +++ b/Remote/Git.hs @@ -368,9 +368,7 @@ copyFromRemote' r key file dest meterupdate | not $ Git.repoIsUrl (repo r) = guardUsable (repo r) (return False) $ do params <- Ssh.rsyncParams r Download u <- getUUID -#ifndef mingw32_HOST_OS - hardlink <- annexHardLink <$> Annex.getGitConfig -#endif + hardlink <- wantHardLink -- run copy from perspective of remote onLocal r $ do ensureInitialized @@ -378,19 +376,9 @@ copyFromRemote' r key file dest meterupdate case v of Nothing -> return False Just (object, checksuccess) -> do - let copier = rsyncOrCopyFile params object dest -#ifndef mingw32_HOST_OS - let linker = createLink object dest >> return True - go <- ifM (pure hardlink <&&> not <$> isDirect) - ( return $ \m -> liftIO (catchBoolIO linker) - <||> copier m - , return copier - ) -#else - let go = copier -#endif + copier <- mkCopier hardlink params object dest runTransfer (Transfer Download u key) - file noRetry noObserver go + file noRetry noObserver copier <&&> checksuccess | Git.repoIsSsh (repo r) = feedprogressback $ \feeder -> do direct <- isDirect @@ -506,6 +494,7 @@ copyToRemote' r key file p checksuccessio <- Annex.withCurrentState checksuccess params <- Ssh.rsyncParams r Upload u <- getUUID + hardlink <- wantHardLink -- run copy from perspective of remote onLocal r $ ifM (Annex.Content.inAnnex key) ( return True @@ -514,7 +503,7 @@ copyToRemote' r key file p runTransfer (Transfer Download u key) file noRetry noObserver $ const $ Annex.Content.saveState True `after` Annex.Content.getViaTmpChecked (liftIO checksuccessio) key - (\d -> rsyncOrCopyFile params object d p) + (\dest -> mkCopier hardlink params object dest >>= \a -> a p) ) fsckOnRemote :: Git.Repo -> [CommandParam] -> Annex (IO Bool) @@ -622,3 +611,23 @@ commitOnCleanup r a = go `after` a withQuietOutput createProcessSuccess $ proc shellcmd $ toCommand shellparams + +wantHardLink :: Annex Bool +wantHardLink = (annexHardLink <$> Annex.getGitConfig) <&&> (not <$> isDirect) + +-- If either the remote or local repository wants to use hard links, +-- the copier will do so, falling back to copying. +mkCopier :: Bool -> [CommandParam] -> FilePath -> FilePath -> Annex (MeterUpdate -> Annex Bool) +mkCopier remotewanthardlink rsyncparams object dest = do + let copier = rsyncOrCopyFile rsyncparams object dest +#ifndef mingw32_HOST_OS + localwanthardlink <- wantHardLink + let linker = createLink object dest >> return True + ifM (pure (remotewanthardlink || localwanthardlink) <&&> not <$> isDirect) + ( return $ \m -> liftIO (catchBoolIO linker) + <||> copier m + , return copier + ) +#else + return copier +#endif diff --git a/debian/changelog b/debian/changelog index eb2fed8ff1..92b6b16aba 100644 --- a/debian/changelog +++ b/debian/changelog @@ -20,6 +20,8 @@ git-annex (5.20150825) UNRELEASED; urgency=medium * sync: Add --no-commit, --no-pull, --no-push options to turn off parts of the sync process, as well as supporting --commit, --pull, --push, and --no-content options to specify the (current) default behavior. + * annex.hardlink extended to also try to use hard links when copying from + the repository to a remote. -- Joey Hess Tue, 01 Sep 2015 14:46:18 -0700 diff --git a/doc/git-annex.mdwn b/doc/git-annex.mdwn index a916b74a45..794950d76a 100644 --- a/doc/git-annex.mdwn +++ b/doc/git-annex.mdwn @@ -875,8 +875,8 @@ Here are all the supported configuration settings. * `annex.hardlink` - Set this to `true` to make file contents be hard linked into the - repository when possible, instead of a more expensive copy. + Set this to `true` to make file contents be hard linked between the + repository and its remotes when possible, instead of a more expensive copy. Use with caution -- This can invalidate numcopies counting, since with hard links, fewer copies of a file can exist. So, it is a good diff --git a/doc/todo/annex.hardlink_should_also_affect_copy_to_origin.mdwn b/doc/todo/annex.hardlink_should_also_affect_copy_to_origin.mdwn index bee0993122..d79c13f92a 100644 --- a/doc/todo/annex.hardlink_should_also_affect_copy_to_origin.mdwn +++ b/doc/todo/annex.hardlink_should_also_affect_copy_to_origin.mdwn @@ -3,3 +3,5 @@ repository when eg `git annex copy --from origin`. This should also be done when copying files --to origin (or other remotes on the same filesystem). This way, a quick shared clone can be used to add/modify files, and cheaply send the changes back to the parent repo. --[[Joey]] + +> [[done]] --[[Joey]]