git-annex 3.20130105 → 3.20130107
raw patch · 45 files changed
+342/−185 lines, 45 filesdep ~yesod-form
Dependency ranges changed: yesod-form
Files
- Annex/CatFile.hs +15/−2
- Annex/Content.hs +0/−1
- Annex/Direct.hs +6/−12
- Assistant.hs +2/−0
- Assistant/Environment.hs +26/−0
- Assistant/Threads/Watcher.hs +7/−6
- Backend.hs +19/−6
- CHANGELOG +11/−2
- Command/Add.hs +29/−14
- Command/AddUrl.hs +6/−1
- Command/Copy.hs +2/−3
- Command/Drop.hs +1/−1
- Command/Find.hs +1/−1
- Command/Fix.hs +1/−1
- Command/Fsck.hs +42/−20
- Command/Log.hs +1/−1
- Command/Move.hs +1/−1
- Command/PreCommit.hs +1/−1
- Command/Whereis.hs +1/−1
- Locations.hs +3/−0
- Makefile +2/−1
- Remote/Bup.hs +3/−4
- Remote/Directory.hs +2/−4
- Remote/Glacier.hs +4/−5
- Remote/Hook.hs +6/−7
- Remote/Rsync.hs +6/−6
- Remote/S3.hs +3/−5
- Remote/WebDAV.hs +5/−6
- Seek.hs +4/−0
- Utility/UserInfo.hs +5/−1
- debian/changelog +11/−2
- doc/assistant/release_notes.mdwn +4/−0
- doc/assistant/thanks.mdwn +1/−1
- doc/bugs/Disconcerting_warning_from_git-annex.mdwn +6/−0
- doc/bugs/OSX_app_issues/comment_7_acd73cc5c4caa88099e2d2f19947aadf._comment +8/−0
- doc/design/assistant/blog/day_163__free_features.mdwn +32/−0
- doc/design/assistant/blog/day_164__bugfixes.mdwn +17/−0
- doc/design/assistant/blog/day_165__release_day.mdwn +14/−0
- doc/direct_mode.mdwn +9/−25
- doc/git-annex.mdwn +5/−3
- doc/news/version_3.20121126.mdwn +0/−27
- doc/news/version_3.20130107.mdwn +13/−0
- doc/preferred_content.mdwn +0/−9
- git-annex.1 +5/−3
- git-annex.cabal +2/−2
Annex/CatFile.hs view
@@ -9,8 +9,9 @@ catFile, catObject, catObjectDetails,+ catFileHandle, catKey,- catFileHandle+ catKeyFile, ) where import qualified Data.ByteString.Lazy as L@@ -46,4 +47,16 @@ {- From the Sha or Ref of a symlink back to the key. -} catKey :: Ref -> Annex (Maybe Key)-catKey ref = fileKey . takeFileName . encodeW8 . L.unpack <$> catObject ref+catKey ref = do+ l <- encodeW8 . L.unpack <$> catObject ref+ return $ if isLinkToAnnex l+ then fileKey $ takeFileName l+ else Nothing++{- From a file in git back to the key.+ -+ - Prefixing the file with ./ makes this work even if in a subdirectory+ - of a repo. For some reason, HEAD is sometimes needed.+ -}+catKeyFile :: FilePath -> Annex (Maybe Key)+catKeyFile f = catKey $ Ref $ "HEAD:./" ++ f
Annex/Content.hs view
@@ -309,7 +309,6 @@ where goindirect = indirect =<< inRepo (gitAnnexLocation key) - cleanObjectLoc :: Key -> Annex () cleanObjectLoc key = do file <- inRepo $ gitAnnexLocation key
Annex/Direct.hs view
@@ -55,16 +55,7 @@ (Just key, Nothing, _) -> deletedannexed file key (Nothing, Nothing, _) -> deletegit file (_, Just _, _) -> addgit file- go (file, Nothing) = do- mstat <- liftIO $ catchMaybeIO $ getSymbolicLinkStatus file- case (mstat, toCache =<< mstat) of- (Nothing, _) -> noop- (Just stat, Just cache)- | isSymbolicLink stat -> addgit file- | otherwise -> void $ addDirect file cache- (Just stat, Nothing)- | isSymbolicLink stat -> addgit file- | otherwise -> noop+ go _ = noop modifiedannexed file oldkey cache = do void $ removeAssociatedFile oldkey file@@ -190,10 +181,13 @@ liftIO $ replaceFile f $ moveFile loc , return Nothing )- (loc':_) -> return $ Just $ do+ (loc':_) -> ifM (liftIO $ not . isSymbolicLink <$> getSymbolicLinkStatus f) {- Another direct file has the content, so - hard link to it. -}- liftIO $ replaceFile f $ createLink loc'+ ( return $ Just $ do+ liftIO $ replaceFile f $ createLink loc'+ , return Nothing+ ) {- Removes a direct mode file, while retaining its content. -} removeDirect :: Key -> FilePath -> Annex ()
Assistant.hs view
@@ -151,6 +151,7 @@ #else #warning Building without the webapp. You probably need to install Yesod.. #endif+import Assistant.Environment import qualified Utility.Daemon import Utility.LogFile import Utility.ThreadScheduler@@ -178,6 +179,7 @@ startAssistant :: Bool -> (IO () -> IO ()) -> Maybe (String -> FilePath -> IO ()) -> Annex () startAssistant assistant daemonize webappwaiter = withThreadState $ \st -> do checkCanWatch+ when assistant $ checkEnvironment dstatus <- startDaemonStatus liftIO $ daemonize $ flip runAssistant go =<< newAssistantData st dstatus
+ Assistant/Environment.hs view
@@ -0,0 +1,26 @@+{- git-annex assistant environment+ -+ - Copyright 2012 Joey Hess <joey@kitenet.net>+ -+ - Licensed under the GNU GPL version 3 or higher.+ -}++module Assistant.Environment where++import Assistant.Common+import Utility.UserInfo+import qualified Git.Config++import System.Posix.Env++{- Checks that the system's environment allows git to function.+ - Git requires a GECOS username, or suitable git configuration, or+ - environment variables. -}+checkEnvironment :: Annex ()+checkEnvironment = do+ username <- liftIO myUserName+ gecos <- liftIO myUserGecos+ gitusername <- fromRepo $ Git.Config.getMaybe "user.name"+ when (null gecos && (gitusername == Nothing || gitusername == Just "")) $+ -- existing environment is not overwritten+ liftIO $ setEnv "GIT_AUTHOR_NAME" username False
Assistant/Threads/Watcher.hs view
@@ -138,7 +138,7 @@ - really been modified. -} onAddDirect :: Handler onAddDirect file fs = do- v <- liftAnnex $ catKey (Ref $ ':':file)+ v <- liftAnnex $ catKeyFile file case (v, fs) of (Just key, Just filestatus) -> ifM (liftAnnex $ changedFileStatus key filestatus)@@ -158,11 +158,11 @@ where go (Just (key, _)) = do link <- liftAnnex $ calcGitLink file key- ifM ((==) link <$> liftIO (readSymbolicLink file))+ ifM ((==) (Just link) <$> liftIO (catchMaybeIO $ readSymbolicLink file)) ( do s <- getDaemonStatus checkcontent key s- ensurestaged link s+ ensurestaged (Just link) s , do liftIO $ removeFile file liftIO $ createSymbolicLink link file@@ -170,8 +170,8 @@ addlink link ) go Nothing = do -- other symlink- link <- liftIO (readSymbolicLink file)- ensurestaged link =<< getDaemonStatus+ mlink <- liftIO (catchMaybeIO $ readSymbolicLink file)+ ensurestaged mlink =<< getDaemonStatus {- This is often called on symlinks that are already - staged correctly. A symlink may have been deleted@@ -184,12 +184,13 @@ - (If the daemon has never ran before, avoid staging - links too.) -}- ensurestaged link daemonstatus+ ensurestaged (Just link) daemonstatus | scanComplete daemonstatus = addlink link | otherwise = case filestatus of Just s | not (afterLastDaemonRun (statusChangeTime s) daemonstatus) -> noChange _ -> addlink link+ ensurestaged Nothing _ = noChange {- For speed, tries to reuse the existing blob for symlink target. -} addlink link = do
Backend.hs view
@@ -20,9 +20,11 @@ import Common.Annex import qualified Annex import Annex.CheckAttr+import Annex.CatFile import Types.Key import Types.KeySource import qualified Types.Backend as B+import Config -- When adding a new backend, import it here and add it to the list. import qualified Backend.SHA@@ -73,21 +75,32 @@ | otherwise = c {- Looks up the key and backend corresponding to an annexed file,- - by examining what the file symlinks to. -}+ - by examining what the file symlinks to.+ -+ - In direct mode, there is often no symlink on disk, in which case+ - the symlink is looked up in git instead. However, a real symlink+ - on disk still takes precedence over what was committed to git in direct+ - mode.+ -} lookupFile :: FilePath -> Annex (Maybe (Key, Backend)) lookupFile file = do tl <- liftIO $ tryIO $ readSymbolicLink file case tl of- Left _ -> return Nothing- Right l -> makekey l+ Right l+ | isLinkToAnnex l -> makekey l+ | otherwise -> return Nothing+ Left _ -> ifM isDirect+ ( maybe (return Nothing) makeret =<< catKeyFile file+ , return Nothing+ ) where- makekey l = maybe (return Nothing) (makeret l) (fileKey $ takeFileName l)- makeret l k = let bname = keyBackendName k in+ makekey l = maybe (return Nothing) makeret (fileKey $ takeFileName l)+ makeret k = let bname = keyBackendName k in case maybeLookupBackendName bname of Just backend -> do return $ Just (k, backend) Nothing -> do- when (isLinkToAnnex l) $ warning $+ warning $ "skipping " ++ file ++ " (unknown backend " ++ bname ++ ")" return Nothing
CHANGELOG view
@@ -1,9 +1,18 @@-git-annex (3.20130103) UNRELEASED; urgency=low+git-annex (3.20130107) unstable; urgency=low * webapp: Add UI to stop and restart assistant. * committer: Fix a file handle leak.+ * assistant: Make expensive transfer scan work fully in direct mode.+ * More commands work in direct mode repositories: find, whereis, move, copy,+ drop, log, fsck, add, addurl.+ * sync: No longer automatically adds files in direct mode.+ * assistant: Detect when system is not configured with a user name,+ and set environment to prevent git from failing.+ * direct: Avoid hardlinking symlinks that point to the same content+ when the content is not present.+ * Fix transferring files to special remotes in direct mode. - -- Joey Hess <joeyh@debian.org> Thu, 03 Jan 2013 14:58:45 -0400+ -- Joey Hess <joeyh@debian.org> Mon, 07 Jan 2013 01:01:41 -0400 git-annex (3.20130102) unstable; urgency=low
Command/Add.hs view
@@ -21,14 +21,19 @@ import Utility.Touch import Utility.FileMode import Config+import qualified Git.HashObject+import qualified Git.UpdateIndex+import Git.Types def :: [Command]-def = [notDirect $ notBareRepo $- command "add" paramPaths seek "add files to annex"]+def = [notBareRepo $ command "add" paramPaths seek "add files to annex"] {- Add acts on both files not checked into git yet, and unlocked files. -} seek :: [CommandSeek]-seek = [withFilesNotInGit start, withFilesUnlocked start]+seek =+ [ withFilesNotInGit start+ , whenNotDirect $ withFilesUnlocked start+ ] {- The add subcommand annexes a file, generating a key for it using a - backend, and then moving it into the annex directory and setting up@@ -60,15 +65,15 @@ tmp <- fromRepo gitAnnexTmpDir createAnnexDirectory tmp liftIO $ do- (tmpfile, handle) <- openTempFile tmp (takeFileName file)- hClose handle+ (tmpfile, h) <- openTempFile tmp (takeFileName file)+ hClose h nukeFile tmpfile createLink file tmpfile return $ KeySource { keyFilename = file , contentLocation = tmpfile } {- Moves a locked down file into the annex. -- - In direct mode, leaves the file alone, and just updates bookeeping+ - In direct mode, leaves the file alone, and just updates bookkeeping - information. -} ingest :: KeySource -> Annex (Maybe Key)@@ -146,11 +151,21 @@ {- Note: Several other commands call this, and expect it to - create the symlink and add it. -} cleanup :: FilePath -> Key -> Bool -> CommandCleanup-cleanup file key hascontent = do- _ <- link file key hascontent- params <- ifM (Annex.getState Annex.force)- ( return [Param "-f"]- , return []- )- Annex.Queue.addCommand "add" (params++[Param "--"]) [file]- return True+cleanup file key hascontent = ifM (isDirect <&&> pure hascontent)+ ( do+ l <- calcGitLink file key+ sha <- inRepo $ Git.HashObject.hashObject BlobObject l+ Annex.Queue.addUpdateIndex =<<+ inRepo (Git.UpdateIndex.stageSymlink file sha)+ when hascontent $+ logStatus key InfoPresent+ return True+ , do+ _ <- link file key hascontent+ params <- ifM (Annex.getState Annex.force)+ ( return [Param "-f"]+ , return []+ )+ Annex.Queue.addCommand "add" (params++[Param "--"]) [file]+ return True+ )
Command/AddUrl.hs view
@@ -22,9 +22,10 @@ import Types.Key import Types.KeySource import Config+import Annex.Content.Direct def :: [Command]-def = [notDirect $ notBareRepo $ withOptions [fileOption, pathdepthOption] $+def = [notBareRepo $ withOptions [fileOption, pathdepthOption] $ command "addurl" (paramRepeating paramUrl) seek "add urls to annex"] fileOption :: Option@@ -79,6 +80,8 @@ case k of Nothing -> stop Just (key, _) -> do+ whenM isDirect $+ void $ addAssociatedFile key file moveAnnex key tmp setUrlPresent key url next $ Command.Add.cleanup file key True@@ -90,6 +93,8 @@ if exists then do let key = Backend.URL.fromUrl url size+ whenM isDirect $+ void $ addAssociatedFile key file setUrlPresent key url next $ Command.Add.cleanup file key False else do
Command/Copy.hs view
@@ -14,9 +14,8 @@ import Annex.Wanted def :: [Command]-def = [notDirect $ - withOptions Command.Move.options $ command "copy" paramPaths seek- "copy content of files to/from another repository"]+def = [withOptions Command.Move.options $ command "copy" paramPaths seek+ "copy content of files to/from another repository"] seek :: [CommandSeek] seek = [withField Command.Move.toOption Remote.byName $ \to ->
Command/Drop.hs view
@@ -20,7 +20,7 @@ import Annex.Wanted def :: [Command]-def = [notDirect $ withOptions [fromOption] $ command "drop" paramPaths seek+def = [withOptions [fromOption] $ command "drop" paramPaths seek "indicate content of files not currently wanted"] fromOption :: Option
Command/Find.hs view
@@ -20,7 +20,7 @@ import qualified Option def :: [Command]-def = [notDirect $ noCommit $ withOptions [formatOption, print0Option] $+def = [noCommit $ withOptions [formatOption, print0Option] $ command "find" paramPaths seek "lists available files"] formatOption :: Option
Command/Fix.hs view
@@ -23,7 +23,7 @@ start :: FilePath -> (Key, Backend) -> CommandStart start file (key, _) = do link <- calcGitLink file key- stopUnless ((/=) link <$> liftIO (readSymbolicLink file)) $ do+ stopUnless ((/=) (Just link) <$> liftIO (catchMaybeIO $ readSymbolicLink file)) $ do showStart "fix" file next $ perform file link
Command/Fsck.hs view
@@ -34,7 +34,7 @@ import System.Locale def :: [Command]-def = [notDirect $ withOptions options $ command "fsck" paramPaths seek+def = [withOptions options $ command "fsck" paramPaths seek "check for problems"] fromOption :: Option@@ -180,12 +180,18 @@ check :: [Annex Bool] -> Annex Bool check cs = all id <$> sequence cs -{- Checks that the file's symlink points correctly to the content. -}+{- Checks that the file's symlink points correctly to the content.+ -+ - In direct mode, there is only a symlink when the content is not present.+ -} fixLink :: Key -> FilePath -> Annex Bool fixLink key file = do want <- calcGitLink file key- have <- liftIO $ readSymbolicLink file- when (want /= have) $ do+ have <- liftIO $ catchMaybeIO $ readSymbolicLink file+ maybe noop (go want) have+ return True+ where+ go want have = when (want /= have) $ do {- Version 3.20120227 had a bug that could cause content - to be stored in the wrong hash directory. Clean up - after the bug by moving the content.@@ -203,23 +209,27 @@ liftIO $ removeFile file liftIO $ createSymbolicLink want file Annex.Queue.addCommand "add" [Param "--force", Param "--"] [file]- return True {- Checks that the location log reflects the current status of the key, - in this repository only. -} verifyLocationLog :: Key -> String -> Annex Bool verifyLocationLog key desc = do present <- inAnnex key+ direct <- isDirect+ u <- getUUID - -- Since we're checking that a key's file is present, throw- -- in a permission fixup here too.- when present $ do+ {- Since we're checking that a key's file is present, throw+ - in a permission fixup here too. -}+ when (present && not direct) $ do file <- inRepo $ gitAnnexLocation key freezeContent file freezeContentDir file - u <- getUUID- verifyLocationLog' key desc present u (logChange key u)+ {- In direct mode, modified files will show up as not present,+ - but that is expected and not something to do anything about. -}+ if (direct && not present)+ then return True+ else verifyLocationLog' key desc present u (logChange key u) verifyLocationLogRemote :: Key -> String -> Remote -> Bool -> Annex Bool verifyLocationLogRemote key desc remote present =@@ -248,14 +258,20 @@ bad s {- The size of the data for a key is checked against the size encoded in- - the key's metadata, if available. -}+ - the key's metadata, if available.+ -+ - Not checked in direct mode, because files can be changed directly.+ -} checkKeySize :: Key -> Annex Bool-checkKeySize key = do- file <- inRepo $ gitAnnexLocation key- ifM (liftIO $ doesFileExist file)- ( checkKeySizeOr badContent key file- , return True- )+checkKeySize key = ifM isDirect+ ( return True+ , do+ file <- inRepo $ gitAnnexLocation key+ ifM (liftIO $ doesFileExist file)+ ( checkKeySizeOr badContent key file+ , return True+ )+ ) checkKeySizeRemote :: Key -> Remote -> Maybe FilePath -> Annex Bool checkKeySizeRemote _ _ Nothing = return True@@ -283,10 +299,16 @@ , msg ] +{- Runs the backend specific check on a key's content.+ -+ - In direct mode, this is skipped, because files can change at any time. -} checkBackend :: Backend -> Key -> Annex Bool-checkBackend backend key = do- file <- inRepo (gitAnnexLocation key)- checkBackendOr badContent backend key file+checkBackend backend key = ifM isDirect+ ( return True+ , do+ file <- inRepo $ gitAnnexLocation key+ checkBackendOr badContent backend key file+ ) checkBackendRemote :: Backend -> Key -> Remote -> Maybe FilePath -> Annex Bool checkBackendRemote backend key remote = maybe (return True) go
Command/Log.hs view
@@ -36,7 +36,7 @@ type Outputter = Bool -> POSIXTime -> [UUID] -> Annex () def :: [Command]-def = [notDirect $ withOptions options $+def = [withOptions options $ command "log" paramPaths seek "shows location log"] options :: [Option]
Command/Move.hs view
@@ -19,7 +19,7 @@ import Logs.Transfer def :: [Command]-def = [notDirect $ withOptions options $ command "move" paramPaths seek+def = [withOptions options $ command "move" paramPaths seek "move content of files to/from another repository"] fromOption :: Option
Command/PreCommit.hs view
@@ -19,7 +19,7 @@ - And, it needs to inject unlocked files into the annex. -} seek :: [CommandSeek] seek =- [ withFilesToBeCommitted $ whenAnnexed Command.Fix.start+ [ whenNotDirect $ withFilesToBeCommitted $ whenAnnexed $ Command.Fix.start , withFilesUnlockedToBeCommitted start] start :: FilePath -> CommandStart
Command/Whereis.hs view
@@ -15,7 +15,7 @@ import Logs.Trust def :: [Command]-def = [notDirect $ noCommit $ command "whereis" paramPaths seek+def = [noCommit $ command "whereis" paramPaths seek "lists repositories that have file content"] seek :: [CommandSeek]
Locations.hs view
@@ -93,6 +93,9 @@ - - When the file is not present, returns the location where the file should - be stored.+ -+ - This does not take direct mode into account, so in direct mode it is not+ - the actual location of the file's content. -} gitAnnexLocation :: Key -> Git.Repo -> IO FilePath gitAnnexLocation key r
Makefile view
@@ -135,7 +135,8 @@ --underlaydir=/dev/null --disable-plugin=shortcut \ --disable-plugin=smiley \ --plugin=comments --set comments_pagespec="*" \- --exclude='news/.*'+ --exclude='news/.*' --exclude='design/assistant/blog/*' \+ --exclude='bugs/*' --exclude='todo/*' --exclude='forum/*' clean: rm -rf $(GIT_ANNEX_TMP_BUILD_DIR) $(bins) $(mans) test configure *.tix .hpc $(sources) \
Remote/Bup.hs view
@@ -27,6 +27,7 @@ import Data.ByteString.Lazy.UTF8 (fromString) import Data.Digest.Pure.SHA import Utility.UserInfo+import Annex.Content type BupRepo = String @@ -120,14 +121,12 @@ (os ++ [Param "-n", Param (bupRef k)] ++ src) store :: Remote -> BupRepo -> Key -> AssociatedFile -> MeterUpdate -> Annex Bool-store r buprepo k _f _p = do- src <- inRepo $ gitAnnexLocation k+store r buprepo k _f _p = sendAnnex k $ \src -> do params <- bupSplitParams r buprepo k [File src] liftIO $ boolSystem "bup" params storeEncrypted :: Remote -> BupRepo -> (Cipher, Key) -> Key -> MeterUpdate -> Annex Bool-storeEncrypted r buprepo (cipher, enck) k _p = do- src <- inRepo $ gitAnnexLocation k+storeEncrypted r buprepo (cipher, enck) k _p = sendAnnex k $ \src -> do params <- bupSplitParams r buprepo enck [] liftIO $ catchBoolIO $ encrypt cipher (feedFile src) $ \h ->
Remote/Directory.hs view
@@ -111,8 +111,7 @@ withStoredFiles = withCheckedFiles doesFileExist store :: FilePath -> ChunkSize -> Key -> AssociatedFile -> MeterUpdate -> Annex Bool-store d chunksize k _f p = do- src <- inRepo $ gitAnnexLocation k+store d chunksize k _f p = sendAnnex k $ \src -> metered (Just p) k $ \meterupdate -> storeHelper d chunksize k $ \dests -> case chunksize of@@ -126,8 +125,7 @@ =<< L.readFile src storeEncrypted :: FilePath -> ChunkSize -> (Cipher, Key) -> Key -> MeterUpdate -> Annex Bool-storeEncrypted d chunksize (cipher, enck) k p = do- src <- inRepo $ gitAnnexLocation k+storeEncrypted d chunksize (cipher, enck) k p = sendAnnex k $ \src -> metered (Just p) k $ \meterupdate -> storeHelper d chunksize enck $ \dests -> encrypt cipher (feedFile src) $ readBytes $ \b ->
Remote/Glacier.hs view
@@ -23,6 +23,7 @@ import Creds import Meters import qualified Annex+import Annex.Content import System.Process @@ -84,17 +85,15 @@ | keySize k == Just 0 = do warning "Cannot store empty files in Glacier." return False- | otherwise = do- src <- inRepo $ gitAnnexLocation k+ | otherwise = sendAnnex k $ \src -> metered (Just m) k $ \meterupdate -> storeHelper r k $ streamMeteredFile src meterupdate storeEncrypted :: Remote -> (Cipher, Key) -> Key -> MeterUpdate -> Annex Bool-storeEncrypted r (cipher, enck) k m = do- f <- inRepo $ gitAnnexLocation k+storeEncrypted r (cipher, enck) k m = sendAnnex k $ \src -> do metered (Just m) k $ \meterupdate -> storeHelper r enck $ \h ->- encrypt cipher (feedFile f)+ encrypt cipher (feedFile src) (readBytes $ meteredWrite meterupdate h) retrieve :: Remote -> Key -> AssociatedFile -> FilePath -> Annex Bool
Remote/Hook.hs view
@@ -103,16 +103,15 @@ ) store :: String -> Key -> AssociatedFile -> MeterUpdate -> Annex Bool-store h k _f _p = do- src <- inRepo $ gitAnnexLocation k+store h k _f _p = sendAnnex k $ \src -> runHook h "store" k (Just src) $ return True storeEncrypted :: String -> (Cipher, Key) -> Key -> MeterUpdate -> Annex Bool-storeEncrypted h (cipher, enck) k _p = withTmp enck $ \tmp -> do- src <- inRepo $ gitAnnexLocation k- liftIO $ encrypt cipher (feedFile src) $- readBytes $ L.writeFile tmp- runHook h "store" enck (Just tmp) $ return True+storeEncrypted h (cipher, enck) k _p = withTmp enck $ \tmp ->+ sendAnnex k $ \src -> do+ liftIO $ encrypt cipher (feedFile src) $+ readBytes $ L.writeFile tmp+ runHook h "store" enck (Just tmp) $ return True retrieve :: String -> Key -> AssociatedFile -> FilePath -> Annex Bool retrieve h k _f d = runHook h "retrieve" k (Just d) $ return True
Remote/Rsync.hs view
@@ -101,14 +101,14 @@ f = keyFile k store :: RsyncOpts -> Key -> AssociatedFile -> MeterUpdate -> Annex Bool-store o k _f p = rsyncSend o p k <=< inRepo $ gitAnnexLocation k+store o k _f p = sendAnnex k $ rsyncSend o p k storeEncrypted :: RsyncOpts -> (Cipher, Key) -> Key -> MeterUpdate -> Annex Bool-storeEncrypted o (cipher, enck) k p = withTmp enck $ \tmp -> do- src <- inRepo $ gitAnnexLocation k- liftIO $ encrypt cipher (feedFile src) $- readBytes $ L.writeFile tmp- rsyncSend o p enck tmp+storeEncrypted o (cipher, enck) k p = withTmp enck $ \tmp ->+ sendAnnex k $ \src -> do+ liftIO $ encrypt cipher (feedFile src) $+ readBytes $ L.writeFile tmp+ rsyncSend o p enck tmp retrieve :: RsyncOpts -> Key -> AssociatedFile -> FilePath -> Annex Bool retrieve o k _ f = untilTrue (rsyncUrls o k) $ \u -> rsyncRemote o Nothing
Remote/S3.hs view
@@ -112,8 +112,7 @@ M.delete "bucket" defaults store :: Remote -> Key -> AssociatedFile -> MeterUpdate -> Annex Bool-store r k _f p = s3Action r False $ \(conn, bucket) -> do- src <- inRepo $ gitAnnexLocation k+store r k _f p = s3Action r False $ \(conn, bucket) -> sendAnnex k $ \src -> do res <- storeHelper (conn, bucket) r k p src s3Bool res @@ -121,9 +120,8 @@ storeEncrypted r (cipher, enck) k p = s3Action r False $ \(conn, bucket) -> -- To get file size of the encrypted content, have to use a temp file. -- (An alternative would be chunking to to a constant size.)- withTmp enck $ \tmp -> do- f <- inRepo $ gitAnnexLocation k- liftIO $ encrypt cipher (feedFile f) $+ withTmp enck $ \tmp -> sendAnnex k $ \src -> do+ liftIO $ encrypt cipher (feedFile src) $ readBytes $ L.writeFile tmp res <- storeHelper (conn, bucket) r enck p tmp s3Bool res
Remote/WebDAV.hs view
@@ -30,6 +30,7 @@ import Crypto import Creds import Meters+import Annex.Content type DavUrl = String type DavUser = B8.ByteString@@ -82,16 +83,14 @@ store :: Remote -> Key -> AssociatedFile -> MeterUpdate -> Annex Bool store r k _f p = metered (Just p) k $ \meterupdate ->- davAction r False $ \(baseurl, user, pass) -> do- f <- inRepo $ gitAnnexLocation k- liftIO $ withMeteredFile f meterupdate $+ davAction r False $ \(baseurl, user, pass) -> sendAnnex k $ \src ->+ liftIO $ withMeteredFile src meterupdate $ storeHelper r k baseurl user pass storeEncrypted :: Remote -> (Cipher, Key) -> Key -> MeterUpdate -> Annex Bool storeEncrypted r (cipher, enck) k p = metered (Just p) k $ \meterupdate ->- davAction r False $ \(baseurl, user, pass) -> do- f <- inRepo $ gitAnnexLocation k- liftIO $ encrypt cipher (streamMeteredFile f meterupdate) $+ davAction r False $ \(baseurl, user, pass) -> sendAnnex k $ \src ->+ liftIO $ encrypt cipher (streamMeteredFile src meterupdate) $ readBytes $ storeHelper r enck baseurl user pass storeHelper :: Remote -> Key -> DavUrl -> DavUser -> DavPass -> L.ByteString -> IO Bool
Seek.hs view
@@ -20,6 +20,7 @@ import qualified Git.LsFiles as LsFiles import qualified Limit import qualified Option+import Config seekHelper :: ([FilePath] -> Git.Repo -> IO ([FilePath], IO Bool)) -> [FilePath] -> Annex [FilePath] seekHelper a params = do@@ -123,3 +124,6 @@ notSymlink :: FilePath -> IO Bool notSymlink f = liftIO $ not . isSymbolicLink <$> getSymbolicLinkStatus f++whenNotDirect :: CommandSeek -> CommandSeek+whenNotDirect a params = ifM isDirect ( return [] , a params )
Utility/UserInfo.hs view
@@ -7,7 +7,8 @@ module Utility.UserInfo ( myHomeDir,- myUserName+ myUserName,+ myUserGecos, ) where import Control.Applicative@@ -23,6 +24,9 @@ {- Current user's user name. -} myUserName :: IO String myUserName = myVal ["USER", "LOGNAME"] userName++myUserGecos :: IO String+myUserGecos = myVal [] userGecos myVal :: [String] -> (UserEntry -> String) -> IO String myVal envvars extract = maybe (extract <$> getpwent) return =<< check envvars
debian/changelog view
@@ -1,9 +1,18 @@-git-annex (3.20130103) UNRELEASED; urgency=low+git-annex (3.20130107) unstable; urgency=low * webapp: Add UI to stop and restart assistant. * committer: Fix a file handle leak.+ * assistant: Make expensive transfer scan work fully in direct mode.+ * More commands work in direct mode repositories: find, whereis, move, copy,+ drop, log, fsck, add, addurl.+ * sync: No longer automatically adds files in direct mode.+ * assistant: Detect when system is not configured with a user name,+ and set environment to prevent git from failing.+ * direct: Avoid hardlinking symlinks that point to the same content+ when the content is not present.+ * Fix transferring files to special remotes in direct mode. - -- Joey Hess <joeyh@debian.org> Thu, 03 Jan 2013 14:58:45 -0400+ -- Joey Hess <joeyh@debian.org> Mon, 07 Jan 2013 01:01:41 -0400 git-annex (3.20130102) unstable; urgency=low
doc/assistant/release_notes.mdwn view
@@ -1,3 +1,7 @@+## version 3.20130107++This is a bugfix release.+ ## version 3.20130102 This release makes several significant improvements to the git-annex
doc/assistant/thanks.mdwn view
@@ -47,7 +47,7 @@ Mesar Hameed, Brandur K. Holm Petersen, Takahiro Inoue, Kai Hendry, Stephen Youndt, Lee Roberson, Ben Strawbridge, Andrew Greenberg, Alfred Adams Andrew, Aaron De Vries, Monti Knazze, Jorge Canseco, Hamish, Mark Eichin,-Sherif Abouseda, Ben Strawbridge+Sherif Abouseda, Ben Strawbridge, chee rabbits, Pedro Côrte-Real And special thanks to Kevin McKenzie, who also gave me a login to a Mac OSX machine, which has proven invaluable, and Jimmy Tang who has helped
+ doc/bugs/Disconcerting_warning_from_git-annex.mdwn view
@@ -0,0 +1,6 @@+I did a "git annex add" of a bunch of files on a storage server with low IOPS, and saw this:++ git-annex: /tank/Media/Pictures/.git/annex/tmp/430_32b_SHA256E-s4464838--c1785a76ee1451f602e93c99c147e214705004e541de8256d74a3be3717d15e5.jpg.log: openBinaryFile: resource busy (file is locked)+failed++How is that even possible, when the server is doing nothing else?
+ doc/bugs/OSX_app_issues/comment_7_acd73cc5c4caa88099e2d2f19947aadf._comment view
@@ -0,0 +1,8 @@+[[!comment format=mdwn+ username="http://joeyh.name/"+ ip="4.152.108.211"+ subject="comment 7"+ date="2013-01-05T17:48:52Z"+ content="""+@jsilence, this problem does not involve lsof. There was a typo in the cabal file that prevented cabal building it with hfsevents. I'm releasing a new version to cabal with this typo fixed.+"""]]
+ doc/design/assistant/blog/day_163__free_features.mdwn view
@@ -0,0 +1,32 @@+There was a typo in cabal file that broke building the assistant on OSX.+This didn't affect the autobuilds of the app, but several users building by+hand reported problems. I made a new minor release fixing that typo, and+also a resouce leak bug.++Got a restart UI working after all. It's a hack though. It+opens a new tab for the new assistant instance, and as most web browsers+don't allow javascript to close tabs, the old tab is left open. At some+point I need to add a proper thread manager to the assistant, which the+restart code could use to kill the watcher and committer threads, and then+I could do a clean restart, bringing up the new daemon and redirecting the+browser to it.++Found a bug in the assistant in direct mode -- the expensive transfer scan+didn't queue uploads needed to sync to other repos in direct mode, although+it did queue downloads. Fixing this laid some very useful groundwork for+making more commands support direct mode, too. Got stuck for a long time+dealing with some very strange `git-cat-file` behavior while making this+work. Ended up putting in a workaround.++After that, I found that these commands work in direct mode, without+needing any futher changes!++* `git annex find`+* `git annex whereis`+* `git annex copy`+* `git annex move`+* `git annex drop`+* `git annex log`++Enjoy! The only commands I'd like to add to this are `fsck`, `add`,+and `addurl`...
+ doc/design/assistant/blog/day_164__bugfixes.mdwn view
@@ -0,0 +1,17 @@+Several bugfixes from user feedback today.++Made the assistant detect misconfigured systems where git will fail to+commit because it cannot determine the user's name or email address, and+dummy up enough info to get git working. It makes sense for git and+git-annex to fail at the command line on such a misconfigured system, so+the user can fix it, but for the assistant it makes sense to plow on and just+work.++I found a big gap in direct mode -- all the special remotes expected to find+content in the indirect mode location when transferring to the remote. It+was easy to fix once I noticed the problem. This is a big enough bug that+I will be making a new release in a day or so.++Also, got fsck working in direct mode. It doesn't check as many things+as in indirect mode, because direct mode files can be modified at any time.+Still, it's usable, and useful.
+ doc/design/assistant/blog/day_165__release_day.mdwn view
@@ -0,0 +1,14 @@+Got `git annex add` (and `addurl`) working in direct mode. This allowed me+to make `git annex sync` in direct mode no longer automatically add new+files.++It's also now safe to mix direct mode annexed files with regular files in+git, in the same repository. Might have been safe all along, but I've+tested it, and it certianly works now. You just have to be careful to not+use `git commit -a` to commit changes to such files, since that'll also +stage the entire content of direct mode files.++Made a minor release for these recent changes and bugfixes. Recommended if+you're using direct mode. Had to chase down a stupid typo I made yesterday+that caused fsck to infinite loop if it found a corrupted file. Thank+goodness for test suites.
doc/direct_mode.mdwn view
@@ -34,35 +34,19 @@ ## use a direct mode repository -Perhaps the best way to use a direct mode repository is with the git-annex-assistant.--Otherwise, the main command that's used in direct mode repositories is-`git annex sync`. This automatically adds new files, commits all-changed files to git, pushes them out, pulls down any changes, etc.--You can also run `git annex get` to transfer the content of files into your-direct mode repository. Or if the direct mode repository is a remote of-some other, regular git-annex repository, you can use commands in the other-repository like `git annex copy` and `git annex move` to transfer the-contents of files to the direct mode repository.+You can use most git-annex commands as usual in a direct mode repository.+A few commands don't work in direct mode, and will refuse to do anything. -You can use `git commit --staged`. (But not `git commit -a` .. It'll commit-whole large files into git!)+Direct mode also works well with the git-annex assistant. -You can use `git log` and other git query commands.+You can use `git commit --staged`. But not `git commit -a` .. It'll+commit whole large files into git! ## what doesn't work in direct mode -In general git-annex commands will only work in direct mode repositories on-files whose content is not present. That's because such files are still -represented as symlinks, which git-annex commands know how to operate on.-So, `git annex get` works, but `git annex drop` and `git annex move` don't,-and things like `git annex status` show incomplete information.--It's technically possible to make all git-annex commands work in direct-mode repositories, so this might change. Check back to this page to see-current status about what works and what doesn't.+`git annex status` show incomplete information. A few other commands,+like `git annex unlock` don't make sense in direct mode and will refuse to+run. As for git commands, you can probably use some git working tree manipulation commands, like `git checkout` and `git revert` in useful@@ -72,4 +56,4 @@ This is one reason it's wise to make git-annex untrust your direct mode repositories. Still, you can lose data using these sort of git commands, so-use extreme caution. +use extreme caution.
doc/git-annex.mdwn view
@@ -269,11 +269,13 @@ * direct Switches a repository to use direct mode, where rather than symlinks to- files, the files are directly present in the repository. Note that many git- and git-annex commands will not work in direct mode; you're mostly- limited to using "git annex sync" and "git annex get".+ files, the files are directly present in the repository. As part of the switch to direct mode, any changed files will be committed.++ Note that git commands that operate on the work tree are often unsafe to+ use in direct mode repositories, and can result in data loss or other+ bad behavior. * indirect
− doc/news/version_3.20121126.mdwn
@@ -1,27 +0,0 @@-git-annex 3.20121126 released with [[!toggle text="these changes"]]-[[!toggleable text="""- * New webdav and Amazon glacier special remotes.- * Display a warning when a non-existing file or directory is specified.- * webapp: Added configurator for Box.com.- * webapp: Show error messages to user when testing XMPP creds.- * Fix build of assistant without yesod.- * webapp: The list of repositiories refreshes when new repositories are- added, including when new repository configurations are pushed in from- remotes.- * OSX: Fix RunAtLoad value in plist file.- * Getting a file from chunked directory special remotes no longer buffers- it all in memory.- * S3: Added progress display for uploading and downloading.- * directory special remote: Made more efficient and robust.- * Bugfix: directory special remote could loop forever storing a key- when a too small chunksize was configured.- * Allow controlling whether login credentials for S3 and webdav are- committed to the repository, by setting embedcreds=yes|no when running- initremote.- * Added smallarchive repository group, that only archives files that are- in archive directories. Used by default for glacier when set up in the- webapp.- * assistant: Fixed handling of toplevel archive directory and- client repository group.- * assistant: Apply preferred content settings when a new symlink- is created, or a symlink gets renamed. Made archive directories work."""]]
+ doc/news/version_3.20130107.mdwn view
@@ -0,0 +1,13 @@+git-annex 3.20130107 released with [[!toggle text="these changes"]]+[[!toggleable text="""+ * webapp: Add UI to stop and restart assistant.+ * committer: Fix a file handle leak.+ * assistant: Make expensive transfer scan work fully in direct mode.+ * More commands work in direct mode repositories: find, whereis, move, copy,+ drop, log, fsck, add, addurl.+ * sync: No longer automatically adds files in direct mode.+ * assistant: Detect when system is not configured with a user name,+ and set environment to prevent git from failing.+ * direct: Avoid hardlinking symlinks that point to the same content+ when the content is not present.+ * Fix transferring files to special remotes in direct mode."""]]
doc/preferred_content.mdwn view
@@ -58,15 +58,6 @@ the repo it's being dropped from. This is different than running `git annex drop --copies=2`, which will drop files that current have 2 copies. -A wrinkle of this approach is how `in=` is handled. When deciding if-content should be dropped, git-annex looks at the current status, not-the status if the content would be dropped. So `in=here` means that-any currently present content is preferred, which can be useful if you-want manual control over content. Meanwhile `not (in=here)` should be-avoided -- it will cause content that's not here to be preferred,-but once the content arrives, it'll stop being preferred and will be-dropped again!- ## difference: "present" There's a special "present" keyword you can use in a preferred content
git-annex.1 view
@@ -240,11 +240,13 @@ .IP .IP "direct" Switches a repository to use direct mode, where rather than symlinks to-files, the files are directly present in the repository. Note that many git-and git\-annex commands will not work in direct mode; you're mostly-limited to using "git annex sync" and "git annex get".+files, the files are directly present in the repository. .IP As part of the switch to direct mode, any changed files will be committed.+.IP+Note that git commands that operate on the work tree are often unsafe to+use in direct mode repositories, and can result in data loss or other+bad behavior. .IP .IP "indirect" Switches a repository back from direct mode to the default, indirect mode.
git-annex.cabal view
@@ -1,5 +1,5 @@ Name: git-annex-Version: 3.20130105+Version: 3.20130107 Cabal-Version: >= 1.8 License: GPL Maintainer: Joey Hess <joey@kitenet.net>@@ -99,7 +99,7 @@ if flag(Webapp) && flag(Assistant) Build-Depends: yesod, yesod-static, case-insensitive, http-types, transformers, wai, wai-logger, warp, blaze-builder,- crypto-api, hamlet, clientsession, aeson, yesod-form,+ crypto-api, hamlet, clientsession, aeson, yesod-form (>= 1.2.0), template-haskell, yesod-default (>= 1.1.0), data-default CPP-Options: -DWITH_WEBAPP