annex.hardlink extended to also try to use hard links when copying from the repository to a remote.

Also, it used to only check that one of the repos was not in direct mode;
now when either repo is direct mode, annex.hardlink won't have an effect.
This commit is contained in:
Joey Hess 2015-09-14 12:13:38 -04:00
parent c5260f5cb0
commit ffa8221517
4 changed files with 31 additions and 18 deletions

View file

@ -368,9 +368,7 @@ copyFromRemote' r key file dest meterupdate
| not $ Git.repoIsUrl (repo r) = guardUsable (repo r) (return False) $ do | not $ Git.repoIsUrl (repo r) = guardUsable (repo r) (return False) $ do
params <- Ssh.rsyncParams r Download params <- Ssh.rsyncParams r Download
u <- getUUID u <- getUUID
#ifndef mingw32_HOST_OS hardlink <- wantHardLink
hardlink <- annexHardLink <$> Annex.getGitConfig
#endif
-- run copy from perspective of remote -- run copy from perspective of remote
onLocal r $ do onLocal r $ do
ensureInitialized ensureInitialized
@ -378,19 +376,9 @@ copyFromRemote' r key file dest meterupdate
case v of case v of
Nothing -> return False Nothing -> return False
Just (object, checksuccess) -> do Just (object, checksuccess) -> do
let copier = rsyncOrCopyFile params object dest copier <- mkCopier hardlink 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
runTransfer (Transfer Download u key) runTransfer (Transfer Download u key)
file noRetry noObserver go file noRetry noObserver copier
<&&> checksuccess <&&> checksuccess
| Git.repoIsSsh (repo r) = feedprogressback $ \feeder -> do | Git.repoIsSsh (repo r) = feedprogressback $ \feeder -> do
direct <- isDirect direct <- isDirect
@ -506,6 +494,7 @@ copyToRemote' r key file p
checksuccessio <- Annex.withCurrentState checksuccess checksuccessio <- Annex.withCurrentState checksuccess
params <- Ssh.rsyncParams r Upload params <- Ssh.rsyncParams r Upload
u <- getUUID u <- getUUID
hardlink <- wantHardLink
-- run copy from perspective of remote -- run copy from perspective of remote
onLocal r $ ifM (Annex.Content.inAnnex key) onLocal r $ ifM (Annex.Content.inAnnex key)
( return True ( return True
@ -514,7 +503,7 @@ copyToRemote' r key file p
runTransfer (Transfer Download u key) file noRetry noObserver $ const $ runTransfer (Transfer Download u key) file noRetry noObserver $ const $
Annex.Content.saveState True `after` Annex.Content.saveState True `after`
Annex.Content.getViaTmpChecked (liftIO checksuccessio) key 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) fsckOnRemote :: Git.Repo -> [CommandParam] -> Annex (IO Bool)
@ -622,3 +611,23 @@ commitOnCleanup r a = go `after` a
withQuietOutput createProcessSuccess $ withQuietOutput createProcessSuccess $
proc shellcmd $ proc shellcmd $
toCommand shellparams 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

2
debian/changelog vendored
View file

@ -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 * 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 the sync process, as well as supporting --commit, --pull, --push, and
--no-content options to specify the (current) default behavior. --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 <id@joeyh.name> Tue, 01 Sep 2015 14:46:18 -0700 -- Joey Hess <id@joeyh.name> Tue, 01 Sep 2015 14:46:18 -0700

View file

@ -875,8 +875,8 @@ Here are all the supported configuration settings.
* `annex.hardlink` * `annex.hardlink`
Set this to `true` to make file contents be hard linked into the Set this to `true` to make file contents be hard linked between the
repository when possible, instead of a more expensive copy. repository and its remotes when possible, instead of a more expensive copy.
Use with caution -- This can invalidate numcopies counting, since Use with caution -- This can invalidate numcopies counting, since
with hard links, fewer copies of a file can exist. So, it is a good with hard links, fewer copies of a file can exist. So, it is a good

View file

@ -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 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 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]] files, and cheaply send the changes back to the parent repo. --[[Joey]]
> [[done]] --[[Joey]]