summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joeyh@joeyh.name>2015-09-14 12:13:38 -0400
committerGravatar Joey Hess <joeyh@joeyh.name>2015-09-14 12:13:38 -0400
commite323354b4ca2a44baae8223b9dd47aaab234a56a (patch)
tree6d3a7f0ffecd6d8cfe7a4c10cf7136a877d20ce4
parent0685f4f87a84396a26433c99300bae8a8aefa1e2 (diff)
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.
-rw-r--r--Remote/Git.hs41
-rw-r--r--debian/changelog2
-rw-r--r--doc/git-annex.mdwn4
-rw-r--r--doc/todo/annex.hardlink_should_also_affect_copy_to_origin.mdwn2
4 files changed, 31 insertions, 18 deletions
diff --git a/Remote/Git.hs b/Remote/Git.hs
index 0fecf1ed1..4187a5178 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 eb2fed8ff..92b6b16ab 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 <id@joeyh.name> Tue, 01 Sep 2015 14:46:18 -0700
diff --git a/doc/git-annex.mdwn b/doc/git-annex.mdwn
index a916b74a4..794950d76 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 bee099312..d79c13f92 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]]