packages feed

git-annex 3.20130207 → 3.20130216.1

raw patch · 137 files changed

+1550/−1163 lines, 137 filesdep +Globdep +randomdep +uuiddep −HTTPdep −pcre-lightdep ~basebinary-added

Dependencies added: Glob, random, uuid

Dependencies removed: HTTP, pcre-light

Dependency ranges changed: base

Files

+ .git-annex.cabal.swp view

binary file changed (absent → 20480 bytes)

Annex.hs view
@@ -108,7 +108,6 @@ 	, uuidmap :: Maybe UUIDMap 	, preferredcontentmap :: Maybe PreferredContentMap 	, shared :: Maybe SharedRepository-	, direct :: Maybe Bool 	, forcetrust :: TrustMap 	, trustmap :: Maybe TrustMap 	, groupmap :: Maybe GroupMap@@ -138,7 +137,6 @@ 	, uuidmap = Nothing 	, preferredcontentmap = Nothing 	, shared = Nothing-	, direct = Nothing 	, forcetrust = M.empty 	, trustmap = Nothing 	, groupmap = Nothing
Annex/Content.hs view
@@ -50,6 +50,7 @@ import Git.SharedRepository import Annex.Perms import Annex.Content.Direct+import Backend  {- Checks if a given key's content is currently present. -} inAnnex :: Key -> Annex Bool@@ -80,7 +81,7 @@ {- A safer check; the key's content must not only be present, but  - is not in the process of being removed. -} inAnnexSafe :: Key -> Annex (Maybe Bool)-inAnnexSafe = inAnnex' (maybe False id) (Just False) go+inAnnexSafe = inAnnex' (fromMaybe False) (Just False) go   where 	go f = liftIO $ openforlock f >>= check 	openforlock f = catchMaybeIO $@@ -239,42 +240,35 @@ moveAnnex :: Key -> FilePath -> Annex () moveAnnex key src = withObjectLoc key storeobject storedirect   where-	storeobject dest = do-		ifM (liftIO $ doesFileExist dest)-			( liftIO $ removeFile src-			, do-				createContentDir dest-				liftIO $ moveFile src dest-				freezeContent dest-				freezeContentDir dest-			)-	storedirect fs = storedirect' =<< liftIO (filterM validsymlink fs)--	validsymlink f = do-		tl <- tryIO $ readSymbolicLink f-		return $ case tl of-			Right l-				| isLinkToAnnex l ->-					Just key == fileKey (takeFileName l)-			_ -> False+	storeobject dest = ifM (liftIO $ doesFileExist dest)+		( liftIO $ removeFile src+		, do+			createContentDir dest+			liftIO $ moveFile src dest+			freezeContent dest+			freezeContentDir dest+		)+	storedirect fs = storedirect' =<< filterM validsymlink fs+	validsymlink f = (==) (Just key) <$> isAnnexLink f  	storedirect' [] = storeobject =<< inRepo (gitAnnexLocation key) 	storedirect' (dest:fs) = do-		updateCache key src+		updateInodeCache key src 		thawContent src-		liftIO $ replaceFile dest $ moveFile src-		liftIO $ forM_ fs $ \f -> replaceFile f $-			void . copyFileExternal dest+		replaceFile dest $ liftIO . moveFile src+		forM_ fs $ \f -> replaceFile f $+			void . liftIO . copyFileExternal dest  {- Replaces any existing file with a new version, by running an action.  - First, makes sure the file is deleted. Or, if it didn't already exist,  - makes sure the parent directory exists. -}-replaceFile :: FilePath -> (FilePath -> IO ()) -> IO ()+replaceFile :: FilePath -> (FilePath -> Annex ()) -> Annex () replaceFile file a = do-	r <- tryIO $ removeFile file-	case r of-		Left _ -> createDirectoryIfMissing True (parentDir file)-		_ -> noop+	liftIO $ do+		r <- tryIO $ removeFile file+		case r of+			Left _ -> createDirectoryIfMissing True $ parentDir file+			_ -> noop 	a file  {- Runs an action to transfer an object's content.@@ -283,7 +277,7 @@  - If this happens, runs the rollback action and returns False. The  - rollback action should remove the data that was transferred.  -}-sendAnnex :: Key -> (Annex ()) -> (FilePath -> Annex Bool) -> Annex Bool+sendAnnex :: Key -> Annex () -> (FilePath -> Annex Bool) -> Annex Bool sendAnnex key rollback sendobject = go =<< prepSendAnnex key   where 	go Nothing = return False@@ -308,10 +302,10 @@ 	indirect f = return $ Just (f, return True) 	direct [] = return Nothing 	direct (f:fs) = do-		cache <- recordedCache key+		cache <- recordedInodeCache key 		-- check that we have a good file-		ifM (compareCache f cache)-			( return $ Just (f, compareCache f cache)+		ifM (liftIO $ compareInodeCache f cache)+			( return $ Just (f, liftIO $ compareInodeCache f cache) 			, direct fs 			) @@ -335,12 +329,9 @@ cleanObjectLoc :: Key -> Annex () cleanObjectLoc key = do 	file <- inRepo $ gitAnnexLocation key-	liftIO $ do-		let dir = parentDir file-		void $ catchMaybeIO $ do-			allowWrite dir-			removeDirectoryRecursive dir-		removeparents dir (2 :: Int)+	unlessM crippledFileSystem $+		void $ liftIO $ catchMaybeIO $ allowWrite $ parentDir file+	liftIO $ removeparents file (3 :: Int)   where 	removeparents _ 0 = noop 	removeparents file n = do@@ -356,28 +347,30 @@ removeAnnex key = withObjectLoc key remove removedirect   where 	remove file = do-		liftIO $ do-			allowWrite $ parentDir file-			removeFile file+		unlessM crippledFileSystem $+			liftIO $ allowWrite $ parentDir file+		liftIO $ nukeFile file+		removeInodeCache key 		cleanObjectLoc key 	removedirect fs = do-		cache <- recordedCache key+		cache <- recordedInodeCache key+		removeInodeCache key 		mapM_ (resetfile cache) fs-		cleanObjectLoc key-	resetfile cache f = whenM (compareCache f cache) $ do+	resetfile cache f = whenM (liftIO $ compareInodeCache f cache) $ do 		l <- calcGitLink f key 		top <- fromRepo Git.repoPath 		cwd <- liftIO getCurrentDirectory 		let top' = fromMaybe top $ absNormPath cwd top 		let l' = relPathDirToFile top' (fromMaybe l $ absNormPath top' l)-		liftIO $ replaceFile f $ const $-			createSymbolicLink l' f+		replaceFile f $ const $+			makeAnnexLink l' f  {- Moves a key's file out of .git/annex/objects/ -} fromAnnex :: Key -> FilePath -> Annex () fromAnnex key dest = do 	file <- inRepo $ gitAnnexLocation key-	liftIO $ allowWrite $ parentDir file+	unlessM crippledFileSystem $+		liftIO $ allowWrite $ parentDir file 	thawContent file 	liftIO $ moveFile file dest 	cleanObjectLoc key@@ -390,23 +383,29 @@ 	bad <- fromRepo gitAnnexBadDir 	let dest = bad </> takeFileName src 	createAnnexDirectory (parentDir dest)-	liftIO $ do-		allowWrite (parentDir src)-		moveFile src dest+	unlessM crippledFileSystem $+		liftIO $ allowWrite (parentDir src)+	liftIO $ moveFile src dest 	cleanObjectLoc key 	logStatus key InfoMissing 	return dest -{- List of keys whose content exists in .git/annex/objects/ -}+{- List of keys whose content exists in the annex. -} getKeysPresent :: Annex [Key]-getKeysPresent = liftIO . traverse (2 :: Int) =<< fromRepo gitAnnexObjectDir+getKeysPresent = do+	direct <- isDirect+	dir <- fromRepo gitAnnexObjectDir+	liftIO $ traverse direct (2 :: Int) dir   where-	traverse depth dir = do+	traverse direct depth dir = do 		contents <- catchDefaultIO [] (dirContents dir) 		if depth == 0-			then continue (mapMaybe (fileKey . takeFileName) contents) []+			then do+				contents' <- filterM (present direct) contents+				let keys = mapMaybe (fileKey . takeFileName) contents'+				continue keys [] 			else do-				let deeper = traverse (depth - 1)+				let deeper = traverse direct (depth - 1) 				continue [] (map deeper contents) 	continue keys [] = return keys 	continue keys (a:as) = do@@ -414,6 +413,13 @@ 		morekeys <- unsafeInterleaveIO a 		continue (morekeys++keys) as +	{- In indirect mode, look for the key. In direct mode,+	 - the inode cache file is only present when a key's content+	 - is present. -}+	present False d = doesFileExist $ contentfile d+	present True d = doesFileExist $ contentfile d ++ ".cache"+	contentfile d = d </> takeFileName d+ {- Things to do to record changes to content when shutting down.  -  - It's acceptable to avoid committing changes to the branch,@@ -444,17 +450,18 @@ 		when ok $ thawContent file 		return ok 	copy = ifM (liftIO $ doesFileExist file)-			( return True-			, do-				s <- inRepo $ gitAnnexLocation key-				liftIO $ copyFileExternal s file-			)+		( return True+		, do+			s <- inRepo $ gitAnnexLocation key+			liftIO $ copyFileExternal s file+		)  {- Blocks writing to an annexed file. The file is made unwritable  - to avoid accidental edits. core.sharedRepository may change  - who can read it. -} freezeContent :: FilePath -> Annex ()-freezeContent file = liftIO . go =<< fromRepo getSharedRepository+freezeContent file = unlessM crippledFileSystem $+	liftIO . go =<< fromRepo getSharedRepository   where 	go GroupShared = modifyFileMode file $ 		removeModes writeModes .@@ -467,7 +474,8 @@ {- Allows writing to an annexed file that freezeContent was called on  - before. -} thawContent :: FilePath -> Annex ()-thawContent file = liftIO . go =<< fromRepo getSharedRepository+thawContent file = unlessM crippledFileSystem $+	liftIO . go =<< fromRepo getSharedRepository   where 	go GroupShared = groupWriteRead file 	go AllShared = groupWriteRead file
Annex/Content/Direct.hs view
@@ -11,14 +11,12 @@ 	addAssociatedFile, 	goodContent, 	changedFileStatus,-	updateCache,-	recordedCache,-	compareCache,-	writeCache,-	genCache,-	toCache,-	Cache(..),-	prop_read_show_direct+	recordedInodeCache,+	updateInodeCache,+	writeInodeCache,+	compareInodeCache,+	removeInodeCache,+	toInodeCache, ) where  import Common.Annex@@ -26,8 +24,7 @@ import qualified Git import Utility.TempFile import Logs.Location--import System.Posix.Types+import Utility.InodeCache  {- Absolute FilePaths of Files in the tree that are associated with a key. -} associatedFiles :: Key -> Annex [FilePath]@@ -78,7 +75,7 @@ addAssociatedFile :: Key -> FilePath -> Annex [FilePath] addAssociatedFile key file = do 	file' <- normaliseAssociatedFile file-	changeAssociatedFiles key $ \files -> do+	changeAssociatedFiles key $ \files -> 		if file' `elem` files 			then files 			else file':files@@ -98,70 +95,36 @@  -} goodContent :: Key -> FilePath -> Annex Bool goodContent key file = do-	old <- recordedCache key-	compareCache file old+	old <- recordedInodeCache key+	liftIO $ compareInodeCache file old  changedFileStatus :: Key -> FileStatus -> Annex Bool changedFileStatus key status = do-	old <- recordedCache key-	let curr = toCache status+	old <- recordedInodeCache key+	let curr = toInodeCache status 	return $ curr /= old -{- Gets the recorded cache for a key. -}-recordedCache :: Key -> Annex (Maybe Cache)-recordedCache key = withCacheFile key $ \cachefile ->-	liftIO $ catchDefaultIO Nothing $ readCache <$> readFile cachefile--{- Compares a cache with the current cache for a file. -}-compareCache :: FilePath -> Maybe Cache -> Annex Bool-compareCache file old = do-	curr <- liftIO $ genCache file-	return $ isJust curr && curr == old+{- Gets the recorded inode cache for a key. -}+recordedInodeCache :: Key -> Annex (Maybe InodeCache)+recordedInodeCache key = withInodeCacheFile key $ \f ->+	liftIO $ catchDefaultIO Nothing $ readInodeCache <$> readFile f  {- Stores a cache of attributes for a file that is associated with a key. -}-updateCache :: Key -> FilePath -> Annex ()-updateCache key file = maybe noop (writeCache key) =<< liftIO (genCache file)+updateInodeCache :: Key -> FilePath -> Annex ()+updateInodeCache key file = maybe noop (writeInodeCache key)+	=<< liftIO (genInodeCache file)  {- Writes a cache for a key. -}-writeCache :: Key -> Cache -> Annex ()-writeCache key cache = withCacheFile key $ \cachefile -> do-	createContentDir cachefile-	liftIO $ writeFile cachefile $ showCache cache--{- Cache a file's inode, size, and modification time to determine if it's- - been changed. -}-data Cache = Cache FileID FileOffset EpochTime-	deriving (Eq, Show)--showCache :: Cache -> String-showCache (Cache inode size mtime) = unwords-	[ show inode-	, show size-	, show mtime-	]--readCache :: String -> Maybe Cache-readCache s = case words s of-	(inode:size:mtime:_) -> Cache-		<$> readish inode-		<*> readish size-		<*> readish mtime-	_ -> Nothing---- for quickcheck-prop_read_show_direct :: Cache -> Bool-prop_read_show_direct c = readCache (showCache c) == Just c--genCache :: FilePath -> IO (Maybe Cache)-genCache f = catchDefaultIO Nothing $ toCache <$> getFileStatus f+writeInodeCache :: Key -> InodeCache -> Annex ()+writeInodeCache key cache = withInodeCacheFile key $ \f -> do+	createContentDir f+	liftIO $ writeFile f $ showInodeCache cache -toCache :: FileStatus -> Maybe Cache-toCache s-	| isRegularFile s = Just $ Cache-		(fileID s)-		(fileSize s)-		(modificationTime s)-	| otherwise = Nothing+{- Removes an inode cache. -}+removeInodeCache :: Key -> Annex ()+removeInodeCache key = withInodeCacheFile key $ \f -> do+	createContentDir f -- also thaws directory+	liftIO $ nukeFile f -withCacheFile :: Key -> (FilePath -> Annex a) -> Annex a-withCacheFile key a = a =<< inRepo (gitAnnexCache key)+withInodeCacheFile :: Key -> (FilePath -> Annex a) -> Annex a+withInodeCacheFile key a = a =<< inRepo (gitAnnexInodeCache key)
Annex/Direct.hs view
@@ -10,8 +10,6 @@ import Common.Annex import qualified Git import qualified Git.LsFiles-import qualified Git.UpdateIndex-import qualified Git.HashObject import qualified Git.Merge import qualified Git.DiffTree as DiffTree import Git.Sha@@ -24,6 +22,8 @@ import Types.KeySource import Annex.Content import Annex.Content.Direct+import Annex.Link+import Utility.InodeCache import Utility.CopyFile  {- Uses git ls-files to find files that need to be committed, and stages@@ -45,12 +45,12 @@ 	go (file, Just sha) = do 		mkey <- catKey sha 		mstat <- liftIO $ catchMaybeIO $ getSymbolicLinkStatus file-		case (mkey, mstat, toCache =<< mstat) of+		case (mkey, mstat, toInodeCache =<< mstat) of 			(Just key, _, Just cache) -> do 				{- All direct mode files will show as 				 - modified, so compare the cache to see if 				 - it really was. -}-				oldcache <- recordedCache key+				oldcache <- recordedInodeCache key 				when (oldcache /= Just cache) $ 					modifiedannexed file key cache 			(Just key, Nothing, _) -> deletedannexed file key@@ -72,25 +72,23 @@  {- Adds a file to the annex in direct mode. Can fail, if the file is  - modified or deleted while it's being added. -}-addDirect :: FilePath -> Cache -> Annex Bool+addDirect :: FilePath -> InodeCache -> Annex Bool addDirect file cache = do 	showStart "add" file 	let source = KeySource 		{ keyFilename = file 		, contentLocation = file+		, inodeCache = Just cache 		} 	got =<< genKey source =<< chooseBackend file   where 	got Nothing = do 		showEndFail 		return False-	got (Just (key, _)) = ifM (compareCache file $ Just cache)+	got (Just (key, _)) = ifM (liftIO $ compareInodeCache file $ Just cache) 		( do-			link <- calcGitLink file key-			sha <- inRepo $ Git.HashObject.hashObject BlobObject link-			Annex.Queue.addUpdateIndex =<<-				inRepo (Git.UpdateIndex.stageSymlink file sha)-			writeCache key cache+			stageSymlink file =<< hashSymlink =<< calcGitLink file key+			writeInodeCache key cache 			void $ addAssociatedFile key file 			logStatus key InfoPresent 			showEndOk@@ -137,13 +135,13 @@ 			| otherwise = araw f 		f = DiffTree.file item -	moveout k f = removeDirect k f+	moveout = removeDirect  	{- Files deleted by the merge are removed from the work tree. 	 - Empty work tree directories are removed, per git behavior. -} 	moveout_raw f = liftIO $ do 		nukeFile f-		void $ catchMaybeIO $ removeDirectory $ parentDir f+		void $ tryIO $ removeDirectory $ parentDir f 	 	{- The symlink is created from the key, rather than moving in the 	 - symlink created in the temp directory by the merge. This because@@ -153,20 +151,20 @@  	 - Symlinks are replaced with their content, if it's available. -} 	movein k f = do 		l <- calcGitLink f k-		liftIO $ replaceFile f $ const $-			createSymbolicLink l f+		replaceFile f $+			makeAnnexLink l 		toDirect k f 	 	{- Any new, modified, or renamed files were written to the temp 	 - directory by the merge, and are moved to the real work tree. -} 	movein_raw f = liftIO $ do 		createDirectoryIfMissing True $ parentDir f-		void $ catchMaybeIO $ rename (d </> f) f+		void $ tryIO $ rename (d </> f) f  {- If possible, converts a symlink in the working tree into a direct  - mode file. -} toDirect :: Key -> FilePath -> Annex ()-toDirect k f = maybe noop id =<< toDirectGen k f+toDirect k f = fromMaybe noop =<< toDirectGen k f  toDirectGen :: Key -> FilePath -> Annex (Maybe (Annex ())) toDirectGen k f = do@@ -177,16 +175,17 @@ 		[] -> ifM (liftIO $ doesFileExist loc) 			( return $ Just $ do 				{- Move content from annex to direct file. -}-				updateCache k loc+				updateInodeCache k loc 				thawContent loc-				liftIO $ replaceFile f $ moveFile loc+				replaceFile f $+					liftIO . moveFile loc 			, return Nothing 			)-		(loc':_) -> ifM (liftIO $ catchBoolIO $ not . isSymbolicLink <$> getSymbolicLinkStatus loc')+		(loc':_) -> ifM (isNothing <$> getAnnexLinkTarget loc') 			{- Another direct file has the content; copy it. -}-			( return $ Just $ do-				liftIO $ replaceFile f $-					void . copyFileExternal loc'+			( return $ Just $+				replaceFile f $+					void . liftIO . copyFileExternal loc' 			, return Nothing 			) @@ -194,16 +193,12 @@ removeDirect :: Key -> FilePath -> Annex () removeDirect k f = do 	locs <- removeAssociatedFile k f-	when (null locs) $ do-		r <- liftIO $ catchMaybeIO $ getSymbolicLinkStatus f-		case r of-			Just s-				| not (isSymbolicLink s) ->-					moveAnnex k f-			_ -> noop+	when (null locs) $+		whenM (isNothing <$> getAnnexLinkTarget f) $+			moveAnnex k f 	liftIO $ do 		nukeFile f-		void $ catchMaybeIO $ removeDirectory $ parentDir f+		void $ tryIO $ removeDirectory $ parentDir f  {- Called when a direct mode file has been changed. Its old content may be  - lost. -}
+ Annex/Link.hs view
@@ -0,0 +1,76 @@+{- git-annex links to content+ -+ - On file systems that support them, symlinks are used.+ -+ - On other filesystems, git instead stores the symlink target in a regular+ - file.+ -+ - Copyright 2013 Joey Hess <joey@kitenet.net>+ -+ - Licensed under the GNU GPL version 3 or higher.+ -}++module Annex.Link where++import Common.Annex+import qualified Annex+import qualified Git.HashObject+import qualified Git.UpdateIndex+import qualified Annex.Queue+import Git.Types++type LinkTarget = String++{- Checks if a file is a link to a key. -}+isAnnexLink :: FilePath -> Annex (Maybe Key)+isAnnexLink file = maybe Nothing (fileKey . takeFileName) <$> getAnnexLinkTarget file++{- Gets the link target of a symlink.+ -+ - On a filesystem that does not support symlinks, get the link+ - target by looking inside the file. (Only return at first 8k of the file,+ - more than enough for any symlink target.)+ -+ - Returns Nothing if the file is not a symlink, or not a link to annex+ - content.+ -}+getAnnexLinkTarget :: FilePath -> Annex (Maybe LinkTarget)+getAnnexLinkTarget file = do+	v <- ifM (coreSymlinks <$> Annex.getGitConfig)+		( liftIO $ catchMaybeIO $ readSymbolicLink file+		, liftIO $ catchMaybeIO $ take 8192 <$> readFile file+		)+	case v of+		Nothing -> return Nothing+		Just l+			| isLinkToAnnex l -> return v+			| otherwise -> return Nothing++{- Creates a link on disk.+ -+ - On a filesystem that does not support symlinks, writes the link target+ - to a file. Note that git will only treat the file as a symlink if+ - it's staged as such, so use addAnnexLink when adding a new file or+ - modified link to git.+ -}+makeAnnexLink :: LinkTarget -> FilePath -> Annex ()+makeAnnexLink linktarget file = ifM (coreSymlinks <$> Annex.getGitConfig)+	( liftIO $ createSymbolicLink linktarget file+	, liftIO $ writeFile file linktarget+	)++{- Creates a link on disk, and additionally stages it in git. -}+addAnnexLink :: LinkTarget -> FilePath -> Annex ()+addAnnexLink linktarget file = do+	makeAnnexLink linktarget file+	stageSymlink file =<< hashSymlink linktarget++{- Injects a symlink target into git, returning its Sha. -}+hashSymlink :: LinkTarget -> Annex Sha+hashSymlink linktarget = inRepo $ Git.HashObject.hashObject BlobObject linktarget++{- Stages a symlink to the annex, using a Sha of its target. -}+stageSymlink :: FilePath -> Sha -> Annex ()+stageSymlink file sha =+	Annex.Queue.addUpdateIndex =<<+		inRepo (Git.UpdateIndex.stageSymlink file sha)
Annex/Perms.hs view
@@ -18,6 +18,7 @@ import Utility.FileMode import Git.SharedRepository import qualified Annex+import Config  import System.Posix.Types @@ -34,7 +35,8 @@  - use the default mode, but with core.sharedRepository set,  - allow the group to write, etc. -} setAnnexPerm :: FilePath -> Annex ()-setAnnexPerm file = withShared $ liftIO . go+setAnnexPerm file = unlessM crippledFileSystem $+	withShared $ liftIO . go   where 	go GroupShared = groupWriteRead file 	go AllShared = modifyFileMode file $ addModes $@@ -77,7 +79,8 @@  - file.  -} freezeContentDir :: FilePath -> Annex ()-freezeContentDir file = liftIO . go =<< fromRepo getSharedRepository+freezeContentDir file = unlessM crippledFileSystem $+	liftIO . go =<< fromRepo getSharedRepository   where 	dir = parentDir file 	go GroupShared = groupWriteRead dir@@ -91,6 +94,7 @@ 	unlessM (liftIO $ doesDirectoryExist dir) $ 		createAnnexDirectory dir  	-- might have already existed with restricted perms-	liftIO $ allowWrite dir+	unlessM crippledFileSystem $+		liftIO $ allowWrite dir   where 	dir = parentDir dest
Annex/UUID.hs view
@@ -6,7 +6,7 @@  - UUIDs of remotes are cached in git config, using keys named  - remote.<name>.annex-uuid  -- - Copyright 2010-2011 Joey Hess <joey@kitenet.net>+ - Copyright 2010-2013 Joey Hess <joey@kitenet.net>  -  - Licensed under the GNU GPL version 3 or higher.  -}@@ -24,20 +24,17 @@ import Common.Annex import qualified Git import qualified Git.Config-import qualified Build.SysConfig as SysConfig import Config +import qualified Data.UUID as U+import System.Random+ configkey :: ConfigKey configkey = annexConfig "uuid" -{- Generates a UUID. There is a library for this, but it's not packaged,- - so use the command line tool. -}+{- Generates a random UUID, that does not include the MAC address. -} genUUID :: IO UUID-genUUID = gen . lines <$> readProcess command params-  where-	gen [] = error $ "no output from " ++ command-	gen (l:_) = toUUID l-	(command:params) = words SysConfig.uuid+genUUID = UUID . show <$> (randomIO :: IO U.UUID)  {- Get current repository's UUID. -} getUUID :: Annex UUID
Assistant/Install.hs view
@@ -14,6 +14,7 @@ import Assistant.Ssh import Locations.UserConfig import Utility.FileMode+import Utility.Shell  #ifdef darwin_HOST_OS import Utility.OSX@@ -58,7 +59,7 @@ 		sshdir <- sshDir 		let shim = sshdir </> "git-annex-shell" 		let content = unlines-			[ "#!/bin/sh"+			[ shebang 			, "set -e" 			, "exec", base </> "runshell" ++  			  " git-annex-shell -c \"$SSH_ORIGINAL_COMMAND\""
Assistant/Pairing.hs view
@@ -5,6 +5,8 @@  - Licensed under the GNU GPL version 3 or higher.  -} +{-# LANGUAGE CPP #-}+ module Assistant.Pairing where  import Common.Annex@@ -70,7 +72,12 @@ 	} 	deriving (Show) -data SomeAddr = IPv4Addr HostAddress | IPv6Addr HostAddress6+data SomeAddr = IPv4Addr HostAddress+{- My Android build of the Network library does not currently have IPV6+ - support. -}+#ifndef WITH_ANDROID+	| IPv6Addr HostAddress6+#endif 	deriving (Ord, Eq, Read, Show)  {- This contains the whole secret, just lightly obfuscated to make it not
Assistant/Pairing/Network.hs view
@@ -60,7 +60,7 @@ 		go cache' $ pred <$> n 	{- The multicast library currently chokes on ipv6 addresses. -} 	sendinterface _ (IPv6Addr _) = noop-	sendinterface cache i = void $ catchMaybeIO $+	sendinterface cache i = void $ tryIO $ 		withSocketsDo $ bracket setup cleanup use 	  where 		setup = multicastSender (multicastAddress i) pairingPort
Assistant/Ssh.hs view
@@ -10,6 +10,7 @@ import Common.Annex import Utility.TempFile import Utility.UserInfo+import Utility.Shell import Git.Remote  import Data.Text (Text)@@ -155,7 +156,7 @@ 	echoval v = "echo " ++ shellEscape v 	wrapper = "~/.ssh/git-annex-shell" 	script =-		[ "#!/bin/sh"+		[ shebang 		, "set -e" 		, "exec git-annex-shell -c \"$SSH_ORIGINAL_COMMAND\"" 		]
Assistant/Threads/Committer.hs view
@@ -15,16 +15,13 @@ import Assistant.Commits import Assistant.Alert import Assistant.DaemonStatus-import Assistant.Threads.Watcher import Assistant.TransferQueue import Logs.Transfer import Logs.Location import qualified Annex.Queue import qualified Git.Command-import qualified Git.HashObject import qualified Git.LsFiles import qualified Git.Version-import Git.Types import qualified Command.Add import Utility.ThreadScheduler import qualified Utility.Lsof as Lsof@@ -33,6 +30,7 @@ import Config import Annex.Exception import Annex.Content+import Annex.Link import qualified Annex  import Data.Time.Clock@@ -216,9 +214,7 @@ 				, Command.Add.link file key True 				) 			whenM (pure DirWatcher.eventsCoalesce <||> isDirect) $ do-				sha <- inRepo $-					Git.HashObject.hashObject BlobObject link-				stageSymlink file sha+				stageSymlink file =<< hashSymlink link 				showEndOk 		queueTransfers Next key (Just file) Upload 		return $ Just change@@ -233,14 +229,14 @@ 			then a 			else do 				-- remove the hard link-				void $ liftIO $ tryIO $ removeFile $ contentLocation keysource+				when (contentLocation keysource /= keyFilename keysource) $+					void $ liftIO $ tryIO $ removeFile $ contentLocation keysource 				return Nothing  {- Files can Either be Right to be added now,  - or are unsafe, and must be Left for later.  -- - Check by running lsof on the temp directory, which- - the KeySources are locked down in.+ - Check by running lsof on the repository.  -} safeToAdd :: Maybe Seconds -> [Change] -> [Change] -> Assistant [Either Change Change] safeToAdd _ [] [] = return []@@ -248,12 +244,12 @@ 	maybe noop (liftIO . threadDelaySeconds) delayadd 	liftAnnex $ do 		keysources <- mapM Command.Add.lockDown (map changeFile pending)-		let inprocess' = catMaybes $ -			map mkinprocess (zip pending keysources)-		tmpdir <- fromRepo gitAnnexTmpDir+		let inprocess' = inprocess ++ catMaybes (map mkinprocess $ zip pending keysources) 		openfiles <- S.fromList . map fst3 . filter openwrite <$>-			liftIO (Lsof.queryDir tmpdir)-		let checked = map (check openfiles) $ inprocess ++ inprocess'+			findopenfiles (map keySource inprocess')+		liftIO $ print openfiles+		let checked = map (check openfiles) inprocess'+		liftIO $ print checked  		{- If new events are received when files are closed, 		 - there's no need to retry any changes that cannot@@ -278,10 +274,29 @@ 		warning $ keyFilename ks 			++ " still has writers, not adding" 		-- remove the hard link-		void $ liftIO $ tryIO $ removeFile $ contentLocation ks+		when (contentLocation ks /= keyFilename ks) $+			void $ liftIO $ tryIO $ removeFile $ contentLocation ks 	canceladd _ = noop -	openwrite (_file, mode, _pid) =-		mode == Lsof.OpenWriteOnly || mode == Lsof.OpenReadWrite+	openwrite (_file, mode, _pid)+		| mode == Lsof.OpenWriteOnly = True+		| mode == Lsof.OpenReadWrite = True+		| mode == Lsof.OpenUnknown = True+		| otherwise = False  	allRight = return . map Right++	{- Normally the KeySources are locked down inside the temp directory,+	 - so can just lsof that, which is quite efficient.+	 -+	 - In crippled filesystem mode, there is no lock down, so must run lsof+	 - on each individual file.+	 -}+	findopenfiles keysources = ifM crippledFileSystem+		( liftIO $ do+			let segments = segmentXargs $ map keyFilename keysources+			concat <$> forM segments (\fs -> Lsof.query $ "--" : fs)+		, do+			tmpdir <- fromRepo gitAnnexTmpDir+			liftIO $ Lsof.queryDir tmpdir+		)
Assistant/Threads/Watcher.hs view
@@ -12,7 +12,6 @@ 	WatcherException(..), 	checkCanWatch, 	needLsof,-	stageSymlink, 	onAddSymlink, 	runHandler, ) where@@ -32,13 +31,13 @@ import qualified Annex.Queue import qualified Git import qualified Git.UpdateIndex-import qualified Git.HashObject import qualified Git.LsFiles as LsFiles import qualified Backend import Annex.Content import Annex.Direct import Annex.Content.Direct import Annex.CatFile+import Annex.Link import Git.Types import Config import Utility.ThreadScheduler@@ -206,7 +205,7 @@ 				ensurestaged (Just link) s 			, do 				liftIO $ removeFile file-				liftIO $ createSymbolicLink link file+				liftAnnex $ Backend.makeAnnexLink link file 				checkcontent key =<< getDaemonStatus 				addlink link 			)@@ -242,10 +241,7 @@ 				Just (currlink, sha) 					| s2w8 link == L.unpack currlink -> 						stageSymlink file sha-				_ -> do-					sha <- inRepo $-						Git.HashObject.hashObject BlobObject link-					stageSymlink file sha+				_ -> stageSymlink file =<< hashSymlink link 		madeChange file LinkChange  	{- When a new link appears, or a link is changed, after the startup@@ -289,13 +285,3 @@ 	liftAnnex $ warning msg 	void $ addAlert $ warningAlert "watcher" msg 	noChange--{- Adds a symlink to the index, without ever accessing the actual symlink- - on disk. This avoids a race if git add is used, where the symlink is- - changed to something else immediately after creation. It also allows- - direct mode to work.- -}-stageSymlink :: FilePath -> Sha -> Annex ()-stageSymlink file sha =-	Annex.Queue.addUpdateIndex =<<-		inRepo (Git.UpdateIndex.stageSymlink file sha)
Assistant/WebApp/Configurators/Local.hs view
@@ -82,7 +82,6 @@ 		, (return $ path == home, "Sorry, using git-annex for your whole home directory is not currently supported.") 		, (not <$> doesDirectoryExist parent, "Parent directory does not exist.") 		, (not <$> canWrite path, "Cannot write a repository there.")-		, (not <$> canMakeSymlink path, "That directory is on a filesystem that does not support symlinks. Try a different location.") 		] 	return $  		case headMaybe problems of@@ -306,16 +305,3 @@ 	tocheck <- ifM (doesDirectoryExist dir) 		(return dir, return $ parentDir dir) 	catchBoolIO $ fileAccess tocheck False True False--{- Checks if a directory is on a filesystem that supports symlinks. -}-canMakeSymlink :: FilePath -> IO Bool-canMakeSymlink dir = ifM (doesDirectoryExist dir)-	( catchBoolIO $ test dir-	, canMakeSymlink (parentDir dir)-	)-  where-	test d = do-		let link = d </> "delete.me"-		createSymbolicLink link link-		removeLink link-		return True
Assistant/WebApp/Utility.hs view
@@ -97,7 +97,7 @@ 		| otherwise = killThread tid 	{- In order to stop helper processes like rsync, 	 - kill the whole process group of the process running the transfer. -}-	killproc pid = void $ catchMaybeIO $ do+	killproc pid = void $ tryIO $ do 		g <- getProcessGroupIDOf pid 		void $ tryIO $ signalProcessGroup sigTERM g 		threadDelay 50000 -- 0.05 second grace period
Assistant/XMPP/Git.hs view
@@ -25,6 +25,7 @@ import Locations.UserConfig import qualified Types.Remote as Remote import Utility.FileMode+import Utility.Shell  import Network.Protocol.XMPP import qualified Data.Text as T@@ -141,7 +142,7 @@ 		let wrapper = tmpdir </> "git-remote-xmpp" 		program <- readProgramFile 		writeFile wrapper $ unlines-			[ "#!/bin/sh"+			[ shebang 			, "exec " ++ program ++ " xmppgit" 			] 		modifyFileMode wrapper $ addModes executeModes
Backend.hs view
@@ -1,6 +1,6 @@ {- git-annex key/value backends  -- - Copyright 2010 Joey Hess <joey@kitenet.net>+ - Copyright 2010,2013 Joey Hess <joey@kitenet.net>  -  - Licensed under the GNU GPL version 3 or higher.  -}@@ -10,17 +10,18 @@ 	orderedList, 	genKey, 	lookupFile,+	isAnnexLink,+	makeAnnexLink, 	chooseBackend, 	lookupBackendName, 	maybeLookupBackendName ) where -import System.Posix.Files- import Common.Annex import qualified Annex import Annex.CheckAttr import Annex.CatFile+import Annex.Link import Types.Key import Types.KeySource import qualified Types.Backend as B@@ -75,26 +76,23 @@ 		| 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 links 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+ - In direct mode, there is often no link on disk, in which case+ - the symlink is looked up in git instead. However, a real link  - 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-		Right l-			| isLinkToAnnex l -> makekey l-			| otherwise -> return Nothing-		Left _ -> ifM isDirect+	mkey <- isAnnexLink file+	case mkey of+		Just key -> makeret key+		Nothing -> ifM isDirect 			( maybe (return Nothing) makeret =<< catKeyFile file 			, return Nothing 			)   where-	makekey l = maybe (return Nothing) makeret (fileKey $ takeFileName l) 	makeret k = let bname = keyBackendName k in 		case maybeLookupBackendName bname of 			Just backend -> do
Build/Configure.hs view
@@ -7,6 +7,7 @@ import System.Process import Control.Applicative import System.FilePath+import System.Environment  import Build.TestConfig import Utility.SafeCommand@@ -19,7 +20,6 @@ 	, testCp "cp_a" "-a" 	, testCp "cp_p" "-p" 	, testCp "cp_reflink_auto" "--reflink=auto"-	, TestCase "uuid generator" $ selectCmd "uuid" [("uuid -m", ""), ("uuid", ""), ("uuidgen", "")] 	, TestCase "xargs -0" $ requireCmd "xargs_0" "xargs -0 </dev/null" 	, TestCase "rsync" $ requireCmd "rsync" "rsync --version >/dev/null" 	, TestCase "curl" $ testCmd "curl" "curl --version >/dev/null"@@ -122,8 +122,26 @@  run :: [TestCase] -> IO () run ts = do+	args <- getArgs 	setup 	config <- runTests ts-	writeSysConfig config+	if args == ["Android"]+		then writeSysConfig $ androidConfig config+		else writeSysConfig config 	cleanup 	cabalSetup++{- Hard codes some settings to cross-compile for Android. -}+androidConfig :: [Config] -> [Config]+androidConfig c = overrides ++ filter (not . overridden) c+  where+	overrides = +		[ Config "cp_reflink_auto" $ BoolConfig False+		, Config "curl" $ BoolConfig False+		, Config "sshconnectioncaching" $ BoolConfig False+		, Config "sha224" $ MaybeStringConfig Nothing+		, Config "sha384" $ MaybeStringConfig Nothing+		]+	overridden (Config k _) = k `elem` overridekeys+	overridekeys = map (\(Config k _) -> k) overrides+
Build/Standalone.hs view
@@ -39,7 +39,6 @@ 	, Just "rsync" 	, Just "ssh" 	, Just "sh"-	, headMaybe $ words SysConfig.uuid -- may include parameters 	, ifset SysConfig.curl "curl" 	, ifset SysConfig.wget "wget" 	, ifset SysConfig.bup "bup"
CHANGELOG view
@@ -1,3 +1,32 @@+git-annex (3.20130217) UNRELEASED; urgency=low++  * Should now fully support git repositories with core.symlinks=false;+    always using git's pseudosymlink files in such repositories.+  * webapp: Allow creating repositories on filesystems that lack support for+    symlinks.++ -- Joey Hess <joeyh@debian.org>  Sun, 17 Feb 2013 16:42:16 -0400++git-annex (3.20130216) unstable; urgency=low++  * Now uses the Haskell uuid library, rather than needing a uuid program.+  * Now uses the Haskell Glob library, rather than pcre-light, avoiding+    the need to install libpcre. Currently done only for Cabal or when+    the Makefile is made to use -DWITH_GLOB+  * Android port now available (command-line only).+  * New annex.crippledfilesystem setting, allows use of git-annex+    repositories on FAT and even worse filesystems; avoiding use of+    hard links and locked down permissions settings. (Support is incomplete.)+  * init: Detect when the repository is on a filesystem that does not+    support hard links, or symlinks, or unix permissions, and set+    annex.crippledfilesystem, as well as annex.direct.+  * add: Improved detection of files that are modified while being added.+  * Fix a bug in direct mode, introduced in the previous release, where+    if a file was dropped and then got back, it would be stored in indirect+    mode.++ -- Joey Hess <joeyh@debian.org>  Sat, 16 Feb 2013 10:03:26 -0400+ git-annex (3.20130207) unstable; urgency=low    * webapp: Now allows restarting any threads that crash.
Command/Add.hs view
@@ -5,25 +5,28 @@  - Licensed under the GNU GPL version 3 or higher.  -} +{-# LANGUAGE CPP #-}+ module Command.Add where  import Common.Annex import Annex.Exception import Command-import qualified Annex-import qualified Annex.Queue import Types.KeySource import Backend import Logs.Location import Annex.Content import Annex.Content.Direct import Annex.Perms+import Annex.Link+import qualified Annex+import qualified Annex.Queue+#ifndef WITH_ANDROID import Utility.Touch+#endif import Utility.FileMode import Config-import qualified Git.HashObject-import qualified Git.UpdateIndex-import Git.Types+import Utility.InodeCache  def :: [Command] def = [notBareRepo $ command "add" paramPaths seek "add files to annex"]@@ -63,18 +66,32 @@  - Lockdown can fail if a file gets deleted, and Nothing will be returned.  -} lockDown :: FilePath -> Annex (Maybe KeySource)-lockDown file = do-	tmp <- fromRepo gitAnnexTmpDir-	createAnnexDirectory tmp-	liftIO $ catchMaybeIO $ do-		preventWrite file-		(tmpfile, h) <- openTempFile tmp (takeFileName file)-		hClose h-		nukeFile tmpfile-		createLink file tmpfile-		return $ KeySource { keyFilename = file , contentLocation = tmpfile }+lockDown file = ifM (crippledFileSystem)+	( liftIO $ catchMaybeIO $ do+		cache <- genInodeCache file+		return $ KeySource+			{ keyFilename = file+			, contentLocation = file+			, inodeCache = cache+			}+	, do+		tmp <- fromRepo gitAnnexTmpDir+		createAnnexDirectory tmp+		liftIO $ catchMaybeIO $ do+			preventWrite file+			(tmpfile, h) <- openTempFile tmp (takeFileName file)+			hClose h+			nukeFile tmpfile+			createLink file tmpfile+			cache <- genInodeCache tmpfile+			return $ KeySource+				{ keyFilename = file+				, contentLocation = tmpfile+				, inodeCache = cache+				}+	) -{- Moves a locked down file into the annex.+{- Ingests a locked down file into the annex.  -  - In direct mode, leaves the file alone, and just updates bookkeeping  - information.@@ -83,35 +100,36 @@ ingest Nothing = return Nothing ingest (Just source) = do 	backend <- chooseBackend $ keyFilename source-	ifM isDirect-		( do-			mstat <- liftIO $ catchMaybeIO $ getSymbolicLinkStatus $ keyFilename source-			k <- genKey source backend-			godirect k (toCache =<< mstat)-		, go =<< genKey source backend-		)+	k <- genKey source backend+	cache <- liftIO $ genInodeCache $ contentLocation source+	case inodeCache source of+		Nothing -> go k cache+		Just c+			| (Just c == cache) -> go k cache+			| otherwise -> failure   where-	go (Just (key, _)) = do+	go k cache = ifM isDirect ( godirect k cache , goindirect k cache )++	goindirect (Just (key, _)) _ = do 		handle (undo (keyFilename source) key) $ 			moveAnnex key $ contentLocation source 		liftIO $ nukeFile $ keyFilename source 		return $ Just key-	go Nothing = failure+	goindirect Nothing _ = failure -	godirect (Just (key, _)) (Just cache) =-		ifM (compareCache (keyFilename source) $ Just cache)-			( do-				writeCache key cache-				void $ addAssociatedFile key $ keyFilename source-				liftIO $ allowWrite $ keyFilename source-				liftIO $ nukeFile $ contentLocation source-				return $ Just key-			, failure-			)+	godirect (Just (key, _)) (Just cache) = do+		writeInodeCache key cache+		void $ addAssociatedFile key $ keyFilename source+		unlessM crippledFileSystem $+			liftIO $ allowWrite $ keyFilename source+		when (contentLocation source /= keyFilename source) $+			liftIO $ nukeFile $ contentLocation source+		return $ Just key 	godirect _ _ = failure  	failure = do-		liftIO $ nukeFile $ contentLocation source+		when (contentLocation source /= keyFilename source) $+			liftIO $ nukeFile $ contentLocation source 		return Nothing		  perform :: FilePath -> CommandPerform@@ -139,35 +157,49 @@ link :: FilePath -> Key -> Bool -> Annex String link file key hascontent = handle (undo file key) $ do 	l <- calcGitLink file key-	liftIO $ createSymbolicLink l file+	makeAnnexLink l file +#ifndef WITH_ANDROID 	when hascontent $ do 		-- touch the symlink to have the same mtime as the 		-- file it points to 		liftIO $ do 			mtime <- modificationTime <$> getFileStatus file 			touch file (TimeSpec mtime) False+#endif  	return l  {- Note: Several other commands call this, and expect it to - - create the symlink and add it. -}+ - create the link and add it.+ - + - In direct mode, when we have the content of the file, it's left as-is,+ - and we just stage a symlink to git.+ - + - Otherwise, as long as the filesystem supports symlinks, we use+ - git add, rather than directly staging the symlink to git.+ - Using git add is best because it allows the queuing to work+ - and is faster (staging the symlink runs hash-object commands each time).+ - Also, using git add allows it to skip gitignored files, unless forced+ - to include them.+ -} cleanup :: FilePath -> Key -> Bool -> CommandCleanup cleanup file key hascontent = do 	when hascontent $ 		logStatus key InfoPresent 	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)-		, do-			_ <- link file key hascontent-			params <- ifM (Annex.getState Annex.force)-				( return [Param "-f"]-				, return []-				)-			Annex.Queue.addCommand "add" (params++[Param "--"]) [file]+		( stageSymlink file =<< hashSymlink =<< calcGitLink file key+		, ifM (coreSymlinks <$> Annex.getGitConfig)+			( do+				_ <- link file key hascontent+				params <- ifM (Annex.getState Annex.force)+					( return [Param "-f"]+					, return []+					)+				Annex.Queue.addCommand "add" (params++[Param "--"]) [file]+			, do+				l <- link file key hascontent+				addAnnexLink l file+			) 		) 	return True
Command/AddUrl.hs view
@@ -75,7 +75,11 @@ 	liftIO $ createDirectoryIfMissing True (parentDir tmp) 	stopUnless (downloadUrl [url] tmp) $ do 		backend <- chooseBackend file-		let source = KeySource { keyFilename = file, contentLocation = tmp }+		let source = KeySource+			{ keyFilename = file+			, contentLocation = tmp+			, inodeCache = Nothing+			} 		k <- genKey source backend 		case k of 			Nothing -> stop
Command/Drop.hs view
@@ -60,10 +60,7 @@ 	untrusteduuids <- trustGet UnTrusted 	let tocheck = Remote.remotesWithoutUUID remotes (trusteduuids'++untrusteduuids) 	stopUnless (canDropKey key numcopies trusteduuids' tocheck []) $ do-		whenM (inAnnex key) $-			removeAnnex key-		{- Clean up stale direct mode files that may exist. -}-		cleanObjectLoc key+		removeAnnex key 		next $ cleanupLocal key  performRemote :: Key -> Maybe Int -> Remote -> CommandPerform
Command/Fsck.hs view
@@ -10,7 +10,6 @@ import Common.Annex import Command import qualified Annex-import qualified Annex.Queue import qualified Remote import qualified Types.Backend import qualified Types.Key@@ -18,6 +17,7 @@ import Annex.Content import Annex.Content.Direct import Annex.Perms+import Annex.Link import Logs.Location import Logs.Trust import Annex.UUID@@ -182,14 +182,14 @@ 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 link points correctly to the content.  -- - In direct mode, there is only a symlink when the content is not present.+ - In direct mode, there is only a link when the content is not present.  -} fixLink :: Key -> FilePath -> Annex Bool fixLink key file = do 	want <- calcGitLink file key-	have <- liftIO $ catchMaybeIO $ readSymbolicLink file+	have <- getAnnexLinkTarget file 	maybe noop (go want) have 	return True   where@@ -203,14 +203,14 @@ 				showNote "fixing content location" 				dir <- liftIO $ parentDir <$> absPath file 				let content = absPathFrom dir have-				liftIO $ allowWrite (parentDir content)+				unlessM crippledFileSystem $+					liftIO $ allowWrite (parentDir content) 				moveAnnex key content  		showNote "fixing link" 		liftIO $ createDirectoryIfMissing True (parentDir file) 		liftIO $ removeFile file-		liftIO $ createSymbolicLink want file-		Annex.Queue.addCommand "add" [Param "--force", Param "--"] [file]+		addAnnexLink want file  {- Checks that the location log reflects the current status of the key,  - in this repository only. -}
Command/Indirect.hs view
@@ -13,9 +13,11 @@ import qualified Git.Command import qualified Git.LsFiles import Config+import qualified Annex import Annex.Direct import Annex.Content import Annex.CatFile+import Init  def :: [Command] def = [notBareRepo $ command "indirect" paramNothing seek@@ -25,7 +27,15 @@ seek = [withNothing start]  start :: CommandStart-start = ifM isDirect ( next perform, stop )+start = ifM isDirect+	( do+		unlessM (coreSymlinks <$> Annex.getGitConfig) $+			error "Git is configured to not use symlinks, so you must use direct mode."+		whenM probeCrippledFileSystem $+			error "This repository seems to be on a crippled filesystem, you must use direct mode."+		next perform+	, stop+	)  perform :: CommandPerform perform = do@@ -73,7 +83,7 @@ 		showEndOk  	cleandirect k = do-		liftIO . nukeFile =<< inRepo (gitAnnexCache k)+		liftIO . nukeFile =<< inRepo (gitAnnexInodeCache k) 		liftIO . nukeFile =<< inRepo (gitAnnexMapping k)  cleanup :: CommandCleanup
Command/Migrate.hs view
@@ -63,5 +63,9 @@ 		next $ Command.ReKey.cleanup file oldkey newkey 	genkey = do 		content <- inRepo $ gitAnnexLocation oldkey-		let source = KeySource { keyFilename = file, contentLocation = content }+		let source = KeySource+			{ keyFilename = file+			, contentLocation = content+			, inodeCache = Nothing+			} 		liftM fst <$> genKey source (Just newbackend)
Command/Move.hs view
@@ -104,7 +104,7 @@ 			Remote.logStatus dest key InfoPresent 		if move 			then do-				whenM (inAnnex key) $ removeAnnex key+				removeAnnex key 				next $ Command.Drop.cleanupLocal key 			else next $ return True 
Command/ReKey.hs view
@@ -14,6 +14,8 @@ import Annex.Content import qualified Command.Add import Logs.Web+import Config+import Utility.CopyFile  def :: [Command] def = [notDirect $ command "rekey"@@ -48,8 +50,15 @@ linkKey :: Key -> Key -> Annex Bool linkKey oldkey newkey = getViaTmpUnchecked newkey $ \tmp -> do 	src <- inRepo $ gitAnnexLocation oldkey-	liftIO $ unlessM (doesFileExist tmp) $ createLink src tmp-	return True+	ifM (liftIO $ doesFileExist tmp)+		( return True+		, ifM crippledFileSystem+			( liftIO $ copyFileExternal src tmp+			, do+				liftIO $ createLink src tmp+				return True+			)+		)  cleanup :: FilePath -> Key -> Key -> CommandCleanup cleanup file oldkey newkey = do
Command/Sync.hs view
@@ -17,6 +17,7 @@ import Annex.Content import Annex.Direct import Annex.CatFile+import Annex.Link import qualified Git.Command import qualified Git.LsFiles as LsFiles import qualified Git.Merge@@ -263,10 +264,8 @@ 	makelink (Just key) = do 		let dest = mergeFile file key 		l <- calcGitLink dest key-		liftIO $ do-			nukeFile dest-			createSymbolicLink l dest-		Annex.Queue.addCommand "add" [Param "--force", Param "--"] [dest]+		liftIO $ nukeFile dest+		addAnnexLink l dest 		whenM (isDirect) $ 			toDirect key dest 	makelink _ = noop
Config.hs view
@@ -86,6 +86,14 @@ 	setConfig (annexConfig "direct") (Git.Config.boolConfig b) 	Annex.changeGitConfig $ \c -> c { annexDirect = b } +crippledFileSystem :: Annex Bool+crippledFileSystem = annexCrippledFileSystem <$> Annex.getGitConfig++setCrippledFileSystem :: Bool -> Annex ()+setCrippledFileSystem b = do+	setConfig (annexConfig "crippledfilesystem") (Git.Config.boolConfig b)+	Annex.changeGitConfig $ \c -> c { annexCrippledFileSystem = b }+ {- Gets the http headers to use. -} getHttpHeaders :: Annex [String] getHttpHeaders = do
INSTALL view
@@ -14,6 +14,7 @@ [[ScientificLinux5]]  | (and other RHEL5 clones like CentOS5) [[openSUSE]]          |  Windows               | [[sorry, Windows not supported yet|todo/windows_support]]+[[Android]]           |  """]]  ## Using cabal
Init.hs view
@@ -9,18 +9,25 @@ 	ensureInitialized, 	isInitialized, 	initialize,-	uninitialize+	uninitialize,+	probeCrippledFileSystem ) where  import Common.Annex import Utility.TempFile import Utility.Network import qualified Git+import qualified Git.LsFiles import qualified Annex.Branch import Logs.UUID import Annex.Version import Annex.UUID import Utility.UserInfo+import Utility.Shell+import Utility.FileMode+import Config+import Annex.Direct+import Backend  genDescription :: Maybe String -> Annex String genDescription (Just d) = return d@@ -34,6 +41,7 @@ initialize :: Maybe String -> Annex () initialize mdescription = do 	prepUUID+	checkCrippledFileSystem 	Annex.Branch.create 	setVersion 	gitPreCommitHookWrite@@ -92,7 +100,43 @@ preCommitHook = (</>) <$> fromRepo Git.localGitDir <*> pure "hooks/pre-commit"  preCommitScript :: String-preCommitScript = -	"#!/bin/sh\n" ++-	"# automatically configured by git-annex\n" ++ -	"git annex pre-commit .\n"+preCommitScript = unlines+	[ shebang+	, "# automatically configured by git-annex"+	, "git annex pre-commit ."+	]++probeCrippledFileSystem :: Annex Bool+probeCrippledFileSystem = do+	tmp <- fromRepo gitAnnexTmpDir+	let f = tmp </> "gaprobe"+	liftIO $ do+		createDirectoryIfMissing True tmp+		writeFile f ""+	uncrippled <- liftIO $ probe f+	liftIO $ removeFile f+	return $ not uncrippled+  where+	probe f = catchBoolIO $ do+		let f2 = f ++ "2"+		nukeFile f2+		createLink f f2+		nukeFile f2+		createSymbolicLink f f2+		nukeFile f2+		preventWrite f+		allowWrite f+		return True++checkCrippledFileSystem :: Annex ()+checkCrippledFileSystem = whenM (probeCrippledFileSystem) $ do+	warning "Detected a crippled filesystem."+	setCrippledFileSystem True+	unlessM isDirect $ do+		warning "Enabling direct mode."+		top <- fromRepo Git.repoPath+		(l, clean) <- inRepo $ Git.LsFiles.inRepo [top]+		forM_ l $ \f ->+			maybe noop (`toDirect` f) =<< isAnnexLink f+		void $ liftIO clean+		setDirect True
Limit.hs view
@@ -5,13 +5,19 @@  - Licensed under the GNU GPL version 3 or higher.  -} +{-# LANGUAGE PackageImports, CPP #-}+ module Limit where -import Text.Regex.PCRE.Light.Char8-import System.Path.WildMatch import Data.Time.Clock.POSIX import qualified Data.Set as S import qualified Data.Map as M+#ifdef WITH_GLOB+import "Glob" System.FilePath.Glob (simplify, compile, match)+#else+import Text.Regex.PCRE.Light.Char8+import System.Path.WildMatch+#endif  import Common.Annex import qualified Annex@@ -82,10 +88,16 @@  matchglob :: String -> Annex.FileInfo -> Bool matchglob glob (Annex.FileInfo { Annex.matchFile = f }) =+#ifdef WITH_GLOB+	match pattern f+  where+	pattern = simplify $ compile glob+#else 	isJust $ match cregex f []   where 	cregex = compile regex [] 	regex = '^':wildToRegex glob+#endif  {- Adds a limit to skip files not believed to be present  - in a specfied repository. -}
Locations.hs view
@@ -12,7 +12,7 @@ 	keyPath, 	gitAnnexLocation, 	gitAnnexMapping,-	gitAnnexCache,+	gitAnnexInodeCache, 	annexLocations, 	annexLocation, 	gitAnnexDir,@@ -123,8 +123,8 @@ {- File that caches information about a key's content, used to determine  - if a file has changed.  - Used in direct mode. -}-gitAnnexCache :: Key -> Git.Repo -> IO FilePath-gitAnnexCache key r  = do+gitAnnexInodeCache :: Key -> Git.Repo -> IO FilePath+gitAnnexInodeCache key r  = do 	loc <- gitAnnexLocation key r  	return $ loc ++ ".cache" 
Makefile view
@@ -6,14 +6,20 @@ # you can turn off some of these features. # # If you're using an old version of yesod, enable -DWITH_OLD_YESOD-FEATURES?=$(GIT_ANNEX_LOCAL_FEATURES) -DWITH_ASSISTANT -DWITH_S3 -DWITH_WEBDAV -DWITH_WEBAPP -DWITH_PAIRING -DWITH_XMPP -DWITH_DNS+FEATURES?=$(GIT_ANNEX_LOCAL_FEATURES) -DWITH_ASSISTANT -DWITH_S3 -DWITH_WEBDAV -DWITH_WEBAPP -DWITH_PAIRING -DWITH_XMPP -DWITH_DNS -DWITH_GLOB  bins=git-annex mans=git-annex.1 git-annex-shell.1 sources=Build/SysConfig.hs Utility/Touch.hs Utility/Mounts.hs all=$(bins) $(mans) docs -OS:=$(shell uname | sed 's/[-_].*//')+OS?=$(shell uname | sed 's/[-_].*//')+ifeq ($(OS),Android)+OPTFLAGS?=-DWITH_INOTIFY -DWITH_ANDROID+clibs=Utility/libdiskfree.o Utility/libmounts.o+CFLAGS:=-Wall -DWITH_ANDROID+THREADFLAGS=-threaded+else ifeq ($(OS),Linux) OPTFLAGS?=-DWITH_INOTIFY -DWITH_DBUS clibs=Utility/libdiskfree.o Utility/libmounts.o@@ -41,6 +47,7 @@ endif endif endif+endif  ALLFLAGS = $(BASEFLAGS) $(FEATURES) $(OPTFLAGS) $(THREADFLAGS) @@ -51,7 +58,8 @@ GHCFLAGS=-prof -auto-all -rtsopts -caf-all -fforce-recomp $(ALLFLAGS) endif -GHCMAKE=ghc $(GHCFLAGS) --make+GHC?=ghc+GHCMAKE=$(GHC) $(GHCFLAGS) --make  # Am I typing :make in vim? Do a fast build. ifdef VIM@@ -69,7 +77,7 @@  Build/SysConfig.hs: configure.hs Build/TestConfig.hs Build/Configure.hs 	$(GHCMAKE) configure-	./configure+	./configure $(OS)  %.hs: %.hsc 	hsc2hs $<@@ -113,7 +121,7 @@  testcoverage: 	rm -f test.tix test-	ghc $(GHCFLAGS) -outputdir $(GIT_ANNEX_TMP_BUILD_DIR)/testcoverage --make -fhpc test+	$(GHC) $(GHCFLAGS) -outputdir $(GIT_ANNEX_TMP_BUILD_DIR)/testcoverage --make -fhpc test 	./test 	@echo "" 	@hpc report test --exclude=Main --exclude=QC@@ -215,6 +223,40 @@ 		-volname git-annex -o tmp/git-annex.dmg 	rm -f tmp/git-annex.dmg.bz2 	bzip2 --fast tmp/git-annex.dmg++# Cross compile for Android binary.+# Uses https://github.com/neurocyte/ghc-android+#+# configure is run, probing the local system.+# So the Android should have all the same stuff that configure probes for,+# including the same version of git.+android:+	OS=Android $(MAKE) Build/SysConfig.hs+	GHC=$$HOME/.ghc/android-14/arm-linux-androideabi-4.7/bin/arm-unknown-linux-androideabi-ghc \+	CC=$$HOME/.ghc/android-14/arm-linux-androideabi-4.7/bin/arm-linux-androideabi-gcc \+	FEATURES="-DWITH_ANDROID -DWITH_ASSISTANT -DWITH_GLOB -DWITH_DNS" \+	OS=Android $(MAKE) fast++ANDROIDAPP_DEST=$(GIT_ANNEX_TMP_BUILD_DIR)/git-annex.android+androidapp:+	$(MAKE) android+	$(MAKE) -C standalone/android++	rm -rf "$(ANDROIDAPP_DEST)"+	install -d "$(ANDROIDAPP_DEST)"++	cp -aR standalone/android/git-annex-bundle "$(ANDROIDAPP_DEST)"+	cp -a standalone/android/runshell "$(ANDROIDAPP_DEST)"+	install -d "$(ANDROIDAPP_DEST)/git-annex-bundle/bin"+	cp git-annex "$(ANDROIDAPP_DEST)/git-annex-bundle/bin/"++	$$HOME/.ghc/android-14/arm-linux-androideabi-4.7/bin/arm-linux-androideabi-strip "$(ANDROIDAPP_DEST)"/git-annex-bundle/bin/*++	ln -sf git-annex "$(ANDROIDAPP_DEST)/git-annex-bundle/bin/git-annex-shell"+	zcat standalone/licences.gz > $(ANDROIDAPP_DEST)/git-annex-bundle/LICENSE+	install -d "$(ANDROIDAPP_DEST)/git-annex-bundle/templates"+	+	cd $(ANDROIDAPP_DEST) && tar czf ../git-annex-android.tar.gz .  # used by ./ghci getflags:
Remote/Directory.hs view
@@ -183,12 +183,14 @@ 		void $ tryIO $ removeDirectoryRecursive dest -- or not exist 		createDirectoryIfMissing True (parentDir dest) 		renameDirectory tmp dest-		mapM_ preventWrite =<< dirContents dest-		preventWrite dest+		-- may fail on some filesystems+		void $ tryIO $ do+			mapM_ preventWrite =<< dirContents dest+			preventWrite dest 	recorder f s = do 		void $ tryIO $ allowWrite f 		writeFile f s-		preventWrite f+		void $ tryIO $ preventWrite f  retrieve :: FilePath -> ChunkSize -> Key -> AssociatedFile -> FilePath -> Annex Bool retrieve d chunksize k _ f = metered Nothing k $ \meterupdate ->@@ -215,10 +217,11 @@ 	go _files = return False  remove :: FilePath -> Key -> Annex Bool-remove d k = liftIO $ catchBoolIO $ do-	allowWrite dir-	removeDirectoryRecursive dir-	return True+remove d k = liftIO $ do+	void $ tryIO $ allowWrite dir+	catchBoolIO $ do+		removeDirectoryRecursive dir+		return True   where 	dir = storeDir d k 
Remote/Rsync.hs view
@@ -20,6 +20,7 @@ import Remote.Helper.Encryptable import Crypto import Utility.Rsync+import Utility.CopyFile import Annex.Perms  type RsyncUrl = String@@ -101,14 +102,14 @@ 	f = keyFile k  store :: RsyncOpts -> Key -> AssociatedFile -> MeterUpdate -> Annex Bool-store o k _f p = sendAnnex k (void $ remove o k) $ rsyncSend o p k+store o k _f p = sendAnnex k (void $ remove o k) $ rsyncSend o p k False  storeEncrypted :: RsyncOpts -> (Cipher, Key) -> Key -> MeterUpdate -> Annex Bool storeEncrypted o (cipher, enck) k p = withTmp enck $ \tmp -> 	sendAnnex k (void $ remove o enck) $ \src -> do 		liftIO $ encrypt cipher (feedFile src) $ 			readBytes $ L.writeFile tmp-		rsyncSend o p enck tmp+		rsyncSend o p enck True tmp  retrieve :: RsyncOpts -> Key -> AssociatedFile -> FilePath -> Annex Bool retrieve o k _ f = untilTrue (rsyncUrls o k) $ \u -> rsyncRemote o Nothing@@ -207,16 +208,34 @@  {- To send a single key is slightly tricky; need to build up a temporary  - directory structure to pass to rsync so it can create the hash- - directories. -}-rsyncSend :: RsyncOpts -> MeterUpdate -> Key -> FilePath -> Annex Bool-rsyncSend o callback k src = withRsyncScratchDir $ \tmp -> do+ - directories.+ -+ - This would not be necessary if the hash directory structure used locally+ - was always the same as that used on the rsync remote. So if that's ever+ - unified, this gets nicer. Especially in the crippled filesystem case.+ - (When we have the right hash directory structure, we can just+ - pass --include=X --include=X/Y --include=X/Y/file --exclude=*)+ -}+rsyncSend :: RsyncOpts -> MeterUpdate -> Key -> Bool -> FilePath -> Annex Bool+rsyncSend o callback k canrename src = withRsyncScratchDir $ \tmp -> do 	let dest = tmp </> Prelude.head (keyPaths k) 	liftIO $ createDirectoryIfMissing True $ parentDir dest-	liftIO $ createLink src dest-	rsyncRemote o (Just callback)-		[ Param "--recursive"-		, partialParams-		-- tmp/ to send contents of tmp dir-		, Param $ addTrailingPathSeparator tmp-		, Param $ rsyncUrl o-		]+	ok <- if canrename+		then do+			liftIO $ renameFile src dest+			return True+		else ifM crippledFileSystem+			( liftIO $ copyFileExternal src dest+			, do+				liftIO $ createLink src dest+				return True+			)+	if ok+		then rsyncRemote o (Just callback)+			[ Param "--recursive"+			, partialParams+			-- tmp/ to send contents of tmp dir+			, Param $ addTrailingPathSeparator tmp+			, Param $ rsyncUrl o+			]+		else return False
Types/GitConfig.hs view
@@ -35,37 +35,41 @@ 	, annexHttpHeadersCommand :: Maybe String 	, annexAutoCommit :: Bool 	, annexWebOptions :: [String]+	, annexCrippledFileSystem :: Bool+	, coreSymlinks :: Bool 	}  extractGitConfig :: Git.Repo -> GitConfig extractGitConfig r = GitConfig-	{ annexVersion = notempty $ getmaybe "version"-	, annexNumCopies = get "numcopies" 1+	{ annexVersion = notempty $ getmaybe (annex "version")+	, annexNumCopies = get (annex "numcopies") 1 	, annexDiskReserve = fromMaybe onemegabyte $-		readSize dataUnits =<< getmaybe "diskreserve"-	, annexDirect = getbool "direct" False-	, annexBackends = getwords "backends"-	, annexQueueSize = getmayberead "queuesize"-	, annexBloomCapacity = getmayberead "bloomcapacity"-	, annexBloomAccuracy = getmayberead "bloomaccuracy"-	, annexSshCaching = getmaybebool "sshcaching"-	, annexAlwaysCommit = getbool "alwayscommit" True-	, annexDelayAdd = getmayberead "delayadd"-	, annexHttpHeaders = getlist "http-headers"-	, annexHttpHeadersCommand = getmaybe "http-headers-command"-	, annexAutoCommit = getbool "autocommit" True-	, annexWebOptions = getwords "web-options"+		readSize dataUnits =<< getmaybe (annex "diskreserve")+	, annexDirect = getbool (annex "direct") False+	, annexBackends = getwords (annex "backends")+	, annexQueueSize = getmayberead (annex "queuesize")+	, annexBloomCapacity = getmayberead (annex "bloomcapacity")+	, annexBloomAccuracy = getmayberead (annex "bloomaccuracy")+	, annexSshCaching = getmaybebool (annex "sshcaching")+	, annexAlwaysCommit = getbool (annex "alwayscommit") True+	, annexDelayAdd = getmayberead (annex "delayadd")+	, annexHttpHeaders = getlist (annex "http-headers")+	, annexHttpHeadersCommand = getmaybe (annex "http-headers-command")+	, annexAutoCommit = getbool (annex "autocommit") True+	, annexWebOptions = getwords (annex "web-options")+	, annexCrippledFileSystem = getbool (annex "crippledfilesystem") False+	, coreSymlinks = getbool "core.symlinks" True 	}   where 	get k def = fromMaybe def $ getmayberead k 	getbool k def = fromMaybe def $ getmaybebool k 	getmaybebool k = Git.Config.isTrue =<< getmaybe k 	getmayberead k = readish =<< getmaybe k-	getmaybe k = Git.Config.getMaybe (key k) r-	getlist k = Git.Config.getList (key k) r+	getmaybe k = Git.Config.getMaybe k r+	getlist k = Git.Config.getList k r 	getwords k = fromMaybe [] $ words <$> getmaybe k -	key k = "annex." ++ k+	annex k = "annex." ++ k 			 	onemegabyte = 1000000 
Types/KeySource.hs view
@@ -7,16 +7,23 @@  module Types.KeySource where +import Utility.InodeCache+ {- When content is in the process of being added to the annex,  - and a Key generated from it, this data type is used.   -  - The contentLocation may be different from the filename  - associated with the key. For example, the add command- - temporarily puts the content into a lockdown directory+ - may temporarily hard link the content into a lockdown directory  - for checking. The migrate command uses the content- - of a different Key. -}+ - of a different Key.+ -+ - The inodeCache can be used to detect some types of modifications to+ - files that may be made while they're in the process of being added.+ -} data KeySource = KeySource 	{ keyFilename :: FilePath 	, contentLocation :: FilePath+	, inodeCache :: Maybe InodeCache 	} 	deriving (Show)
+ Utility/InodeCache.hs view
@@ -0,0 +1,50 @@+{- Caching a file's inode, size, and modification time to see when it's changed.+ -+ - Copyright 2013 Joey Hess <joey@kitenet.net>+ -+ - Licensed under the GNU GPL version 3 or higher.+ -}++module Utility.InodeCache where++import Common+import System.Posix.Types++data InodeCache = InodeCache FileID FileOffset EpochTime+	deriving (Eq, Show)++showInodeCache :: InodeCache -> String+showInodeCache (InodeCache inode size mtime) = unwords+	[ show inode+	, show size+	, show mtime+	]++readInodeCache :: String -> Maybe InodeCache+readInodeCache s = case words s of+	(inode:size:mtime:_) -> InodeCache+		<$> readish inode+		<*> readish size+		<*> readish mtime+	_ -> Nothing++-- for quickcheck+prop_read_show_inodecache :: InodeCache -> Bool+prop_read_show_inodecache c = readInodeCache (showInodeCache c) == Just c++genInodeCache :: FilePath -> IO (Maybe InodeCache)+genInodeCache f = catchDefaultIO Nothing $ toInodeCache <$> getFileStatus f++toInodeCache :: FileStatus -> Maybe InodeCache+toInodeCache s+	| isRegularFile s = Just $ InodeCache+		(fileID s)+		(fileSize s)+		(modificationTime s)+	| otherwise = Nothing++{- Compares an inode cache with the current inode of file. -}+compareInodeCache :: FilePath -> Maybe InodeCache -> IO Bool+compareInodeCache file old = do+	curr <- genInodeCache file+	return $ isJust curr && curr == old
Utility/Lsof.hs view
@@ -5,7 +5,7 @@  - Licensed under the GNU GPL version 3 or higher.  -} -{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE BangPatterns, CPP #-}  module Utility.Lsof where @@ -52,6 +52,15 @@   where 	p = proc "lsof" ("-F0can" : opts) +type LsofParser = String -> [(FilePath, LsofOpenMode, ProcessInfo)]++parse :: LsofParser+#ifdef WITH_ANDROID+parse = parseDefault+#else+parse = parseFormatted+#endif+ {- Parsing null-delimited output like:  -  - pPID\0cCMDLINE\0@@ -62,8 +71,8 @@  - Where each new process block is started by a pid, and a process can  - have multiple files open.  -}-parse :: String -> [(FilePath, LsofOpenMode, ProcessInfo)]-parse s = bundle $ go [] $ lines s+parseFormatted :: LsofParser+parseFormatted s = bundle $ go [] $ lines s   where 	bundle = concatMap (\(fs, p) -> map (\(f, m) -> (f, m, p)) fs) @@ -97,3 +106,14 @@ 	splitnull = split "\0"  	parsefail = error $ "failed to parse lsof output: " ++ show s++{- Parses lsof's default output format. -}+parseDefault :: LsofParser+parseDefault = catMaybes . map parseline . drop 1 . lines+  where+	parseline l = case words l of+		(command : spid : _user : _fd : _type : _device : _size : _node : rest) -> +			case readish spid of+				Nothing -> Nothing+				Just pid -> Just (unwords rest, OpenUnknown, ProcessInfo pid command)+		_ -> Nothing
Utility/SafeCommand.hs view
@@ -85,3 +85,20 @@ prop_idempotent_shellEscape s = [s] == (shellUnEscape . shellEscape) s prop_idempotent_shellEscape_multiword :: [String] -> Bool prop_idempotent_shellEscape_multiword s = s == (shellUnEscape . unwords . map shellEscape) s++{- Segements a list of filenames into groups that are all below the manximum+ - command-line length limit. Does not preserve order. -}+segmentXargs :: [FilePath] -> [[FilePath]]+segmentXargs l = go l [] 0 []+  where+	go [] c _ r = c:r+	go (f:fs) c accumlen r+		| len < maxlen && newlen > maxlen = go (f:fs) [] 0 (c:r)+		| otherwise = go fs (f:c) newlen r+	  where+		len = length f+		newlen = accumlen + len++	{- 10k of filenames per command, well under Linux's 20k limit;+	 - allows room for other parameters etc. -}+	maxlen = 10240
+ Utility/Shell.hs view
@@ -0,0 +1,20 @@+{- /bin/sh handling+ -+ - Copyright 2013 Joey Hess <joey@kitenet.net>+ -+ - Licensed under the GNU GPL version 3 or higher.+ -}++{-# LANGUAGE CPP #-}++module Utility.Shell where++shellPath :: FilePath+#ifndef WITH_ANDROID+shellPath = "/bin/sh"+#else+shellPath = "/system/bin/sh"+#endif++shebang :: String+shebang = "#!" ++ shellPath
Utility/ThreadScheduler.hs view
@@ -6,13 +6,17 @@  - Licensed under the GNU GPL version 3 or higher.  -} +{-# LANGUAGE CPP #-}+ module Utility.ThreadScheduler where  import Common  import Control.Concurrent-import System.Posix.Terminal import System.Posix.Signals+#ifndef WITH_ANDROID+import System.Posix.Terminal+#endif  newtype Seconds = Seconds { fromSeconds :: Int } 	deriving (Eq, Ord, Show)@@ -49,8 +53,10 @@ waitForTermination = do 	lock <- newEmptyMVar 	check softwareTermination lock+#ifndef WITH_ANDROID 	whenM (queryTerminal stdInput) $ 		check keyboardSignal lock+#endif 	takeMVar lock   where 	check sig lock = void $
Utility/libdiskfree.c view
@@ -22,6 +22,10 @@ # define STATCALL statfs /* statfs64 not yet tested on a real FreeBSD machine */ # define STATSTRUCT statfs #else+#if defined WITH_ANDROID+# warning free space checking code not available for Android+# define UNKNOWN+#else #if defined (__linux__) || defined (__FreeBSD_kernel__) /* Linux or Debian kFreeBSD */ /* This is a POSIX standard, so might also work elsewhere too. */@@ -31,6 +35,7 @@ #else # warning free space checking code not available for this OS # define UNKNOWN+#endif #endif #endif #endif
Utility/libmounts.h view
@@ -5,6 +5,10 @@ # include <sys/mount.h> # define GETMNTINFO #else+#if defined WITH_ANDROID+# warning mounts listing code not available for Android+# define UNKNOWN+#else #if defined (__linux__) || defined (__FreeBSD_kernel__) /* Linux or Debian kFreeBSD */ #include <mntent.h>@@ -12,6 +16,7 @@ #else # warning mounts listing code not available for this OS # define UNKNOWN+#endif #endif #endif 
debian/changelog view
@@ -1,3 +1,32 @@+git-annex (3.20130217) UNRELEASED; urgency=low++  * Should now fully support git repositories with core.symlinks=false;+    always using git's pseudosymlink files in such repositories.+  * webapp: Allow creating repositories on filesystems that lack support for+    symlinks.++ -- Joey Hess <joeyh@debian.org>  Sun, 17 Feb 2013 16:42:16 -0400++git-annex (3.20130216) unstable; urgency=low++  * Now uses the Haskell uuid library, rather than needing a uuid program.+  * Now uses the Haskell Glob library, rather than pcre-light, avoiding+    the need to install libpcre. Currently done only for Cabal or when+    the Makefile is made to use -DWITH_GLOB+  * Android port now available (command-line only).+  * New annex.crippledfilesystem setting, allows use of git-annex+    repositories on FAT and even worse filesystems; avoiding use of+    hard links and locked down permissions settings. (Support is incomplete.)+  * init: Detect when the repository is on a filesystem that does not+    support hard links, or symlinks, or unix permissions, and set+    annex.crippledfilesystem, as well as annex.direct.+  * add: Improved detection of files that are modified while being added.+  * Fix a bug in direct mode, introduced in the previous release, where+    if a file was dropped and then got back, it would be stored in indirect+    mode.++ -- Joey Hess <joeyh@debian.org>  Sat, 16 Feb 2013 10:03:26 -0400+ git-annex (3.20130207) unstable; urgency=low    * webapp: Now allows restarting any threads that crash.
debian/control view
@@ -17,6 +17,7 @@ 	libghc-quickcheck2-dev, 	libghc-monad-control-dev (>= 0.3), 	libghc-lifted-base-dev,+	libghc-uuid-dev, 	libghc-json-dev, 	libghc-ifelse-dev, 	libghc-bloomfilter-dev,
debian/rules view
@@ -12,6 +12,12 @@ %: 	dh $@ +# Builds standalone tarball with the same FEATURES as debian package.+standalone:+	$(MAKE) linuxstandalone+ # Not intended for use by anyone except the author. announcedir: 	@echo ${HOME}/src/git-annex/doc/news++.PHONY: standalone
doc/assistant/release_notes.mdwn view
@@ -1,9 +1,24 @@-## 3.20130124+## version 3.20130216 -This is primarily a bugfix release.+This adds a port to Android. Only usable at the command line so far;+beta qualitty. -## version 3.20130107, 3.20130114+Also a bugfix release, and improves support for FAT. +The following are known limitations of this release of the git-annex+assistant:++* No Android app yet.+* On BSD operating systems (but not on OS X), the assistant uses kqueue to+  watch files. Kqueue has to open every directory it watches, so too many+  directories will run it out of the max number of open files (typically+  1024), and fail. See [[this_bug|bugs/Issue_on_OSX_with_some_system_limits]]+  for a workaround.+* Also on systems with kqueue, modifications to existing files in direct+  mode will not be noticed.++## version 3.20130107, 3.20130114, 3.20130124, 3.20130207+ These are bugfix releases.  ## version 3.20130102@@ -16,20 +31,6 @@ your changes. Direct mode is the default for new repositories created by the assistant. To convert your existing repository to use direct mode, manually run `git annex direct` inside the repository.--The following are known limitations of this release of the git-annex-assistant:--* If a file in a direct mode repository is modified as it's being transferred,-  the old version of the file can be lost, and fsck will later complain-  about a corrupt object.-* On BSD operating systems (but not on OS X), the assistant uses kqueue to-  watch files. Kqueue has to open every directory it watches, so too many-  directories will run it out of the max number of open files (typically-  1024), and fail. See [[this_bug|bugs/Issue_on_OSX_with_some_system_limits]]-  for a workaround.-* Also on systems with kqueue, modifications to existing files in direct-  mode will not be noticed.  ## version 3.20121211 
− doc/bugs/3.20121113_build_error___39__not_in_scope_getAddBoxComR__39__.mdwn
@@ -1,33 +0,0 @@-What steps will reproduce the problem?--Building from latest source, Cabal update, cabal install --only dependencies, cabal configure, Cabal build--What is the expected output? What do you see instead?--Error message from build--...--Loading package DAV-0.2 ... linking ... done.--Loading object (static) dist/build/git-annex/git-annex-tmp/Utility/libdiskfree.o ... done--Loading object (static) dist/build/git-annex/git-annex-tmp/Utility/libmounts.o ... done--final link ... done---Assistant/Threads/WebApp.hs:47:1: Not in scope: `getAddBoxComR'--Assistant/Threads/WebApp.hs:47:1: Not in scope: `getEnableWebDAVR'---What version of git-annex are you using? On what operating system?--Latest version via git from git-annex.branchable.com--Debian Squeeze (6.0.6)--Please provide any additional information below.--> I noticed this earlier and fixed it. [[done]] --[[Joey]]
− doc/bugs/Is_there_any_way_to_rate_limit_uploads_to_an_S3_backend__63__.mdwn
@@ -1,19 +0,0 @@-What steps will reproduce the problem?--Adding files to a local annex set up to sync to a remote S3 one---What is the expected output? What do you see instead?--It syncs, but maxes out the uplink---What version of git-annex are you using? On what operating system?--3.20121112 on Debian testing---Please provide any additional information below.--The man page lists how to configure rate limiting for rsync, not sure how to do it for this-
− doc/bugs/Lost_S3_Remote/comment_1_6e80e6db6671581d471fc9a54181c04c._comment
@@ -1,10 +0,0 @@-[[!comment format=mdwn- username="http://joey.kitenet.net/"- nickname="joey"- subject="comment 1"- date="2012-01-06T03:04:35Z"- content="""-Despite `status` listing S3 support, your git-annex is actually built with S3stub, probably because it failed to find the necessary S3 module at build time. Rebuild git-annex and watch closely, you'll see \"** building without S3 support\". Look above that for the error and fix it.--It was certianly a bug that it showed S3 as supported when built without it. I've fixed that.-"""]]
− doc/bugs/Lost_S3_Remote/comment_2_c99c65882a3924f4890e500f9492b442._comment
@@ -1,8 +0,0 @@-[[!comment format=mdwn- username="http://joey.kitenet.net/"- nickname="joey"- subject="comment 2"- date="2012-01-06T03:08:28Z"- content="""-BTW, you'll want to \"make clean\", since the S3stub hack symlinks a file into place and it will continue building with S3stub even if you fix the problem until you clean.-"""]]
− doc/bugs/Lost_S3_Remote/comment_3_1e434d5a20a692cd9dc7f6f8f20f30dd._comment
@@ -1,8 +0,0 @@-[[!comment format=mdwn- username="https://www.google.com/accounts/o8/id?id=AItOawkey8WuXUh_x5JC2c9_it1CYRnVTgdGu1M"- nickname="Dustin"- subject="Thank you!"- date="2012-01-06T03:38:27Z"- content="""-make clean and rebuild worked...  Thank you-"""]]
− doc/bugs/More_sync__39__ing_weirdness_with_the_assistant_branch_on_OSX.mdwn
@@ -1,15 +0,0 @@-Running the 'assistant' branch, I occassionally get--To myhost1:/Users/jtang/annex- ! [rejected]        master -> synced/master (non-fast-forward)-error: failed to push some refs to 'myhost1:/Users/jtang/annex'-hint: Updates were rejected because a pushed branch tip is behind its remote-hint: counterpart. Check out this branch and merge the remote changes-hint: (e.g. 'git pull') before pushing again.-hint: See the 'Note about fast-forwards' in 'git push --help' for details.-(Recording state in git...)--manually running a 'git annex sync' usually fixes it, I guess once the sync command runs periodically this problem will go away, is this even OSX specific? I don't quite get the behaviour that is described in [[design/assistant/blog/day_15__its_aliiive]].--> With my changes today, I've seen it successfully recover from this-> situation. [[done]] --[[Joey]] 
− doc/bugs/OSX_app_issues/comment_10_54d8f3e429df9a9958370635c890abf0._comment
@@ -1,11 +0,0 @@-[[!comment format=mdwn- username="http://joeyh.name/"- ip="4.154.3.194"- subject="comment 10"- date="2013-01-19T16:13:20Z"- content="""-The app uses the version of git included in it, because using the system's installed version if there is one is likely to run into other version incompatabilities. --You can either install git-annex using cabal and homebrew, as documented, or you could go in and delete-all the git programs out of the app, and then it'd use the system's git stuff instead.-"""]]
− doc/bugs/OSX_app_issues/comment_11_bb2ceb95a844449795addee6986d0763._comment
@@ -1,26 +0,0 @@-[[!comment format=mdwn- username="https://www.google.com/accounts/o8/id?id=AItOawlYy4BrJyV1PdfqzevCVziXRp89iUH6Xzw"- nickname="Christopher"- subject="Code signing errors in log on starting git-annex.app"- date="2013-01-19T22:30:32Z"- content="""-When I run via the App and set up a fresh repo, i get some Console.app spam (looks like one per file added to the repo dir... or maybe one per git command?):--    2013-01-19 2:44:55.000 PM kernel[0]: CODE SIGNING: cs_invalid_page(0x1008b4000): p=73995[git] clearing CS_VALID-    2013-01-19 2:44:55.000 PM kernel[0]: CODE SIGNING: cs_invalid_page(0x10f99e000): p=73996[git] clearing CS_VALID-    2013-01-19 2:44:55.000 PM kernel[0]: CODE SIGNING: cs_invalid_page(0x102b44000): p=73997[git] clearing CS_VALID-    2013-01-19 2:44:55.000 PM kernel[0]: CODE SIGNING: cs_invalid_page(0x1029f4000): p=73998[git] clearing CS_VALID-    ...--and nothing seems to work. The page address and the pid increment steadily with each line.  I'm using 10.8.2 (12C60) on a Mac Pro, and grabbed:--     /git-annex/OSX/current/10.8.2_Mountain_Lion/git-annex.dmg.bz2	--(published 14-Jan-2013 15:19)--It seems to be a code signing issue, perhaps with the vendored git binaries. While things are sort-of working, the web app shows the files flying by really fast. --Using a fresh repo via `git annex webapp` works great (I built that after much teeth-knashing, brew install/link cycles, and then cabal install git-annex). --I am very excited for this to work, this is exactly what I've been waiting for to replace dropbox. Came very close to writing it myself a few times (and in Haskell no less!!). -"""]]
− doc/bugs/OSX_app_issues/comment_12_f3bc5a4e4895ac9351786f0bdd8005ba._comment
@@ -1,11 +0,0 @@-[[!comment format=mdwn- username="https://www.google.com/accounts/o8/id?id=AItOawmYiJgOvC4IDYkr2KIjMlfVD9r_1Sij_jY"- nickname="Douglas"- subject="Error creating remote repository using ssh on OSX"- date="2013-01-25T13:18:40Z"- content="""-There is an issue with creating remote repositories using ssh (the problem may require using a different account name.) I filed the following bug:---<http://git-annex.branchable.com/bugs/Error_creating_remote_repository_using_ssh_on_OSX/>-"""]]
− doc/bugs/OSX_app_issues/comment_2_fd560811c57df5cbc3976639642b8b19._comment
@@ -1,8 +0,0 @@-[[!comment format=mdwn- username="https://www.google.com/accounts/o8/id?id=AItOawkN91jAhoesnVI9TtWANaBPaYjd1V9Pag8"- nickname="Benjamin"- subject="Package for older OS X"- date="2012-11-17T12:36:45Z"- content="""-Is there an option to provide application bundle for older versions of OS X? The last time I tried the bundle wouldn't work under 10.5. If no specific features from newer OS X versions are required, it could be enough to add a simple switch when building.-"""]]
− doc/bugs/OSX_app_issues/comment_4_4cda124b57ddc87645d5822f14ed5c59._comment
@@ -1,8 +0,0 @@-[[!comment format=mdwn- username="https://www.google.com/accounts/o8/id?id=AItOawkBTVYS5lTecuenAB01eHgfUxE20vWVpU4"- nickname="Peng"- subject="Large Mountain Loin package size"- date="2012-12-28T22:17:43Z"- content="""-I see that git-annex package file is 489.9MB on Mac Mountain Loin (git-annex.dmg.bz2). The file git-annex.dmg.bz2 is only of size 24M. Is there any way to reduce the package size?-"""]]
− doc/bugs/OSX_app_issues/comment_5_0d1df34f83a8dac9c438d93806236818._comment
@@ -1,8 +0,0 @@-[[!comment format=mdwn- username="http://joeyh.name/"- ip="2001:4978:f:21a::2"- subject="comment 5"- date="2013-01-02T19:52:28Z"- content="""-The build for today's release is 24 mb.-"""]]
− doc/bugs/OSX_app_issues/comment_6_bc44d5aea5f77e331a32913ada293730._comment
@@ -1,27 +0,0 @@-[[!comment format=mdwn- username="https://www.jsilence.org/"- nickname="jsilence"- subject="Setting up a repository fails on OSX 10.6"- date="2013-01-05T11:17:18Z"- content="""-I installed Haskell via MacPorts and managed to compile git-annex as described via cabal.--On the initial start, git-annex webapp starts just fine and the webapp opens in the browser. When I try to configure a local repository, the webapp crashes.--    1 jsilence@zeo ~ % git-annex webapp-    (Recording state in git...)-    WebApp crashed: watch mode is not available on this system-    -    Launching web browser on file:///var/folders/6b/6bWnFAnbFXSPCLPvCnKNrE+++TI/-Tmp-/webapp1003.html-    jsilence@zeo ~ % --\"watch mode is not suported\" suggests that lsof is not in the PATH. lsof resides in /usr/sbin and can be found just fine:--    jsilence@zeo ~ % which lsof-    /usr/sbin/lsof--Any help would be appreciated.---jsl--"""]]
− doc/bugs/OSX_app_issues/comment_7_93e0bb53ac2d7daef53426fbdc5f92d9._comment
@@ -1,15 +0,0 @@-[[!comment format=mdwn- username="https://www.google.com/accounts/o8/id?id=AItOawkurjhi0CRJvgm7QNaZDWS9hitBtavqIpc"- nickname="Bret"- subject="git-annex.app Not working on 32 bit machines"- date="2012-11-03T19:18:47Z"- content="""-I tried running the git-annex.app on my Core Duo Macbook pro, and it does not run at all.  I get an error on my system.log--`Nov  3 12:13:26 Bret-Mac [0x0-0x15015].com.branchable.git-annex[155]: /Applications/git-annex.app/Contents/MacOS/runshell: line 52: /Applications/git-annex.app/Contents/MacOS/bin/git-annex: Bad CPU type in executable-Nov  3 12:13:26 Bret-Mac com.apple.launchd.peruser.501[92] ([0x0-0x15015].com.branchable.git-annex[155]): Exited with exit code: 1`--It works on my 64 bit machine, and this has become quite the problem for a while now, where people with newer macs dont compile back for a 32bit machine.  --Is there any hope for a pre-compiled binary that works on a 32 bit machine?-"""]]
− doc/bugs/OSX_app_issues/comment_7_acd73cc5c4caa88099e2d2f19947aadf._comment
@@ -1,8 +0,0 @@-[[!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/bugs/OSX_app_issues/comment_8_141eac2f3fb25fe18b4268786f00ad6a._comment
@@ -1,8 +0,0 @@-[[!comment format=mdwn- username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"- nickname="Jimmy"- subject="comment 8"- date="2012-11-07T16:08:00Z"- content="""-I've been updating my haskell platform install recently, i used to try and get the builder to spit out 32/64bit binaries, but recently it's just become too messy, I've just migrated to a full 64bit build system. I'm afraid I won't be able to  provide 32bit builds any more.-"""]]
− doc/bugs/OSX_app_issues/comment_8_f4d5b2645d7f29b80925159efb94a998._comment
@@ -1,8 +0,0 @@-[[!comment format=mdwn- username="https://www.google.com/accounts/o8/id?id=AItOawmOsimKUgz6rxpmsS_nrBQGavEYyUpDlsE"- nickname="Tim"- subject="OS X 10.8.2"- date="2013-01-11T00:07:54Z"- content="""-Double click on the app, give permission for it to run and ... nothing-"""]]
− doc/bugs/OSX_app_issues/comment_9_2e6dfca0fd8df04066769653724eae28._comment
@@ -1,17 +0,0 @@-[[!comment format=mdwn- username="https://www.google.com/accounts/o8/id?id=AItOawmRFKwny4rArBaz-36xTcsJYqKIgdDaw5Q"- nickname="Andrew"- subject="Prefer the system/path git binaries if they're a newer version"- date="2013-01-19T06:20:38Z"- content="""-I have used homebrew to install git v1.8.0.2 but git-annex.app packages git v1.7.10.2. git 1.7 crashes due to some newer directives in my global git config.--    error: Malformed value for push.default: simple-    error: Must be one of nothing, matching, tracking or current.-    fatal: bad config file line 38 in /Users/akraut/.gitconfig-    -    git-annex: fd:13: hGetLine: end of file-    failed-    git-annex: webapp: 1 failed--"""]]
− doc/bugs/Switching_from_indirect_mode_to_direct_mode_breaks_duplicates.mdwn
@@ -1,30 +0,0 @@-#What steps will reproduce the problem?--1. Create a new repository in indirect mode.--2. Add the same file twice under a different name. Now you have two symlinks pointing to the same file under .git/annex/objects/--3. Switch to direct mode. The first symlink gets replaced by the actual file. The second stays unchanged, pointing to nowhere. But git annex whereis still reports it has a copy.--4. Delete the first file. Git annex whereis still thinks it has a copy of file 2, which is not true -> data loss.--#What is the expected output? What do you see instead?--When switching to direct mode, both symlinks should be replaced by a copy (or at least a hardlink) of the actual file.--> The typo that caused this bug is fixed. --[[Joey]] --#What version of git-annex are you using? On what operating system?--3.20130107 on Arch Linux x64--#Please provide any additional information below.--The deduplication performed by git-annex is very dangerous in itself-because files with identical content become replaced by references to the-same file without the user necessarily being aware. Think of the user-making a copy of a file, than modifying it. He would expect to end up with-two files, the unchanged original and the modified copy. But what he really-gets is two symlinks pointing to the same modified file.--> I agree, it now copies rather than hard linking.  [[done]] --[[Joey]] 
+ doc/bugs/Unknown_remote_type_webdav.mdwn view
@@ -0,0 +1,8 @@+When I attempt to setup a [box.com special remote](http://git-annex.branchable.com/tips/using_box.com_as_a_special_remote/) I get the following error:++    git-annex: Unknown remote type webdav++I'm using the Linux prebuilt tarball. Does it not include webdav support?++> The amd64 standalone tarball was indeed built without it for the last+> release. Fixed that. [[done]] --[[Joey]]
+ doc/bugs/WebDAV_HandshakeFailed_.mdwn view
@@ -0,0 +1,5 @@+When I attempt to add a Box.com special remote to my annex I get the following error:++    git-annex: HandshakeFailed (Error_Protocol ("certificate rejected: certificate is not allowed to sign another certificate",True,CertificateUnknown))++Running git-annex version: 3.20130207
+ doc/bugs/assistant_does_not_list_remote___39__origin__39__.mdwn view
@@ -0,0 +1,22 @@+What steps will reproduce the problem?++1. create a git annex repo on a server+2. clone it on workstation+3. open the webapp on the workstation+++What is the expected output? What do you see instead?++The webapp should show the 'origin' remote and the assistant should ensure syncing.+Instead the remote does not show up in the webapp.+I checked with `git annex status` and the remote is there.++What version of git-annex are you using? On what operating system?++3.20130207 on latest Ubuntu++Please provide any additional information below.++I tried both with direct and indirect mode for the local annex repo.++I am sorry if I am missing the point. I checked the docs, however without much success.
doc/bugs/dropunused_doesn__39__t_work_in_my_case__63__.mdwn view
@@ -57,5 +57,14 @@ git-annex: 3.20130124 Debian: sid 2013-02-01 -> unused being confused by stale data left when switching from direct mode.-> I've made this be cleaned up. [[done]] --[[Joey]]+> I put a fix in for this in 57780cb3a4dfe1292b72e1412ec4d2a70b6d04ce +> but it was buggy and I had to revert it.+> +> The bug is caused by direct mode cache and mapping info.+> This makes getKeysPresent find keys that are not present.+> It would be expensive to make getKeysPresent check that the+> actual key files are present (it just lists the directories). +> But this seems to be needed, since direct mode can leave+> cache and mapping files behind. --[[Joey]]++>> Now fixed properly. [[done]] --[[Joey]]
− doc/bugs/git-annex_has_issues_with_git_when_staging__47__commiting_logs.mdwn
@@ -1,34 +0,0 @@-After a series of pretty convoluted copying files around between annex'd repos and pulling changes around between repos. I noticed that occassionally when git-annex tries to stage files (the `.git-annex/*/*/*logs`) git some times gets wedged and doing a "git commit -a" doesn't seem to work or files might not get added thus leaving a bunch of untracked files or modified files that aren't staged for a commit.--I tried running a *`git rm --cached -f -r *`* then *git add -u .git-annex/* or the usual *git add* then a commit fixes things for me. If I don't do that then my subsequent merges/pulls will fail and result in *no known copies of files* I suspect git-annex might have just touched some file modes and git picked up the changes but got confused since there was no content change. It might also just be a git on OSX thing and it doesn't affect linux/bsd users.--For now it's just a bit of extra work for me when it does occur but it does not seem to occur often.--> What do you mean when you say that git "got wedged"? It hung somehow?->-> If git-annex runs concurrently with another git command that locks-> the repository, its git add of log files can fail.-> -> Update: Also, of course, if you are running a "got annex get" or-> similar, and ctrl-c it after it has gotten some files, it can-> end up with unstaged or in some cases un-added log files that git-annex-> wrote -- since git-annex only stages log files in git on shutdown, and-> ctrl-c bypasses that.-> --[[Joey]] -->> It "got wedged" as in git doesn't let me commit anything, even though it tells me that there is stuff to be committed in the staging area.-->>> I've never seen git refuse to commit staged files. There would have to->>> be some error message? --[[Joey]] -->>>> there were no error messages at all-->>>>> Can I see a transcript? I'm having difficulty getting my head around->>>>> what git is doing. Sounds like the files could just not be `git->>>>> added` yet, but I get the impression from other things that you say->>>>> that it's not so simple. --[[Joey]] --This turns out to be a bug in git, and I have posted a bug report on the mailing list.-The git-annex behavior that causes this situation is being handled as-another bug, [[git-annex directory hashing problems on osx]].-So, closing this bug report. [[done]] --[[Joey]]
− doc/bugs/git_annex_gets_confused_about_remotes_with_dots_in_their_names.mdwn
@@ -1,34 +0,0 @@-For test.com//test, I get this:--    % git annex copy . --to test.com//test-    (getting UUID for test...) git-annex: there is no git remote named "test.com//test"--And my .git/config changes from--    [remote "test.com//test"]-    	url = richih@test.com:/test-    	fetch = +refs/heads/*:refs/remotes/test.com//test/*--to--    [remote "test.com//test"]-    	url = richih@test.com:/test-    	fetch = +refs/heads/*:refs/remotes/test.com//test/*-    	annex-uuid = xyz-    [remote "test"]-    	annex-uuid = xyz---Unless I am misunderstanding something, git annex gets confused about what the name of the remote it supposed to be, truncates at the dot for some operations and uses the full name for others.--> I've fixed this bug. [[done]]-> -> However, using "/" in a remote name seems likely to me to confuse -> git's own remote branch handling. Although I've never tried it.-> --[[Joey]] -->> From what I can see, git handles / just fine, but would get upset about : which is why it's not allowed in a remote's name.->> My naming scheme is host//path/to/annex. It sorts nicely and gives all important information left to right with the most specific parts at the beginning and end.->> If you have any other ideas or scheme, I am all ears :)->> Either way, thanks for fixing this so quickly.->> -- RichiH
− doc/bugs/git_defunct_processes___40__child_of_git-annex_assistant__41__.mdwn
@@ -1,34 +0,0 @@-What steps will reproduce the problem?--run git annex assistant, add a file, which is picked up and pushed by the assistant.  --What is the expected output? What do you see instead?--a ps -ef shows a large number of defunct git processes.. for example:-<pre>-nelg      9622     1  0 02:01 ?        00:00:01 git-annex assistant-nelg      9637  9622  0 02:01 ?        00:00:00 git --git-dir=/home/nelg/Downloads/test2/.git --work-tree=/home/nelg/Downloads/test2 cat-file --batch-nelg     12080  9622  0 02:19 ?        00:00:00 [git] &lt;defunct&gt;-nelg     12082  9622  0 02:19 ?        00:00:00 [git] &lt;defunct&gt;-nelg     12083  9622  0 02:19 ?        00:00:00 [git] &lt;defunct&gt;-nelg     12084  9622  0 02:19 ?        00:00:00 [git] &lt;defunct&gt;-------</pre>--What version of git-annex are you using? On what operating system?--Compiled git annex from git (cbcd208d158f8e42dda03a5eeaf1bac21045a140), on Mandriva 2010.2, 32 bit, using ghc-7.4.1.- git version 1.7.1---Please provide any additional information below.--I also found that the version of git I have does not support the option: --allow-empty-message-So, suggest that if the version of git installed is an older version, that the params in  Assistant/Threads/Committer.hs-are changed to  [ Param "-m", Param "git assistant".... or something like that.--I have done this on my copy for testing it.--For testing, I am also using two repositories on the same computer.  I set this up from the command line, as the web app does not seem to support syncing to two different git folders on the same computer.--> [[done]]; all zombies are squelched now in the assistant. --[[Joey]]
+ doc/bugs/missing_dependency_in_git-annex-3.20130216.mdwn view
@@ -0,0 +1,29 @@+What steps will reproduce the problem?++build git-annex-3.20130216 on OS X lion+++What is the expected output? What do you see instead?++successful compile; error was:++```+Annex/UUID.hs:30:8:+    Could not find module `System.Random'+    It is a member of the hidden package `random-1.0.1.1'.+    Perhaps you need to add `random' to the build-depends in your .cabal file.+    Use -v to see a list of the files searched for.+```+++What version of git-annex are you using? On what operating system?++building git-annex-3.20130216 on OS X Lion+++Please provide any additional information below.+++adding 'random' to the BuildDepends in git-annex.cabal does indeed fix the error.++> [[done]] --[[Joey]] 
− doc/bugs/wishlist:_more_descriptive_commit_messages_in_git-annex_branch.mdwn
@@ -1,39 +0,0 @@-as of git-annex version 3.20110719, all git-annex commits only contain the word "update" as a commit message. given that the contents of the commit are pretty non-descriptive (SHA1 hashes for file names, uuids for repository names), i suggest to have more descriptive commit messages, as shown here:--    /mnt/usb_disk/photos/2011$ git annex get-    /mnt/usb_disk/photos/2011$ git show git-annex-    [...]-    usb-disk-photos: get 2011-    -    * 10 files retrieved from 2 sources (9 from local-harddisk, 1 from my-server)-    * 120 files were already present-    * 2 files could not be retrieved-    /mnt/usb_disk/photos/2011$ cd ~/photos/2011/07-    ~/photos/2011/07$ git copy --to my-server-    ~/photos/2011/07$ git show git-annex-    [...]-    local-harddisk: copy 2011/07 to my-server-    -    * 20 files pushed-    ~/photos/2011/07$--in my opinion, the messages should at least contain--* what command was used-* in which repository they were executed-* which files or directories they affected (not necessarily all files, but what was given on command line or implicitly from the working directory)----[[chrysn]]--> The implementation of the git-annex branch precludes more descriptive-> commit messages, since a single commit can include changes that were-> previously staged to the branch's index file, or spooled to its journal-> by other git-annex commands (either concurrently running or-> interrupted commands, or even changes needed to automatically merge-> other git-annex branches).-> -> It would be possible to make it *less* verbose, with an empty commit-> message. :) --[[Joey]] -->> Closing as this is literally impossible to do without making->> git-annex worse. [[done]] --[[Joey]] 
doc/design/assistant.mdwn view
@@ -11,11 +11,11 @@ * Month 4 "cloud": [[!traillink cloud]] [[!traillink transfer_control]] * Month 5 "cloud continued": [[!traillink xmpp]] [[!traillink more_cloud_providers]] * Month 6 "9k bonus round": [[!traillink desymlink]]+* Month 7: user-driven features and polishing; +  [presentation at LCA2013](http://mirror.linux.org.au/linux.conf.au/2013/mp4/gitannex.mp4)  We are, approximately, here: -* Month 7: user-driven features and polishing; -  [presentation at LCA2013](https://lca2013.linux.org.au/schedule/30059/view_talk) * Month 8: [[!traillink Android]] * Months 9-11: more user-driven features and polishing (see remaining TODO items in all pages above) * Month 12: "Windows purgatory" [[Windows]]@@ -23,6 +23,8 @@ ## porting  * [[OSX]] port is in fairly good shape, but still has some room for improvement+* [[android]] port is just getting started+* Windows port does not exist yet  ## not yet on the map: 
− doc/design/assistant/OSX/comment_1_9290f6e6f265e906b08631224392b7bf._comment
@@ -1,14 +0,0 @@-[[!comment format=mdwn- username="https://www.google.com/accounts/o8/id?id=AItOawlu-fdXIt_RF9ggvg4zP0yBbtjWQwHAMS4"- nickname="Jörn"- subject="Mount detection"- date="2012-09-21T09:23:34Z"- content="""-regarding the current mount polling on OSX: why not use the NSNotificationCenter for being notified on mount events on OSX?--Details see:--1. <http://stackoverflow.com/questions/12409458/detect-when-a-volume-is-mounted-on-os-x>-2. <http://stackoverflow.com/questions/6062299/how-to-add-an-observer-to-nsnotificationcenter-in-a-c-class-using-objective-c>-3. <https://developer.apple.com/library/mac/#documentation/CoreFoundation/Reference/CFNotificationCenterRef/Reference/reference.html#//apple_ref/doc/uid/20001438>-"""]]
doc/design/assistant/android.mdwn view
@@ -1,36 +1,10 @@-Porting git-annex to Android will use the Android native SDK.--A hopefully small Java app will be developed, which runs the webapp-daemon, and a web browser to display it.--### programs to port--These will probably need to be bundled into the Android app, unless already-available in the App Store.--* ssh (native ssh needed for scp, not a client like ConnectBot)-* rsync-* gpg-* git (not all git commands are needed,-  but core plumbing and a few like `git-add` are.)--## GHC Android?--Android's native SDK does not use glibc. GHC's runtime links with glibc.-This could be an enormous problem. Other people want to see GHC able to-target Android, of course, so someone may solve it before I get stuck on-it.--References:--* <http://stackoverflow.com/questions/5151858/running-a-haskell-program-on-the-android-os>-* <http://www.reddit.com/r/haskell/comments/ful84/haskell_on_android/>--I've heard anecdoally that ipwnstudios not only has an IPhone GHC port,-but also Android. Need to get in touch with them.-<http://ipwnstudios.com/>+### goals -Update: This looks likely: <https://github.com/neurocyte/ghc-android>+1. Get git-annex working at the command line in Android,+   along with all the programs it needs, and the assistant. **done**+2. Get the webapp working. Needs Template Haskell, or a workaround.+3. A hopefully small Java app will be developed, which runs the+   webapp daemon, and a web browser to display it.  ### Android specific features @@ -40,7 +14,9 @@ The app should be aware of network status, and avoid expensive data transfers when not on wifi. This may need to be configurable. -## FAT+### FAT  Due to use of the FAT filesystem, which doesn't do symlinks, [[desymlink]] is probably needed for at least older Android devices that have SD cards.+Additionally, cripped filesystem mode is needed, to avoid hard links,+file modes, etc.
+ doc/design/assistant/blog/day_183__plan_b.mdwn view
@@ -0,0 +1,19 @@+Have not tried to run my static binary on Android yet, but I'm already+working on a plan B in case that doesn't work. Yesterday I stumbled upon+<https://github.com/neurocyte/ghc-android>, a ghc cross-compiler for+Android that uses the Android native development kit. +It first appeared on February 4th. Good timing!++I've gotten it to build and it emits arm executables, that seem to use the+Android linker. So that's very promising indeed. ++I've also gotten cabal working with it, and have it chewing through+installing git-annex's build dependencies.++----++Also made a release today, this is another release that's mostly bugfixes,+and a few minor features. Including one bug fixed at 6 am this morning, urk.++I think I will probably split my days between working on Android porting+and other git-annex development.
+ doc/design/assistant/blog/day_184__just_wanna_run_something.mdwn view
@@ -0,0 +1,46 @@+Have been working on getting all the haskell libraries git-annex uses+built with the android cross compiler. Difficulties so far are+libraries that need tweaks to work with the new version of ghc, and some+that use cabal in ways that break cross compilation. Haskell's network+library was the last and most challenging of those.++At this point, I'm able to start trying to build git-annex for android.+Here's the first try!++<pre>+joey@gnu:~/src/git-annex>cabal install -w $HOME/.ghc-android-14-arm-linux-androideabi-4.7/bin/arm-unknown-linux-androideabi-ghc --with-ghc-pkg=$HOME/.ghc-android-14-arm-linux-androideabi-4.7/bin/arm-unknown-linux-androideabi-ghc-pkg --with-ld=$HOME/.ghc-android-14-arm-linux-androideabi-4.7/bin/arm-linux-androideabi-ld --flags="-Webapp -WebDAV -XMPP -S3 -Dbus"+Resolving dependencies...+Configuring git-annex-3.20130207...+Building git-annex-3.20130207...+Preprocessing executable 'git-annex' for git-annex-3.20130207...+on the commandline: Warning:+    -package-conf is deprecated: Use -package-db instead++Utility/libdiskfree.c:28:26:+     fatal error: sys/statvfs.h: No such file or directory+compilation terminated.+</pre>++Should not be far from a first android build now..++----++While I already have Android "hello world" executables to try, I have not yet+been able to run them. Can't seem to find a directory I can write to on the+Asus Transformer, with a filesystem that supports the +x bit. Do you really+have to root Android just to run simple binaries? I'm crying inside.++It seems that the blessed Android NDK way would involve making a Java app,+that pulls in a shared library that contains the native code. For haskell,+the library will need to contain a C shim that, probably, calls an entry+point to the Haskell runtime system. Once running, it can use the FFI to+communicate back to the Java side, probably. The good news is that CJ van+den Berg, who already saved my bacon once by developing ghc-android, tells+me he's hard at work on that very thing.++----++In the meantime, downloaded the Android SDK. Have gotten it to build a+`.apk` package from just javascript code, and managed to do it without+using eclipse (thank god). Will need this later, but for now want to wash+my brain out with soap after using it.
+ doc/design/assistant/blog/day_185__android_liftoff.mdwn view
@@ -0,0 +1,20 @@+Thanks to hhm, who pointed me at [KBOX](http://kevinboone.net/kbox.html),+I have verified that I can build haskell programs that work on Android.++After hacking on it all day, I've succeeded in making an initial build of+git-annex for Android. It links! It runs!++Which is not to say it's usable yet; for one thing I need to get a port+of git before it can do anything useful. (Some of the other things git-annex+needs, like ssh and sha256sum, are helpfully provided by KBOX.)++Next step will be to find or built a git port for Android. I know there's+one in the "Terminal IDE" app. Once I can use git-annex at the command line+on Android, I'll be able to test it out some (I can also port the test+suite program and run it on Android), and get a feeling for what is needed+to get the port to a usable command-line state.++And then on to the webapp, and an Android app, I suppose. So far, the port+doesn't include the webapp, but does include the assistant. The webapp+needs ghci/template haskell for arm. A few people have been reporting they+have that working, but I don't yet.
+ doc/design/assistant/blog/day_186__Android_success.mdwn view
@@ -0,0 +1,33 @@+I'm now successfully using git-annex at the command line on Android.+`git annex watch` works too.++For now, I'm using a git repository under `/data`, which is on a real,+non-cripped filesystem, so symlinks work there.++There's still the issue of running without any symlinks on `/mnt/sdcard`.+While direct mode gets most of the way, it still uses symlinks in a few+places, so some more work will be needed there. Also, git-annex uses hard+links to lock down files, which won't work on cripped filesystems.++Besides that, there's lots of minor porting, but no big show-stoppers+currently.. Some of today's porting work:++* Cross-compiled git for Android. While the Terminal IDE app has some git+  stuff, it's not complete and misses a lot of plumbing commands git-annex+  uses. My git build needs some tweaks to be relocatable without setting+  `GIT_EXEC_PATH`, but it works.++* Switched git-annex to use the Haskell glob library, rather than PCRE. This+  avoids needing libpcre, which simplifies installation on several platforms+  (including Android).++* Made git-annex's `configure` hardcode some settings when cross-compiling+  for Android, rather than probing the build system.++* Android's built-in `lsof` doesn't support the -F option to use a+  machine-readable output format. So wrote a separate lsof output parser for+  the standard lsof output format. Unfortunatly, Android's lsof does not+  provide any information about where a file is open for read or write, so+  for safety, git-annex has to assume any file that's open might be written+  to, and avoid annexing it. It might be better to provide my own lsof+  eventually.
+ doc/design/assistant/blog/day_187__porting_utilities.mdwn view
@@ -0,0 +1,22 @@+Ported all the utilities git-annex needs to run on Android: +git, rsync, gnupg, dropbear (ssh client), busybox. Built a+Makefile that can download, patch, and cross build these from source.++While all the utilities work, dropbear doesn't allow git-annex to use ssh+connection caching, which is rather annoying especially since these systems+tend to be rather slow and take a while to start up ssh connections.+I'd sort of like to try to get openssh's client working on Android instead.+Don't know how realistic that is.++Dealt with several parts of git-annex that assumed `/bin/sh` exists,+so it instead uses `/system/bin/sh` on Android. Also adapted `runshell`+for Android.++Now I have a 8 mb compressed tarball for Android.+Uncompressed it's 25 mb. This includes a lot of git and busybox+commands that won't be used, so it could be trimmed down further.+16 mb of it is git-annex itself.++[[Instructions for using the Android tarball|install/Android]]  +This is for users who are rather brave, not afraid of command line and+keyboard usage. Good first step.
+ doc/design/assistant/blog/day_188__crippled_filesystem_support.mdwn view
@@ -0,0 +1,37 @@+There are at least three problems with using git-annex+on `/sdcard` on Android, or on a FAT filesystem, or on (to a first+approximation) Windows:++1. symlinks+2. hard links+3. unix permissions++So, I've added an `annex.crippledfilesystem` setting. `git annex init` now+probes to see if all three are supported, and if not, enables that, as well+as direct mode.++In crippled filesystem mode, all the permissions settings are skipped.+Most of them are only used to lock down content in the annex in indirect+mode anyway, so no great loss.++There are several uses of hard links, most of which can be dealt with by+making copies. The one use of permissions and hard links I absolutely+needed to deal with was that they're used to lock down a file as it's being+ingested into the annex. That can't be done on crippled filesystems, so I+made it instead check the metadata of the file before and after to detect+if it changed, the same way direct mode detects when files are modified.+This is likely better than the old method anyway.++The other reason files are hardlinked while they're being ingested is that+this allows running lsof on a single directory of files that are in the+process of being added, to detect if anything has them open for write.+I still need to adjust the lsof check to work in crippled filesystem mode.+It seems this won't make it much slower to run lsof on the whole repository.++At this point, I can use git-annex with a repository on `/sdcard` or a FAT+filesystem, and at least `git annex add` works. ++Still several things on the TODO list before crippled filesystem mode is+complete. The only one I'm scared about is making `git merge` do something+sane when it wants to merge two trees full of symlinks, and the filesystem+doesn't let it create a symlink..
+ doc/design/assistant/blog/day_189__more_crippling.mdwn view
@@ -0,0 +1,44 @@+Finished crippled filesystem support, except for symlink handling.+This was straightforward, just got lsof working in that mode, made+`migrate` copy key contents, and adapted the rsync special remote to+support it. Encrypted rsync special remotes have no more overhead on+crippled filesystems than normally. Un-encrypted rsync special remotes+have some added overhead, but less than encrypted remotes. Acceptable+for now.++I've now successfully run the assistant on a FAT filesystem.++----++Git handles symlinks on crippled filesystems by setting+`core.symlinks=false` and checking them out as files containing the link+text. So to finish up crippled filesystem support, git-annex needs to+do the same whenever it creates a symlink, and needs to read file contents+when it normally reads a symlink target.++There are rather a lot of calls to `createSymbolicLink`,+`readSymbolicLink`, `getSymbolicLinkStatus`, `isSymbolicLink`, and `isSymLink`+in the tree; only ones that are used in direct mode+need to be converted. This will take a while.++Checking whether something is a symlink, or where it points is especially+tricky. How to tell if a small file in a git working tree is intended to be+a symlink or not? Well, it can look at the content and see if it makes+sense as a link text pointing at a git-annex key. As long as the+possibility of false positives is ok. It might be possible, in some cases,+to query git to verify if the object stored for that file is really a+symlink, but that won't work if the file has been renamed, for example.++Converted some of the most commonly used symlink code to handle this.+Much more to do, but it basically works; I can `git annex get` and `git+annex drop` on FAT, and it works.++-----++Unfortunately, got side-tracked when I discovered that the last release+introduced a bug in direct mode. Due to the bug, "git annex get file; git annex+drop file; git annex get file" would end up with the file being an indirect+mode symlink to the content, rather than a direct mode file. No data loss,+but not right. So, spent several hours fixing that reversion, which was+caused by me stupidly fixing another bug at 5 am in the morning last week.. +and I'll probably be pushing out another release tomorrow with the fix.
+ doc/design/assistant/blog/day_190-191__weekend.mdwn view
@@ -0,0 +1,28 @@+Pushed out a release yesterday mostly for a bug fix. I have to build+git-annex 5 times now when releasing. Am wondering if I could get rid of+the Linux 64 bit standalone build. The 32 bit build should run ok on 64 bit+Linux systems, since it has all its own 32 bit libraries. What I really+need to do is set up autobuilders for Linux and Android, like we have for OSX.++Today, dealt with all code that creates or looks at symlinks. Audited every+bit of it, and converted all relevant parts to use a new abstraction layer+that handles the pseudolink files git uses when core.symlinks=false.+This is untested, but I'm quite happy with how it turned out.++----++Where next for Android? I want to spend a while testing command-line+git-annex. After I'm sure it's really solid, I should try to get the webapp+working, if possible.++I've heard rumors that Ubuntu's version of ghc somehow supports template+haskell on arm, so I need to investigate that. If I am unable to get+template haskell on arm, I would need to either wait for further+developments, or try to expand yesod's template haskell to regular haskell+and then build it on arm, or I could of course switch away from hamlet+(using blaze-html instead is appealing in some ways) and+use yesod in non-template-haskell mode entirely. One of these will work,+for sure, only question is how much pain.++After getting the webapp working, there's still the issue of bundling it+all up in an Android app that regular users can install.
− doc/design/assistant/blog/day_81__enabling_pre-existing_special_remotes.mdwn
@@ -1,34 +0,0 @@-It's possible for one git annex repository to configure a special remote-that it makes sense for other repositories to also be able to use. Today I-added the UI to support that; in the list of repositories, such-repositories have a "enable" link.--To enable pre-existing rsync special remotes, the webapp has to do the same-probing and ssh key setup that it does when initially creating them.-Rsync.net is also handled as a special case in that code. There was one-ugly part to this.. When a rsync remote is configured in the webapp,-it uses a mangled hostname like "git-annex-example.com-user", to-make ssh use the key it sets up. That gets stored in the `remote.log`, and so-the enabling code has to unmangle it to get back to the real hostname.-------Based on the still-running [[prioritizing_special_remotes]] poll, a lot-of people want special remote support for their phone or mp3 player.-(As opposed to running git-annex on an Android phone, which comes later..)-It'd be easy enough to make the webapp set up a directory special remote-on such a device, but that makes consuming some types of content on the-phone difficult (mp3 players seem to handle them ok based on what people tell-me). I need to think more about some of the ideas mentioned in [[android]]-for more suitable ways of storing files.--One thing's for sure: You won't want the assistant to sync all your files-to your phone! So I also need to start coming up with partial syncing-controls. One idea is for each remote to have a configurable matcher for files-it likes to receive. That could be only mp3 files, or all files inside a-given subdirectory, or all files *not* in a given subdirectory. That means-that when the assistant detects a file has been moved, it'll need to add-(or remove) a queued transfer. Lots of other things could be matched on,-like file size, number of copies, etc. Oh look, I have a-[beautiful library I wrote earlier](http://joeyh.name/blog/entry/happy_haskell_hacker)-that I can reuse!
doc/design/assistant/polls/prioritizing_special_remotes.mdwn view
@@ -6,7 +6,7 @@ Help me prioritize my work: What special remote would you most like to use with the git-annex assistant? -[[!poll open=yes 15 "Amazon S3 (done)" 12 "Amazon Glacier (done)" 9 "Box.com (done)" 68 "My phone (or MP3 player)" 18 "Tahoe-LAFS" 6 "OpenStack SWIFT" 25 "Google Drive"]]+[[!poll open=yes 15 "Amazon S3 (done)" 12 "Amazon Glacier (done)" 9 "Box.com (done)" 69 "My phone (or MP3 player)" 18 "Tahoe-LAFS" 6 "OpenStack SWIFT" 27 "Google Drive"]]  This poll is ordered with the options I consider easiest to build listed first. Mostly because git-annex already supports them and they
doc/direct_mode.mdwn view
@@ -7,7 +7,13 @@ commands cannot safely be used, and only a subset of git-annex commands can be used. -Repositories created by the [[assistant]] use direct mode by default.+Normally, git-annex repositories start off in indirect mode. With some+exceptions:++* Repositories created by the [[assistant]] use direct mode by default.+* Repositories on FAT and other less than stellar filesystems+  that don't support things like symlinks will be automatically put+  into direct mode.  ## enabling (and disabling) direct mode 
+ doc/forum/Different_annexes_pointing_to_same_special_remote__63__.mdwn view
@@ -0,0 +1,6 @@+Is there likely to be any problem in pointing different annexes to the same special remote (i.e. rsync/box.com/etc.) ?++As the objects are stored based on their SHA256 key the expectation is that the chance of collision is is small.++The only problem I can foresee is where the same content is stored in more than one annex and it is deleted in the remote in one annex, but not the other - there won't be any protection against that, but for non-overlapping content this risk should be negligible.+
+ doc/forum/Does_Jabber_syncing_work_when_the_buddy_is_offline__63__.mdwn view
@@ -0,0 +1,1 @@+Do both friends need to be online in order for Jabber syncing to work? Or will the pushed changes be stored on the Jabber server, so that when the remote machine does come online it can pull them even if the original machine is now offline?
+ doc/forum/Feature_request:_Multiple_concurrent_transfers.mdwn view
@@ -0,0 +1,19 @@+I'm sitting on a pretty fast connection, and often git-annex isn't using my entire upstream to fill the remotes.++Lets say i have an annex with 10 x 100mb files. and my git-annex has 5 special remotes that needs to be filled.++I would like to have git-annex do 5 concurrent uploads(one to each remote). Currently git-annex only uploads to one special-remote at a time (meaning the 4 remaining servers are just waiting).++It would also be nice to have a per remote number of threads. Especially if adding a directory with 1000 small files in it(say 100bytes each), having 5 transfer threads to each remote would make the sync complete much faster.+++For now i've made a shell script that i call:++# for j in `seq -w 0 10`; do echo DOING $j; for i in `curl "http://127.0.0.1:$1/?auth=$2" | grep "continue" | gawk -F\"  ' { print $8 } '`; do curl "http://127.0.0.1:$1$i"; sleep 0; done; done++But it is very rough, and basically just starts all transfers on the page. Which means i currently have 315 active transfers running. whoops.++I could improve the shell script. But it really would be quite a bit niftier to have it as settings in git-annex.++Sincerely+Tobias
+ doc/forum/Feature_request:_git_annex_copy_--auto_does_the_right_thing.mdwn view
@@ -0,0 +1,5 @@+I'm not sure of the right place for feature requests; sorry if this is incorrect.++It occurred to me that it would be neat if running git annex copy --auto copied enough copies of the file to connected remotes that don't have it to fulfil numcopies (if possible). Further coolness could come from choosing the remotes smartly (based, for example, on availability, access cost, remote disk space, trust level... you get the idea)++Having an option like this would allow the user to use numcopies to backup files to wherever possible, if they don't really care about where those copies go.
+ doc/forum/Feature_request:_webapp_support_for_centralized_bare_repos.mdwn view
@@ -0,0 +1,1 @@+I would like it if the webapp could support setting up [bare remotes](http://git-annex.branchable.com/tips/centralized_git_repository_tutorial/) to assist with syncing between two machines that are never online at the same time.
− doc/forum/How_to_prevent_the_assistant_from_downloading_all_data__63__.mdwn
@@ -1,9 +0,0 @@-I have a repository on my laptop with a single remote on a USB drive. Both were created without the assistant.--The remote holds all the content. My understanding is that this would be a "backup" repository, using the group definitions.--The local repository generally holds no content. When I want a file, I make sure the remote is available, and then I `git annex get` it.--This works fine in git annex, but I'm now experimenting with the assistant. As soon as I fire up the assistant, it starts downloading all of the data from the remote. I don't ever want it to automatically get any content from the remote. If it sees new content in the repository, I would like it to push that out to the remote. But never get anything from the remote, and never drop anything that is in the repository.--How can I setup this behaviour in the assistant? I have set the remote's repository group to "backup". The local repository is not in any group, since none of the groups fit my model for this repo.
+ doc/forum/Make_whereis_output_more_compact.mdwn view
@@ -0,0 +1,13 @@+Hi there,++first of all, great job done on annex! I think I finally found what I was looking for to organize all my data.++My question: when I do git annex whereis Music, I get a detailed list of every single song and its remote locations. I have tens of thousands of songs, so just typing git annex whereis Music gives me way too much information. +Here is my proposition: in my case, every file of the Music folder resides in the same remote. So, wouldn't it be better to show just one line of output telling me that Music is on remote bla and blub, and then I know that all files in Music are in remotes bla and blub?++Is that possible now already or would that be a feature request? What do you think?++Cheers,+Moritz.++PS: I know that I can specify filters, e.g. git annex whereis --in bla --and --not --in blub. That is great!
− doc/forum/Syncronisation_of_syncronisation_between_3_repositories__63__.mdwn
@@ -1,11 +0,0 @@-Hello Joey,--I just want to know if file transfers between three inter-connected repositories somehow gets syncronized. I have a laptop, a local file server in my home and a virtual server on the internet.--Both my laptop and my file server are configured with a full git repository and connected through pairing and xmpp. The server on the internet is configured as a rsync special remote.--I want the local file server to hold a copy of everything in my annex, the rsync remote should get everything except the folder "media" (too large to upload and not that important) and the laptop whatever I manually decide (preferred content is set to "present").--I have added some files to the repository on the local file server and transferred their content to my laptop by using "git annex get". But when I started the web interface, I saw that those files who are present on both the file server and on the laptop get uploaded to the remote server from both computers, often the same file at the same time. Previously I though the two assistants would somehow talk to each other via xmpp so that doubled effort like that would be avoided. I'm also worried about data consistency because two apparently separate processes rsync to the same remote repository at the same time.--So my question would be: Is your xmpp protocol designed to deal with situations like this and I did not set it up correctly or is what I'm trying to accomplish simply not (yet) possible?
− doc/forum/mistakenly_checked___42__files__42___into_an_annex.__bummer..mdwn
@@ -1,3 +0,0 @@-A couple times working in an annex manually, I accidentally did "git add" instead of "git annex add" and ended up with files checked into my repo instead of symlinks.  So now there is some file content in git, rather than in the annex.  Is there any way to root that out, or is it there forever?  (My limited knowledge of git says: it's there forever, unless maybe you go into the branches where it lives, do an interactive rebase to the time before it was added, remove that commit, replay history, and then garbage collect, but I have no idea if that would suddenly break git annex, and it sounds painful anyway.)--If say I were a neat freak and wanted to just start over with a clean annex, I imagine the thing to do would be to just start the hell over -- and if I wanted to do that, the way to go would be to get into a full repository, do a "git annex uninit" and then throw away the .git directory, then do "git init" and "git annex init" and then "git annex add ." ?
− doc/forum/switching_to__47__from_direct_mode_while_assistant_is_running.mdwn
@@ -1,2 +0,0 @@-Is that really unsafe?  Because I did that and the switch to direct mode seemed to leave a lot of files still as links, and when I panicked and switched back to indirect mode, a whole lot of stuff seemed to have become unannexed and I reannexed it.-
− doc/forum/wishlist:_git_annex_put_--_same_as_get__44___but_for_defaults.mdwn
@@ -1,17 +0,0 @@-I am running centralized git-annex exclusively.--Similar to--    git annex get--I'd like to have a--    git annex put--which would put all files on the default remote(s).--My main reason for not wanting to use copy --to is that I need to specify the remote's name in this case which makes writing a wrapper unnecessarily hard. Also, this would allow--    mr push--to do the right thing all by itself.
doc/git-annex.mdwn view
@@ -796,16 +796,22 @@   to close it. On Mac OSX, when not using direct mode this defaults to   1 second, to work around a bad interaction with software there. +* `annex.autocommit`++  Set to false to prevent the git-annex assistant from automatically+  committing changes to files in the repository.+ * `annex.direct`    Set to true to enable an (experimental) mode where files in the repository   are accessed directly, rather than through symlinks. Note that many git   and git-annex commands will not work with such a repository. -* `annex.autocommit`+* `annex.crippledfilesystem` -  Set to false to prevent the git-annex assistant from automatically-  committing changes to files in the repository.+  Set to true if the repository is on a crippled filesystem, such as FAT,+  which does not support symbolic links, or hard links, or unix permissions.+  This is automatically probed by "git annex init".  * `remote.<name>.annex-cost` 
doc/index.mdwn view
@@ -59,8 +59,22 @@  ## talks -<video controls src="http://video.fosdem.org/2012/lightningtalks/git_annex___manage_files_with_git,_without_checking_their_contents_into_git.webm" width="500"></video>  -A [15 minute introduction to git-annex](http://video.fosdem.org/2012/lightningtalks/git_annex___manage_files_with_git,_without_checking_their_contents_into_git.webm), presented by Richard Hartmann.+<table>+<tr>+<td width="50%" valign="top">+<video controls+src="http://video.fosdem.org/2012/lightningtalks/git_annex___manage_files_with_git,_without_checking_their_contents_into_git.webm" width="100%"></video><br>+A <a href="http://video.fosdem.org/2012/lightningtalks/git_annex___manage_files_with_git,_without_checking_their_contents_into_git.webm">15 minute introduction to git-annex</a>, presented by Richard Hartmann at Fosdem 2012.+</td>+<td width="50%" valign="top">+<video controls width="100%">+<source type="video/mp4" src="http://mirror.linux.org.au/linux.conf.au/2013/mp4/gitannex.mp4">+<source type="video/ogg" src="http://mirror.linux.org.au/linux.conf.au/2013/ogv/gitannex.ogv">+</video><br>+A <a href="http://mirror.linux.org.au/linux.conf.au/2013/mp4/gitannex.mp4">45 minute demo of git-annex and the assistant</a>), presented by Joey Hess at LCA 2013.+</td>+</tr>+</table>  <br clear="all" /> 
doc/install.mdwn view
@@ -14,6 +14,7 @@ [[ScientificLinux5]]  | (and other RHEL5 clones like CentOS5) [[openSUSE]]          |  Windows               | [[sorry, Windows not supported yet|todo/windows_support]]+[[Android]]           |  """]]  ## Using cabal
+ doc/install/Android.mdwn view
@@ -0,0 +1,37 @@+git-annex can be used on Android, however you need to know your way around+the command line to install and use it. (An Android app may be developed+eventually.)++## prebuilt tarball++Download the [prebuilt tarball](http://downloads.kitenet.net/git-annex/android/).+Instructions below assume it was downloaded to `/sdcard/Download`, which+is the default if you use the web browser for the download.++To use this tarball, you need to install either+[KBOX](http://kevinboone.net/kbox.html) or+[Terminal IDE](https://play.google.com/store/apps/details?id=com.spartacusrex.spartacuside)+(available in Google Play).+This is both to get a shell console, as well as a location under+`/data` where git-annex can be installed.++Open the console app you installed, and enter this command:++	cd $(which sh)/..; tar xf /sdcard/Download/git-annex-android.tar.gz++Now git-annex is installed, but to use it you need to enter a special+shell environment:++	runshell++Now you have git-annex, git, and some other utilities available, and can+do everything in the [[walkthrough]] and more.++## building it yourself++git-annex can be built for Android, with `make android`.+You need <https://github.com/neurocyte/ghc-android> installed first,+and also have to `cabal install` all necessary dependencies. This is not+yet an easy process. ++You also need to install git and all the utilities listed on [[fromscratch]].
doc/install/Fedora.mdwn view
@@ -9,7 +9,7 @@ Older version? Here's an installation recipe for Fedora 14 through 15.  <pre>-sudo yum install ghc cabal-install pcre-devel+sudo yum install ghc cabal-install git clone git://git-annex.branchable.com/ git-annex cd git-annex git checkout ghc7.0
doc/install/Linux_standalone.mdwn view
@@ -6,6 +6,9 @@ on anything except for glibc.  [download tarball](http://downloads.kitenet.net/git-annex/linux/)- ++To use, just unpack the tarball, `cd git-annex.linux` and run `./runshell`+-- this sets up an environment where you can use `git annex`+ Warning: This is a last resort. Most Linux users should instead [[install]] git-annex from their distribution of choice.
doc/install/OSX.mdwn view
@@ -24,7 +24,7 @@  <pre> brew update-brew install haskell-platform git ossp-uuid md5sha1sum coreutils pcre libgsasl gnutls libidn libgsasl pkg-config libxml2+brew install haskell-platform git ossp-uuid md5sha1sum coreutils libgsasl gnutls libidn libgsasl pkg-config libxml2 brew link libxml2 cabal update PATH=$HOME/bin:$PATH@@ -38,10 +38,7 @@ Then execute  <pre>-sudo port install git-core ossp-uuid md5sha1sum coreutils pcre gnutls libxml2 libgsasl pkgconfig--sudo ln -s /opt/local/include/pcre.h  /usr/include/pcre.h # This is hack that allows pcre-light to find pcre-+sudo port install git-core ossp-uuid md5sha1sum coreutils gnutls libxml2 libgsasl pkgconfig sudo cabal update PATH=$HOME/bin:$PATH cabal install c2hs git-annex --bindir=$HOME/bin
+ doc/install/OSX/comment_14_035f856923276b0edad879e196e94097._comment view
@@ -0,0 +1,9 @@+[[!comment format=mdwn+ username="https://www.google.com/accounts/o8/id?id=AItOawmCmNS-oUgYfNg85-LPuxzTZJUp0sIgprM"+ nickname="Jonas"+ subject="more homebrew"+ date="2013-02-16T19:46:47Z"+ content="""+i had macports installed. then i installed brew, instaled haskell via brew. i needed to set +    PATH=$HOME/bin:/usr/local/bin:$PATH+"""]]
doc/install/ScientificLinux5.mdwn view
@@ -29,23 +29,11 @@      $ export PATH=/usr/hs/bin:$PATH -On SL5 pcre is at version 6.6 which is far too old for one of the-dependancies that git-annex requires. Therefore the user must install-an updated version of _pcre_ either from source or another method, I-chose to install it from source and by hand into /usr/local--    $ wget http://sourceforge.net/projects/pcre/files/pcre/8.30/pcre-8.30.tar.gz/download-    $ tar zxvf pcre-8.30.tar.gz-    $ cd pcre-8.30-    $ ./configure-    $ make && make install- Once the packages are installed and are in your execution path, using cabal to configure and build git-annex just makes life easier, it should install all the needed dependancies.      $ cabal update-    $ cabal install pcre-light --extra-include-dirs=/usr/local/include     $ git clone git://git.kitenet.net/git-annex     $ cd git-annex     $ make git-annex.1
doc/install/fromscratch.mdwn view
@@ -5,7 +5,6 @@   * [The Haskell Platform](http://haskell.org/platform/) (GHC 7.4 or newer)   * [mtl](http://hackage.haskell.org.package/mtl) (2.1.1 or newer)   * [MissingH](http://github.com/jgoerzen/missingh/wiki)-  * [pcre-light](http://hackage.haskell.org/package/pcre-light)   * [utf8-string](http://hackage.haskell.org/package/utf8-string)   * [SHA](http://hackage.haskell.org/package/SHA)   * [dataenc](http://hackage.haskell.org/package/dataenc)@@ -20,6 +19,8 @@   * [hS3](http://hackage.haskell.org/package/hS3) (optional)   * [DAV](http://hackage.haskell.org/package/DAV) (optional)   * [SafeSemaphore](http://hackage.haskell.org/package/SafeSemaphore)+  * [UUID](http://hackage.haskell.org/package/uuid)+  * [Glob](http://hackage.haskell.org/package/Glob) * Optional haskell stuff, used by the [[assistant]] and its webapp (edit Makefile to disable)   * [stm](http://hackage.haskell.org/package/stm)     (version 2.3 or newer)@@ -48,8 +49,6 @@   * [async](http://hackage.haskell.org/package/async) * Shell commands   * [git](http://git-scm.com/)-  * [uuid](http://www.ossp.org/pkg/lib/uuid/)-    (or `uuidgen` from util-linux)   * [xargs](http://savannah.gnu.org/projects/findutils/)   * [rsync](http://rsync.samba.org/)   * [curl](http://http://curl.haxx.se/) (optional, but recommended)
+ doc/news/version_3.20130216.mdwn view
@@ -0,0 +1,17 @@+git-annex 3.20130216 released with [[!toggle text="these changes"]]+[[!toggleable text="""+   * Now uses the Haskell uuid library, rather than needing a uuid program.+   * Now uses the Haskell Glob library, rather than pcre-light, avoiding+     the need to install libpcre. Currently done only for Cabal or when+     the Makefile is made to use -DWITH\_GLOB+   * Android port now available (command-line only).+   * New annex.crippledfilesystem setting, allows use of git-annex+     repositories on FAT and even worse filesystems; avoiding use of+     hard links and locked down permissions settings. (Support is incomplete.)+   * init: Detect when the repository is on a filesystem that does not+     support hard links, or symlinks, or unix permissions, and set+     annex.crippledfilesystem, as well as annex.direct.+   * add: Improved detection of files that are modified while being added.+   * Fix a bug in direct mode, introduced in the previous release, where+     if a file was dropped and then got back, it would be stored in indirect+     mode."""]]
− doc/special_remotes/bup/comment_1_96179a003da4444f6fc08867872cda0a._comment
@@ -1,43 +0,0 @@-[[!comment format=mdwn- username="https://www.google.com/accounts/o8/id?id=AItOawkgbXwQtPQSG8igdS7U8l031N8sqDmuyvk"- nickname="Albert"- subject="Error with bup and gnupg"- date="2012-10-22T20:56:56Z"- content="""-Hello,--I get this error when trying to use git-annex with bup and gnupg:--<pre>-move importable_pilot_surveys.tar (gpg) (checking localaseebup...) (to localaseebup...) -Traceback (most recent call last):-  File \"/usr/lib/bup/cmd/bup-split\", line 133, in <module>-    progress=prog)-  File \"/usr/lib/bup/bup/hashsplit.py\", line 167, in split_to_shalist-    for (sha,size,bits) in sl:-  File \"/usr/lib/bup/bup/hashsplit.py\", line 118, in _split_to_blobs-    for (blob, bits) in hashsplit_iter(files, keep_boundaries, progress):-  File \"/usr/lib/bup/bup/hashsplit.py\", line 86, in _hashsplit_iter-    bnew = next(fi)-  File \"/usr/lib/bup/bup/helpers.py\", line 86, in next-    return it.next()-  File \"/usr/lib/bup/bup/hashsplit.py\", line 49, in blobiter-    for filenum,f in enumerate(files):-  File \"/usr/lib/bup/cmd/bup-split\", line 128, in <genexpr>-    files = extra and (open(fn) for fn in extra) or [sys.stdin]-IOError: [Errno 2] No such file or directory: '-'-</pre>---I was able to work-around this issue by altering /usr/lib/bup/cmd/bup-split (though I don't think its a bup bug) to just pull from stdin:--files = [sys.stdin]--on ~ line 128.--Any ideas? Also, do you think that bup's data-deduplication does anything when gnupg is enabled, i.e. is it just as well to use a directory remote with gnupg?--Thanks! Git annex rules!--Albert-"""]]
− doc/special_remotes/bup/comment_2_612b038c15206f9f3c2e23c7104ca627._comment
@@ -1,12 +0,0 @@-[[!comment format=mdwn- username="http://joeyh.name/"- ip="4.154.0.23"- subject="comment 2"- date="2012-10-23T20:01:43Z"- content="""-@Albert, thanks for reporting this bug (but put them in [[bugs]] in future please).--This is specific to using the bup special remote with encryption. Without encryption it works. And no, it won't manage to deduplicate anything that's encrypted, as far as I know. --I think bup-split must have used - for stdin in the past, but now, it just reads from stdin when no file is specified, so I've updated git-annex.-"""]]
− doc/special_remotes/hook/comment_1_6a74a25891974a28a8cb42b87cb53c26._comment
@@ -1,32 +0,0 @@-[[!comment format=mdwn- username="helmut"- ip="89.0.176.236"- subject="Asynchronous hooks?"- date="2012-10-13T09:46:14Z"- content="""-Is there a way to use asynchronous remotes? Interaction with git annex would have to-split the part of initiating some action from completing it.--I imagine I could `git annex copy` a file to an asynchronous remote and the command-would almost immediately complete. Later I would learn that the transfer is-completed, so the hook must be able to record that information in the `git-annex`-branch. An additional plumbing command seems required here as well as a way to-indicate that even though the store-hook completed, the file is not transferred.--Similarly `git annex get` would immediately return without actually fetching the-file. This should already be possible by returning non-zero from the retrieve-hook.-Later the hook could use plumbing level commands to actually stick the received file-into the repository.--The remove-hook should need no changes, but the checkpresent-hook would be more like-a trigger without any actual result. The extension of the plumbing required for the-extension to the receive-hook could update the location log. A downside here is that-you never know when a fsck has completed.--My proposal does not include a way to track the completion of actions, but relies on-the hook to always complete them reliably. It is not clear that this is the best road-for asynchronous hooks.--One use case for this would be a remote that is only accessible via uucp. Are there-other use cases? Is the drafted interface useful?-"""]]
− doc/tips/assume-unstaged/comment_1_44abd811ef79a85e557418e17a3927be._comment
@@ -1,10 +0,0 @@-[[!comment format=mdwn- username="https://me.yahoo.com/a/2djv2EYwk43rfJIAQXjYt_vfuOU-#a11a6"- nickname="Olivier R"- subject="It doesn't work 100%"- date="2012-05-03T21:42:54Z"- content="""-When you remove tracked files... it doesn't show the new status. it's like if the file was ignored.---"""]]
− doc/tips/using_Amazon_S3/comment_1_666a26f95024760c99c627eed37b1966._comment
@@ -1,8 +0,0 @@-[[!comment format=mdwn- username="https://www.google.com/accounts/o8/id?id=AItOawnoUOqs_lbuWyZBqyU6unHgUduJwDDgiKY"- nickname="Matt"- subject="ANNEX_S3 vs AWS for keys"- date="2012-05-29T12:24:25Z"- content="""-The instructions state ANNEX_S3_ACCESS_KEY_ID and ANNEX_SECRET_ACCESS_KEY but git-annex cannot connect with those constants. git-annex tells me to set both \"AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY\" instead, which works. This is with Xubuntu 12.04.-"""]]
− doc/tips/using_Amazon_S3/comment_2_f5a0883be7dbb421b584c6dc0165f1ef._comment
@@ -1,8 +0,0 @@-[[!comment format=mdwn- username="http://joeyh.name/"- ip="4.153.81.112"- subject="comment 2"- date="2012-05-29T19:10:42Z"- content="""-Thanks, I've fixed that. (You could have too.. this is a wiki ;)-"""]]
− doc/todo/cache_key_info/comment_1_578df1b3b2cbfdc4aa1805378f35dc48._comment
@@ -1,11 +0,0 @@-[[!comment format=mdwn- username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"- nickname="Richard"- subject="comment 1"- date="2011-05-17T07:27:02Z"- content="""-Sounds like a good idea.--* git annex fsck (or similar) should check/rebuild the caches-* I would simply require a clean tree with a verbose error. 80/20 rule and defaulting to save actions.-"""]]
− doc/todo/windows_support/comment_1_3cc26ad8101a22e95a8c60cf0c4dedcc._comment
@@ -1,10 +0,0 @@-[[!comment format=mdwn- username="https://www.google.com/accounts/o8/id?id=AItOawkRITTYYsN0TFKN7G5sZ6BWGZOTQ88Pz4s"- nickname="Zoltán"- subject="cygwin"- date="2012-05-15T00:14:08Z"- content="""-What about [Cygwin](http://cygwin.com/)? It emulates POSIX fairly well under Windows (including signals, forking, fs (also things like /dev/null, /proc), unix file permissions), has all standard gnu utilities. It also emulates symlinks, but they are unfortunately incompatible with NTFS symlinks introduced in Vista [due to some stupid restrictions on Windows](http://cygwin.com/ml/cygwin/2009-10/msg00756.html).--If git-annex could be modified to not require symlinks to work, the it would be a pretty neat solution (and you get a real shell, not some command.com on drugs (aka cmd.exe))-"""]]
− doc/todo/windows_support/comment_2_8acae818ce468967499050bbe3c532ea._comment
@@ -1,12 +0,0 @@-[[!comment format=mdwn- username="https://www.google.com/accounts/o8/id?id=AItOawk5cj-itfFHq_yhJHdzk3QOPp-PNW_MjPU"- nickname="Michael"- subject="+1 Cygwin"- date="2012-05-23T19:30:21Z"- content="""-Windows support is a must. In my experience, binary file means proprietary editor, which means Windows.--Unfortunately, there's not much overlap between people who use graphical editors in Windows all day vs. people who are willing to tolerate Cygwin's setup.exe, compile a Haskell program, learn git and git-annex's 90-odd subcommands, and use a mintty terminal to manage their repository, especially now that there's a sexy GitHub app for Windows.--That aside, I think Windows-based content producers are still *the* audience for git-annex. First Windows support, then a GUI, then the world.-"""]]
− doc/todo/windows_support/comment_3_bd0a12f4c9b884ab8a06082842381a01._comment
@@ -1,8 +0,0 @@-[[!comment format=mdwn- username="http://xolus.net/openid/max"- nickname="B0FH"- subject="What about NTFS support ?"- date="2012-08-02T17:45:10Z"- content="""-Has git-annex been tested with an NTFS-formatted disk under Linux ? NTFS is supposed to be case-sensitive and to allow symlinks, and these are supposed to work with ntfs3g.-"""]]
− doc/todo/windows_support/comment_4_ad06b98b2ddac866ffee334e41fee6a8._comment
@@ -1,8 +0,0 @@-[[!comment format=mdwn- username="https://www.google.com/accounts/o8/id?id=AItOawlc1og3PqIGudOMkFNrCCNg66vB7s-jLpc"- nickname="Paul"- subject="Re: What about NTFS support?"- date="2012-08-16T19:30:38Z"- content="""-I successfully use git-annex on an NTFS formatted external USB drive, so yes, it is possible and works well.-"""]]
− doc/todo/windows_support/comment_5_444fc7251f57db241b6e80abae41851c._comment
@@ -1,10 +0,0 @@-[[!comment format=mdwn- username="https://me.yahoo.com/a/dASECLNzvckz4VwqUGYsvthiplY.#d2c27"- nickname="A. D. Sicks"- subject="comment 5"- date="2012-09-09T23:48:21Z"- content="""-Haskell has C++ binding, so it should be possible to port it to .net/Mono with a VB GUI for Windows users.  Windows has a primitive form of symlinks called shortcuts.  Perhaps shortcut support in Windows could replace the use of symlinks.  I've used shortcuts since XP to put my home Windows directory on another partition and never had a hitch...--If anyone is interested in working on this, hit me up.  I would like to use this in my XP vbox to have access to files on my host OS...I have a student edition of Visual Studio 2005 to do an open source port...-"""]]
− doc/todo/windows_support/comment_6_34f1f60b570c389bb1e741b990064a7e._comment
@@ -1,8 +0,0 @@-[[!comment format=mdwn- username="https://www.google.com/accounts/o8/id?id=AItOawnlwEMhiNYv__mEUABW4scn83yMraC3hqE"- nickname="Sean"- subject="NTFS symlinks"- date="2013-01-11T21:44:21Z"- content="""-It seems that NTFS (from Vista forward) has full POSIX support for symlinks. At least, Wikipedia [seems to think so.](http://en.wikipedia.org/wiki/NTFS_symbolic_link). What about doing like GitHub and using MinGW for compatibility? Cygwin absolutely blows in terms of installation size and compatability with the rest of Windows.-"""]]
+ doc/todo/wishlist:_special_remote_Ubuntu_One.mdwn view
@@ -0,0 +1,1 @@+Special remote support for [Ubuntu One](http://one.ubuntu.com) would be nice. They're [using propietary but open protocol](https://wiki.ubuntu.com/UbuntuOne/TechnicalDetails#ubuntuone-storageprotocol) based on [Google Protocol Buffers](http://code.google.com/p/protobuf/). There's [protobuf for Haskell](http://code.google.com/p/protobuf-haskell/) so it should be possible to compile [the protocol file](http://bazaar.launchpad.net/~ubuntuone-control-tower/ubuntuone-storage-protocol/trunk/view/head:/ubuntuone/storageprotocol/protocol.proto) to Haskell code and then use that to implement the native Ubuntu special remote.
git-annex.1 view
@@ -700,14 +700,19 @@ to close it. On Mac OSX, when not using direct mode this defaults to 1 second, to work around a bad interaction with software there. .IP+.IP "annex.autocommit"+Set to false to prevent the git\-annex assistant from automatically+committing changes to files in the repository.+.IP .IP "annex.direct" Set to true to enable an (experimental) mode where files in the repository are accessed directly, rather than through symlinks. Note that many git and git\-annex commands will not work with such a repository. .IP-.IP "annex.autocommit"-Set to false to prevent the git\-annex assistant from automatically-committing changes to files in the repository.+.IP "annex.crippledfilesystem"+Set to true if the repository is on a crippled filesystem, such as FAT,+which does not support symbolic links, or hard links, or unix permissions.+This is automatically probed by "git annex init". .IP .IP "remote.<name>.annex\-cost" When determining which repository to
git-annex.cabal view
@@ -1,5 +1,5 @@ Name: git-annex-Version: 3.20130207+Version: 3.20130216.1 Cabal-Version: >= 1.8 License: GPL Maintainer: Joey Hess <joey@kitenet.net>@@ -57,16 +57,17 @@   Build-Depends: MissingH, hslogger, directory, filepath,    unix, containers, utf8-string, network (>= 2.0), mtl (>= 2.1.1),    bytestring, old-locale, time,-   pcre-light, extensible-exceptions, dataenc, SHA, process, json, HTTP,-   base (>= 4.5 && < 4.7), monad-control, transformers-base, lifted-base,+   extensible-exceptions, dataenc, SHA, process, json,+   base (>= 4.5 && < 4.8), monad-control, transformers-base, lifted-base,    IfElse, text, QuickCheck >= 2.1, bloomfilter, edit-distance, process,-   SafeSemaphore+   SafeSemaphore, uuid, random, Glob   -- Need to list these because they're generated from .hsc files.   Other-Modules: Utility.Touch Utility.Mounts   Include-Dirs: Utility   C-Sources: Utility/libdiskfree.c Utility/libmounts.c   Extensions: CPP   GHC-Options: -threaded+  CPP-Options: -DWITH_GLOB    if flag(S3)     Build-Depends: hS3@@ -123,15 +124,15 @@   Main-Is: test.hs   Build-Depends: testpack, HUnit, MissingH, hslogger, directory, filepath,    unix, containers, utf8-string, network, mtl (>= 2.1.1), bytestring,-   old-locale, time, pcre-light, extensible-exceptions, dataenc, SHA,-   process, json, HTTP, base (>= 4.5 && < 4.7), monad-control,+   old-locale, time, extensible-exceptions, dataenc, SHA,+   process, json, base (>= 4.5 && < 4.7), monad-control,    transformers-base, lifted-base, IfElse, text, QuickCheck >= 2.1,-   bloomfilter, edit-distance, process, SafeSemaphore+   bloomfilter, edit-distance, process, SafeSemaphore, Glob   Other-Modules: Utility.Touch   Include-Dirs: Utility   C-Sources: Utility/libdiskfree.c   Extensions: CPP-  GHC-Options: -threaded+  GHC-Options: -threaded -DWITH_GLOB  source-repository head   type: git
+ standalone/android/Makefile view
@@ -0,0 +1,53 @@+# Cross-compiles utilities needed for git-annex on Android.++# Add Android cross-compiler to PATH (as installed by ghc-android)+PATH:=$(HOME)/.ghc/android-14/arm-linux-androideabi-4.7/bin:$(PATH)++build: source+	mkdir -p git-annex-bundle/bin+	+	cd source/git && $(MAKE) install NO_OPENSSL=1 NO_GETTEXT=1 NO_GECOS_IN_PWENT=1 NO_GETPASS=1 NO_NSEC=1 NO_MKDTEMP=1 NO_PTHREADS=1 NO_PERL=1 NO_CURL=1 NO_EXPAT=1 NO_TCLTK=1 NO_ICONV=1 prefix= DESTDIR=../../git-annex-bundle+	rm -f git-annex-bundle/bin/git-cvsserver++	cp source/busybox/configs/android2_defconfig source/busybox/.config+	echo 'CONFIG_FEATURE_INSTALLER=y' >> source/busybox/.config+	cd source/busybox && yes '' | $(MAKE) oldconfig+	cd source/busybox && $(MAKE)+	cp -a source/busybox/busybox git-annex-bundle/bin/++	cd source/dropbear && git reset --hard origin/master && git am < ../../dropbear.patch+	cp source/automake/lib/config.sub source/automake/lib/config.guess source/dropbear/+	cd source/dropbear && ./configure --host=arm-linux-androideabi --disable-lastlog --disable-utmp --disable-utmpx --disable-wtmp --disable-wtmpx+	cd source/dropbear && $(MAKE) dbclient+	cp -a source/dropbear/dbclient git-annex-bundle/bin/ssh+	+	cd source/rsync && git reset --hard origin/master && git am < ../../rsync.patch+	cp source/automake/lib/config.sub source/automake/lib/config.guess source/rsync/+	cd source/rsync && ./configure --host=arm-linux-androideabi --disable-locale --disable-iconv-open --disable-iconv --disable-acl-support --disable-xattr-support+	cd source/rsync && $(MAKE)+	cp -a source/rsync/rsync git-annex-bundle/bin/++	cd source/gnupg && git checkout gnupg-1.4.13+	cd source/gnupg && ./autogen.sh+	cd source/gnupg && ./configure --host=arm-linux-androideabi --disable-gnupg-iconv --enable-minimal --disable-card-support --disable-agent-support --disable-photo-viewers --disable-keyserver-helpers --disable-nls+	cd source/gnupg; $(MAKE) || true # expected failure in doc build+	cp -a source/gnupg/g10/gpg git-annex-bundle/bin/++source:+	mkdir -p source+	git clone git://git.savannah.gnu.org/automake.git source/automake+	git clone git://git.debian.org/git/d-i/busybox source/busybox+	git clone git://github.com/android/platform_external_dropbear source/dropbear+	git clone git://git.kernel.org/pub/scm/git/git.git source/git+	git clone git://git.samba.org/rsync.git source/rsync+	git clone git://git.gnupg.org/gnupg.git source/gnupg++clean:+	cd source/busybox && $(MAKE) clean+	cd source/dropbear && $(MAKE) clean+	cd source/git && $(MAKE) clean+	cd source/rsync && $(MAKE) clean+	cd source/gnupg && $(MAKE) clean++reallyclean:+	rm -rf source
+ standalone/android/dropbear.patch view
@@ -0,0 +1,55 @@+From 014dadb02fd984828a6232534c47dba8e2f7818a Mon Sep 17 00:00:00 2001+From: Joey Hess <joey@kitenet.net>+Date: Wed, 13 Feb 2013 15:29:52 -0400+Subject: [PATCH] android patch for dropbear++* Disable HOME override+* Use urandom to avoid blocking on every ssh connection.+* Enable use of netbsd_getpass.c+---+ cli-auth.c |    1 ++ cli-main.c |    2 --+ options.h  |    2 +-+ 3 files changed, 2 insertions(+), 3 deletions(-)++diff --git a/cli-auth.c b/cli-auth.c+index 4c17a21..91dfdf8 100644+--- a/cli-auth.c++++ b/cli-auth.c+@@ -31,6 +31,7 @@+ #include "ssh.h"+ #include "packet.h"+ #include "runopts.h"++#include "netbsd_getpass.c"+ + void cli_authinitialise() {+ +diff --git a/cli-main.c b/cli-main.c+index 106006b..68cf023 100644+--- a/cli-main.c++++ b/cli-main.c+@@ -47,8 +47,6 @@ int main(int argc, char ** argv) {+ 	_dropbear_exit = cli_dropbear_exit;+ 	_dropbear_log = cli_dropbear_log;+ +-	putenv("HOME=/data/local");+-+ 	disallow_core();+ + 	cli_getopts(argc, argv);+diff --git a/options.h b/options.h+index 7625151..48e404d 100644+--- a/options.h++++ b/options.h+@@ -159,7 +159,7 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */+  * however significantly reduce the security of your ssh connections+  * if the PRNG state becomes guessable - make sure you know what you are+  * doing if you change this. */+-#define DROPBEAR_RANDOM_DEV "/dev/random"++#define DROPBEAR_RANDOM_DEV "/dev/urandom"+ + /* prngd must be manually set up to produce output */+ /*#define DROPBEAR_PRNGD_SOCKET "/var/run/dropbear-rng"*/+-- +1.7.10.4+
+ standalone/android/rsync.patch view
@@ -0,0 +1,40 @@+From f91df535053958600d57f9df78d9ce84c8718655 Mon Sep 17 00:00:00 2001+From: Joey Hess <joey@kitenet.net>+Date: Wed, 13 Feb 2013 15:51:40 -0400+Subject: [PATCH] android portability++---+ authenticate.c |    3 ++-+ batch.c        |    2 +-+ 2 files changed, 3 insertions(+), 2 deletions(-)++diff --git a/authenticate.c b/authenticate.c+index 7650377..626dec6 100644+--- a/authenticate.c++++ b/authenticate.c+@@ -296,7 +296,8 @@ void auth_client(int fd, const char *user, const char *challenge)+                  *+                  * OpenBSD has a readpassphrase() that might be more suitable.+                  */+-		pass = getpass("Password: ");++		/*pass = getpass("Password: "); */++		exit(1);+ 	}+ + 	if (!pass)+diff --git a/batch.c b/batch.c+index a3e9dca..ee31532 100644+--- a/batch.c++++ b/batch.c+@@ -221,7 +221,7 @@ void write_batch_shell_file(int argc, char *argv[], int file_arg_cnt)+ 	stringjoin(filename, sizeof filename,+ 		   batch_name, ".sh", NULL);+ 	fd = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,+-		     S_IRUSR | S_IWUSR | S_IEXEC);++		     S_IRUSR | S_IWUSR);+ 	if (fd < 0) {+ 		rsyserr(FERROR, errno, "Batch file %s open error",+ 			filename);+-- +1.7.10.4+
+ standalone/android/runshell view
@@ -0,0 +1,62 @@+#!/system/bin/sh+# Runs a shell command (or interactive shell) using the binaries and+# libraries bundled with this app.++set -e++base="$(dirname $0)"/git-annex-bundle++if [ ! -d "$base" ]; then+	echo "** cannot find base directory (I seem to be $0)" >&2+	exit 1+fi++if [ ! -e "$base/bin/git-annex" ]; then+	echo "** base directory $base does not contain bin/git-annex" >&2+	exit 1+fi+if [ ! -e "$base/bin/git" ]; then+	echo "** base directory $base does not contain bin/git" >&2+	exit 1+fi++# Install busybox links.+if [ ! -e "$base/bin/sh" ]; then+	echo "(First run detected ... setting up busybox ...)"+	"$base/bin/busybox" --install "$base/bin"+fi++# Get absolute path to base, to avoid breakage when things change directories.+orig="$(pwd)"+cd "$base"+base="$(pwd)"+cd "$orig"++# Put our binaries first, to avoid issues with out of date or incompatable+# system or App binaries.+ORIG_PATH="$PATH"+export ORIG_PATH+PATH=$base/bin:$PATH+export PATH++ORIG_GIT_EXEC_PATH="$GIT_EXEC_PATH"+export ORIG_GIT_EXEC_PATH+GIT_EXEC_PATH=$base/libexec/git-core+export GIT_EXEC_PATH++ORIG_GIT_TEMPLATE_DIR="$GIT_TEMPLATE_DIR"+export ORIG_GIT_TEMPLATE_DIR+GIT_TEMPLATE_DIR="$base/templates"+export GIT_TEMPLATE_DIR++# Indicate which variables were exported above.+GIT_ANNEX_STANDLONE_ENV="PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR"+export GIT_ANNEX_STANDLONE_ENV++if [ "$1" ]; then+	cmd="$1"+	shift 1+	exec "$cmd" "$@"+else+	sh+fi
standalone/licences.gz view

binary file changed (55614 → 56750 bytes)

test.hs view
@@ -54,7 +54,7 @@ import qualified Utility.Verifiable import qualified Utility.Process import qualified Utility.Misc-import qualified Annex.Content.Direct+import qualified Utility.InodeCache  -- instances for quickcheck instance Arbitrary Types.Key.Key where@@ -75,8 +75,8 @@ 		<*> arbitrary `suchThat` (/= Just "") 		<*> arbitrary -instance Arbitrary Annex.Content.Direct.Cache where-	arbitrary = Annex.Content.Direct.Cache+instance Arbitrary Utility.InodeCache.InodeCache where+	arbitrary = Utility.InodeCache.InodeCache 		<$> arbitrary 		<*> arbitrary 		<*> arbitrary@@ -119,7 +119,7 @@ 	, qctest "prop_verifiable_sane" Utility.Verifiable.prop_verifiable_sane 	, qctest "prop_segment_regressionTest" Utility.Misc.prop_segment_regressionTest 	, qctest "prop_read_write_transferinfo" Logs.Transfer.prop_read_write_transferinfo-	, qctest "prop_read_show_direct" Annex.Content.Direct.prop_read_show_direct+	, qctest "prop_read_show_inodecache" Utility.InodeCache.prop_read_show_inodecache 	, qctest "prop_parse_show_log" Logs.Presence.prop_parse_show_log 	, qctest "prop_read_show_TrustLevel" Types.TrustLevel.prop_read_show_TrustLevel 	, qctest "prop_parse_show_TrustLog" Logs.Trust.prop_parse_show_TrustLog@@ -209,7 +209,7 @@ 	git_annex "drop" ["--force", sha1annexedfile] @? "drop failed" 	writeFile tmp $ content sha1annexedfile 	r <- annexeval $ Types.Backend.getKey backendSHA1 $-		Types.KeySource.KeySource { Types.KeySource.keyFilename = tmp, Types.KeySource.contentLocation = tmp }+		Types.KeySource.KeySource { Types.KeySource.keyFilename = tmp, Types.KeySource.contentLocation = tmp, Types.KeySource.inodeCache = Nothing } 	let key = Types.Key.key2file $ fromJust r 	git_annex "reinject" [tmp, sha1annexedfile] @? "reinject failed" 	git_annex "fromkey" [key, sha1annexedfiledup] @? "fromkey failed"