Do not preserve permissions and acls when copying files from one local git repository to another. Timestamps are still preserved as long as cp --preserve=timestamps is supported.

This avoids cp -a overriding the default mode acls that the user might have
set in a git repository.

With GNU cp, this behavior change should not be a breaking change, because
git-anex also uses rsync sometimes in the same situation, and has only ever
preserved timestamps when using rsync.

Systems without GNU cp will no longer use cp -a, but instead just cp.
So, timestamps will no longer be preserved. Preserving timestamps when
copying between repos is not guaranteed anyway.

Closes: #729757
This commit is contained in:
Joey Hess 2014-08-26 17:06:43 -07:00
parent 06b51f67ac
commit 6eb5c3f479
11 changed files with 28 additions and 16 deletions

View file

@ -580,7 +580,7 @@ preseedTmp key file = go =<< inAnnex key
( return True ( return True
, do , do
s <- calcRepo $ gitAnnexLocation key s <- calcRepo $ gitAnnexLocation key
liftIO $ copyFileExternal s file liftIO $ copyFileExternal CopyTimeStamps s file
) )
{- Blocks writing to an annexed file, and modifies file permissions to {- Blocks writing to an annexed file, and modifies file permissions to

View file

@ -210,7 +210,7 @@ addContentWhenNotPresent key contentfile associatedfile = do
v <- isAnnexLink associatedfile v <- isAnnexLink associatedfile
when (Just key == v) $ when (Just key == v) $
replaceFile associatedfile $ replaceFile associatedfile $
liftIO . void . copyFileExternal contentfile liftIO . void . copyFileExternal CopyAllMetaData contentfile
updateInodeCache key associatedfile updateInodeCache key associatedfile
{- Some filesystems get new inodes each time they are mounted. {- Some filesystems get new inodes each time they are mounted.

View file

@ -357,7 +357,7 @@ toDirectGen k f = do
`catchIO` (\_ -> freezeContent loc) `catchIO` (\_ -> freezeContent loc)
fromdirect loc = do fromdirect loc = do
replaceFile f $ replaceFile f $
liftIO . void . copyFileExternal loc liftIO . void . copyFileExternal CopyAllMetaData loc
updateInodeCache k f updateInodeCache k f
{- Removes a direct mode file, while retaining its content in the annex {- Removes a direct mode file, while retaining its content in the annex

View file

@ -23,6 +23,7 @@ tests =
, TestCase "git version" getGitVersion , TestCase "git version" getGitVersion
, testCp "cp_a" "-a" , testCp "cp_a" "-a"
, testCp "cp_p" "-p" , testCp "cp_p" "-p"
, testCp "cp_preserve_timestamps" "--preserve=timestamps"
, testCp "cp_reflink_auto" "--reflink=auto" , testCp "cp_reflink_auto" "--reflink=auto"
, TestCase "xargs -0" $ requireCmd "xargs_0" "xargs -0 </dev/null" , TestCase "xargs -0" $ requireCmd "xargs_0" "xargs -0 </dev/null"
, TestCase "rsync" $ requireCmd "rsync" "rsync --version >/dev/null" , TestCase "rsync" $ requireCmd "rsync" "rsync --version >/dev/null"

View file

@ -90,7 +90,7 @@ start mode (srcfile, destfile) =
handleexisting =<< liftIO (catchMaybeIO $ getSymbolicLinkStatus destfile) handleexisting =<< liftIO (catchMaybeIO $ getSymbolicLinkStatus destfile)
liftIO $ createDirectoryIfMissing True (parentDir destfile) liftIO $ createDirectoryIfMissing True (parentDir destfile)
liftIO $ if mode == Duplicate || mode == SkipDuplicates liftIO $ if mode == Duplicate || mode == SkipDuplicates
then void $ copyFileExternal srcfile destfile then void $ copyFileExternal CopyAllMetaData srcfile destfile
else moveFile srcfile destfile else moveFile srcfile destfile
Command.Add.perform destfile Command.Add.perform destfile
handleexisting Nothing = noop handleexisting Nothing = noop

View file

@ -136,7 +136,7 @@ test st r k =
, check "retrieveKeyFile resume from end" $ do , check "retrieveKeyFile resume from end" $ do
loc <- Annex.calcRepo (gitAnnexLocation k) loc <- Annex.calcRepo (gitAnnexLocation k)
tmp <- prepTmp k tmp <- prepTmp k
void $ liftIO $ copyFileExternal loc tmp void $ liftIO $ copyFileExternal CopyAllMetaData loc tmp
lockContent k removeAnnex lockContent k removeAnnex
get get
, check "fsck downloaded object" fsck , check "fsck downloaded object" fsck

View file

@ -89,7 +89,7 @@ cleanupIndirect file key = do
) )
where where
copyfrom src = copyfrom src =
thawContent file `after` liftIO (copyFileExternal src file) thawContent file `after` liftIO (copyFileExternal CopyAllMetaData src file)
hardlinkfrom src = hardlinkfrom src =
#ifndef mingw32_HOST_OS #ifndef mingw32_HOST_OS
-- creating a hard link could fall; fall back to copying -- creating a hard link could fall; fall back to copying

View file

@ -46,7 +46,7 @@ perform dest key = do
tmpdest <- fromRepo $ gitAnnexTmpObjectLocation key tmpdest <- fromRepo $ gitAnnexTmpObjectLocation key
liftIO $ createDirectoryIfMissing True (parentDir tmpdest) liftIO $ createDirectoryIfMissing True (parentDir tmpdest)
showAction "copying" showAction "copying"
ifM (liftIO $ copyFileExternal src tmpdest) ifM (liftIO $ copyFileExternal CopyAllMetaData src tmpdest)
( do ( do
liftIO $ do liftIO $ do
removeFile dest removeFile dest

View file

@ -543,7 +543,7 @@ rsyncOrCopyFile rsyncparams src dest p =
docopy = liftIO $ bracket docopy = liftIO $ bracket
(forkIO $ watchfilesize zeroBytesProcessed) (forkIO $ watchfilesize zeroBytesProcessed)
(void . tryIO . killThread) (void . tryIO . killThread)
(const $ copyFileExternal src dest) (const $ copyFileExternal CopyTimeStamps src dest)
watchfilesize oldsz = do watchfilesize oldsz = do
threadDelay 500000 -- 0.5 seconds threadDelay 500000 -- 0.5 seconds
v <- catchMaybeIO $ v <- catchMaybeIO $

View file

@ -1,6 +1,6 @@
{- file copying {- file copying
- -
- Copyright 2010-2013 Joey Hess <joey@kitenet.net> - Copyright 2010-2014 Joey Hess <joey@kitenet.net>
- -
- License: BSD-2-clause - License: BSD-2-clause
-} -}
@ -9,16 +9,20 @@
module Utility.CopyFile ( module Utility.CopyFile (
copyFileExternal, copyFileExternal,
createLinkOrCopy createLinkOrCopy,
CopyMetaData(..)
) where ) where
import Common import Common
import qualified Build.SysConfig as SysConfig import qualified Build.SysConfig as SysConfig
data CopyMetaData = CopyTimeStamps | CopyAllMetaData
deriving (Eq)
{- The cp command is used, because I hate reinventing the wheel, {- The cp command is used, because I hate reinventing the wheel,
- and because this allows easy access to features like cp --reflink. -} - and because this allows easy access to features like cp --reflink. -}
copyFileExternal :: FilePath -> FilePath -> IO Bool copyFileExternal :: CopyMetaData -> FilePath -> FilePath -> IO Bool
copyFileExternal src dest = do copyFileExternal meta src dest = do
whenM (doesFileExist dest) $ whenM (doesFileExist dest) $
removeFile dest removeFile dest
boolSystem "cp" $ params ++ [File src, File dest] boolSystem "cp" $ params ++ [File src, File dest]
@ -26,12 +30,16 @@ copyFileExternal src dest = do
#ifndef __ANDROID__ #ifndef __ANDROID__
params = map snd $ filter fst params = map snd $ filter fst
[ (SysConfig.cp_reflink_auto, Param "--reflink=auto") [ (SysConfig.cp_reflink_auto, Param "--reflink=auto")
, (SysConfig.cp_a, Param "-a") , (allmeta && SysConfig.cp_a, Param "-a")
, (SysConfig.cp_p && not SysConfig.cp_a, Param "-p") , (allmeta && SysConfig.cp_p && not SysConfig.cp_a
, Param "-p")
, (not allmeta && SysConfig.cp_preserve_timestamps
, Param "--preserve=timestamps")
] ]
#else #else
params = [] params = []
#endif #endif
allmeta = meta == CopyAllMetaData
{- Create a hard link if the filesystem allows it, and fall back to copying {- Create a hard link if the filesystem allows it, and fall back to copying
- the file. -} - the file. -}
@ -42,7 +50,7 @@ createLinkOrCopy src dest = go `catchIO` const fallback
go = do go = do
createLink src dest createLink src dest
return True return True
fallback = copyFileExternal src dest fallback = copyFileExternal CopyAllMetaData src dest
#else #else
createLinkOrCopy = copyFileExternal createLinkOrCopy = copyFileExternal CopyAllMetaData
#endif #endif

3
debian/changelog vendored
View file

@ -8,6 +8,9 @@ git-annex (5.20140818) UNRELEASED; urgency=medium
Closes: #758630 Closes: #758630
* Fix handing of autocorrection when running outside a git repository. * Fix handing of autocorrection when running outside a git repository.
* Fix stub git-annex test support when built without tasty. * Fix stub git-annex test support when built without tasty.
* Do not preserve permissions and acls when copying files from
one local git repository to another. Timestamps are still preserved
as long as cp --preserve=timestamps is supported. Closes: #729757
-- Joey Hess <joeyh@debian.org> Tue, 19 Aug 2014 12:52:41 -0400 -- Joey Hess <joeyh@debian.org> Tue, 19 Aug 2014 12:52:41 -0400