packages feed

git-annex 3.20120309 → 3.20120315

raw patch · 53 files changed

+939/−587 lines, 53 filesdep +bloomfiltersetup-changed

Dependencies added: bloomfilter

Files

.gitignore view
@@ -1,3 +1,4 @@+tmp *.hi *.o test
Annex/Content.hs view
@@ -27,6 +27,7 @@  import Control.Exception (bracket_) import System.Posix.Types+import System.IO.Unsafe (unsafeInterleaveIO)  import Common.Annex import Logs.Location@@ -149,16 +150,16 @@ getViaTmpUnchecked :: Key -> (FilePath -> Annex Bool) -> Annex Bool getViaTmpUnchecked key action = do 	tmp <- prepTmp key-	success <- action tmp-	if success-		then do+	ifM (action tmp)+		( do 			moveAnnex key tmp 			logStatus key InfoPresent 			return True-		else do+		, do 			-- the tmp file is left behind, in case caller wants 			-- to resume its transfer 			return False+		)  {- Creates a temp file, runs an action on it, and cleans up the temp file. -} withTmp :: Key -> (FilePath -> Annex a) -> Annex a@@ -229,15 +230,15 @@ moveAnnex key src = do 	dest <- inRepo $ gitAnnexLocation key 	let dir = parentDir dest-	e <- liftIO $ doesFileExist dest-	if e-		then liftIO $ removeFile src-		else liftIO $ do+	liftIO $ ifM (doesFileExist dest)+		( removeFile src+		, do 			createDirectoryIfMissing True dir 			allowWrite dir -- in case the directory already exists 			moveFile src dest 			preventWrite dest 			preventWrite dir+		)  withObjectLoc :: Key -> ((FilePath, FilePath) -> Annex a) -> Annex a withObjectLoc key a = do@@ -290,19 +291,20 @@  {- List of keys whose content exists in .git/annex/objects/ -} getKeysPresent :: Annex [Key]-getKeysPresent = getKeysPresent' =<< fromRepo gitAnnexObjectDir-getKeysPresent' :: FilePath -> Annex [Key]-getKeysPresent' dir = do-	exists <- liftIO $ doesDirectoryExist dir-	if not exists-		then return []-		else liftIO $ do-			-- 2 levels of hashing-			levela <- dirContents dir-			levelb <- mapM dirContents levela-			contents <- mapM dirContents (concat levelb)-			let files = concat contents-			return $ mapMaybe (fileKey . takeFileName) files+getKeysPresent = liftIO . traverse (2 :: Int) =<< fromRepo gitAnnexObjectDir+	where+		traverse depth dir = do+			contents <- catchDefaultIO (dirContents dir) []+			if depth == 0+				then continue (mapMaybe (fileKey . takeFileName) contents) []+				else do+					let deeper = traverse (depth - 1)+					continue [] (map deeper contents)+		continue keys [] = return keys+		continue keys (a:as) = do+			{- Force lazy traversal with unsafeInterleaveIO. -}+			morekeys <- unsafeInterleaveIO a+			continue (morekeys++keys) as  {- Things to do to record changes to content when shutting down.  -@@ -312,12 +314,12 @@ saveState :: Bool -> Annex () saveState oneshot = do 	Annex.Queue.flush False-	unless oneshot $ do-		alwayscommit <- fromMaybe True . Git.configTrue+	unless oneshot $+		ifM alwayscommit+			( Annex.Branch.commit "update" , Annex.Branch.stage)+	where+		alwayscommit = fromMaybe True . Git.configTrue 			<$> fromRepo (Git.Config.get "annex.alwayscommit" "")-		if alwayscommit-			then Annex.Branch.commit "update"-			else Annex.Branch.stage  {- Downloads content from any of a list of urls. -} downloadUrl :: [Url.URLString] -> FilePath -> Annex Bool@@ -336,10 +338,9 @@ 			ok <- copy 			when ok $ liftIO $ allowWrite file 			return ok-		copy = do-			present <- liftIO $ doesFileExist file-			if present-				then return True-				else do+		copy = ifM (liftIO $ doesFileExist file)+				( return True+				, do 					s <- inRepo $ gitAnnexLocation key 					liftIO $ copyFileExternal s file+				)
Annex/Ssh.hs view
@@ -37,15 +37,17 @@ 			sshCleanup  sshInfo :: (String, Maybe Integer) -> Annex (Maybe FilePath, [CommandParam])-sshInfo (host, port) = do-	caching <- fromMaybe SysConfig.sshconnectioncaching . Git.configTrue-		<$> fromRepo (Git.Config.get "annex.sshcaching" "")-	if caching-		then do-			dir <- fromRepo gitAnnexSshDir-			let socketfile = dir </> hostport2socket host port-		 	return (Just socketfile, cacheParams socketfile)-		else return (Nothing, [])+sshInfo (host, port) = ifM caching+	( do+		dir <- fromRepo gitAnnexSshDir+		let socketfile = dir </> hostport2socket host port+	 	return (Just socketfile, cacheParams socketfile)+	, return (Nothing, [])+	)+	where+		caching = fromMaybe SysConfig.sshconnectioncaching +			. Git.configTrue+			<$> fromRepo (Git.Config.get "annex.sshcaching" "")  cacheParams :: FilePath -> [CommandParam] cacheParams socketfile =
Annex/UUID.hs view
@@ -34,11 +34,11 @@ genUUID = pOpen ReadFromPipe command params $ liftM toUUID . hGetLine 	where 		command = SysConfig.uuid-		params = if command == "uuid"+		params 			-- request a random uuid be generated-			then ["-m"]+			| command == "uuid" = ["-m"] 			-- uuidgen generates random uuid by default-			else []+			| otherwise = []  {- Get current repository's UUID. -} getUUID :: Annex UUID
+ Build/Configure.hs view
@@ -0,0 +1,107 @@+{- Checks system configuration and generates SysConfig.hs. -}++module Build.Configure where++import System.Directory+import Data.List+import System.Cmd.Utils+import Control.Applicative++import Build.TestConfig+import Utility.SafeCommand++tests :: [TestCase]+tests =+	[ TestCase "version" getVersion+	, TestCase "git" $ requireCmd "git" "git --version >/dev/null"+	, TestCase "git version" getGitVersion+	, testCp "cp_a" "-a"+	, testCp "cp_p" "-p"+	, testCp "cp_reflink_auto" "--reflink=auto"+	, TestCase "uuid generator" $ selectCmd "uuid" ["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"+	, TestCase "wget" $ testCmd "wget" "wget --version >/dev/null"+	, TestCase "bup" $ testCmd "bup" "bup --version >/dev/null"+	, TestCase "gpg" $ testCmd "gpg" "gpg --version >/dev/null"+	, TestCase "ssh connection caching" getSshConnectionCaching+	] ++ shaTestCases [1, 256, 512, 224, 384]++shaTestCases :: [Int] -> [TestCase]+shaTestCases l = map make l+	where make n =+		let+			cmds = map (\x -> "sha" ++ show n ++ x) ["", "sum"]+			key = "sha" ++ show n+		in TestCase key $ maybeSelectCmd key cmds "</dev/null"++tmpDir :: String+tmpDir = "tmp"++testFile :: String+testFile = tmpDir ++ "/testfile"++testCp :: ConfigKey -> String -> TestCase+testCp k option = TestCase cmd $ testCmd k cmdline+	where+		cmd = "cp " ++ option+		cmdline = cmd ++ " " ++ testFile ++ " " ++ testFile ++ ".new"++{- Pulls package version out of the changelog. -}+getVersion :: Test+getVersion = do+	version <- getVersionString+	return $ Config "packageversion" (StringConfig version)+	+getVersionString :: IO String+getVersionString = do+	changelog <- readFile "CHANGELOG"+	let verline = head $ lines changelog+	return $ middle (words verline !! 1)+	where+		middle = drop 1 . init++getGitVersion :: Test+getGitVersion = do+	(_, s) <- pipeFrom "git" ["--version"]+	let version = last $ words $ head $ lines s+	return $ Config "gitversion" (StringConfig version)++getSshConnectionCaching :: Test+getSshConnectionCaching = Config "sshconnectioncaching" . BoolConfig <$>+	boolSystem "sh" [Param "-c", Param "ssh -o ControlPersist=yes -V >/dev/null 2>/dev/null"]++{- Set up cabal file with version. -}+cabalSetup :: IO ()+cabalSetup = do+	version <- getVersionString+	cabal <- readFile cabalfile+	writeFile tmpcabalfile $ unlines $ +		map (setfield "Version" version) $+		lines cabal+	renameFile tmpcabalfile cabalfile+	where+		cabalfile = "git-annex.cabal"+		tmpcabalfile = cabalfile++".tmp"+		setfield field value s+			| fullfield `isPrefixOf` s = fullfield ++ value+			| otherwise = s+			where+				fullfield = field ++ ": "++setup :: IO ()+setup = do+	createDirectoryIfMissing True tmpDir+	writeFile testFile "test file contents"++cleanup :: IO ()+cleanup = removeDirectoryRecursive tmpDir++run :: [TestCase] -> IO ()+run ts = do+	setup+	config <- runTests ts+	writeSysConfig config+	cleanup+	cabalSetup
CHANGELOG view
@@ -1,3 +1,27 @@+git-annex (3.20120315) unstable; urgency=low++  * fsck: Fix up any broken links and misplaced content caused by the+    directory hash calculation bug fixed in the last release.+  * sync: Sync to lower cost remotes first.+  * status: Fixed to run in constant space.+  * status: More accurate display of sizes of tmp and bad keys.+  * unused: Now uses a bloom filter, and runs in constant space.+    Use of a bloom filter does mean it will not notice a small+    number of unused keys. For repos with up to half a million keys,+    it will miss one key in 1000.+  * Added annex.bloomcapacity and annex.bloomaccuracy, which can be+    adjusted as desired to tune the bloom filter.+  * status: Display amount of memory used by bloom filter, and+    detect when it's too small for the number of keys in a repository.+  * git-annex-shell: Runs hooks/annex-content after content is received+    or dropped.+  * Work around a bug in rsync (IMHO) introduced by openSUSE's SIP patch.+  * git-annex now behaves as git-annex-shell if symlinked to and run by that+    name. The Makefile sets this up, saving some 8 mb of installed size.+  * git-union-merge is a demo program, so it is no longer built by default.++ -- Joey Hess <joeyh@debian.org>  Thu, 15 Mar 2012 11:05:28 -0400+ git-annex (3.20120309) unstable; urgency=low    * Fix key directory hash calculation code to behave as it did before 
Command.hs view
@@ -65,9 +65,7 @@  {- Stops unless a condition is met. -} stopUnless :: Annex Bool -> Annex (Maybe a) -> Annex (Maybe a)-stopUnless c a = do-	ok <- c-	if ok then a else stop+stopUnless c a = ifM c ( a , stop )  {- Prepares to run a command via the check and seek stages, returning a  - list of actions to perform to run the command. -}
Command/Add.hs view
@@ -85,8 +85,9 @@ 				mtime <- modificationTime <$> getFileStatus file 				touch file (TimeSpec mtime) False -	force <- Annex.getState Annex.force-	if force-		then Annex.Queue.add "add" [Param "-f", Param "--"] [file]-		else Annex.Queue.add "add" [Param "--"] [file]+	params <- ifM (Annex.getState Annex.force)+		( return [Param "-f"]+		, return []+		)+	Annex.Queue.add "add" (params++[Param "--"]) [file] 	return True
Command/AddUrl.hs view
@@ -51,17 +51,17 @@ 	where 		geturl = do 			liftIO $ createDirectoryIfMissing True (parentDir file)-			fast <- Annex.getState Annex.fast-			if fast then nodownload url file else download url file-		addurl (key, _backend) = do-			ok <- liftIO $ Url.check url (keySize key)-			if ok-				then do+			ifM (Annex.getState Annex.fast)+				( nodownload url file , download url file )+		addurl (key, _backend) =+			ifM (liftIO $ Url.check url $ keySize key)+				( do 					setUrlPresent key url 					next $ return True-				else do+				, do 					warning $ "failed to verify url: " ++ url 					stop+				)  download :: String -> FilePath -> CommandPerform download url file = do
Command/Commit.hs view
@@ -7,8 +7,10 @@  module Command.Commit where +import Common.Annex import Command import qualified Annex.Branch+import qualified Git  def :: [Command] def = [command "commit" paramNothing seek@@ -20,4 +22,8 @@ start :: CommandStart start = next $ next $ do 	Annex.Branch.commit "update"+	_ <- runhook =<< (inRepo $ Git.hookPath "annex-content") 	return True+	where+		runhook (Just hook) = liftIO $ boolSystem hook []+		runhook Nothing = return True
Command/Fsck.hs view
@@ -10,6 +10,7 @@ import Common.Annex import Command import qualified Annex+import qualified Annex.Queue import qualified Remote import qualified Types.Backend import qualified Types.Key@@ -51,7 +52,8 @@ perform :: Key -> FilePath -> Backend -> Maybe Int -> CommandPerform perform key file backend numcopies = check 	-- order matters-	[ verifyLocationLog key file+	[ fixLink key file+	, verifyLocationLog key file 	, checkKeySize key 	, checkBackend backend key 	, checkKeyNumCopies key file numcopies@@ -60,17 +62,18 @@ {- To fsck a remote, the content is retrieved to a tmp file,  - and checked locally. -} performRemote :: Key -> FilePath -> Backend -> Maybe Int -> Remote -> CommandPerform-performRemote key file backend numcopies remote = do-	v <- Remote.hasKey remote key-	case v of-		Left err -> do+performRemote key file backend numcopies remote =+	dispatch =<< Remote.hasKey remote key+	where+		dispatch (Left err) = do 			showNote err 			stop-		Right True -> withtmp $ \tmpfile -> do-			copied <- getfile tmpfile-			if copied then go True (Just tmpfile) else go True Nothing-		Right False -> go False Nothing-	where+		dispatch (Right True) = withtmp $ \tmpfile ->+			ifM (getfile tmpfile)+				( go True (Just tmpfile)+				, go True Nothing+				)+		dispatch (Right False) = go False Nothing 		go present localcopy = check 			[ verifyLocationLogRemote key file remote present 			, checkKeySizeRemote key remote localcopy@@ -85,15 +88,14 @@ 			let cleanup = liftIO $ catchIO (removeFile tmp) (const $ return ()) 			cleanup 			cleanup `after` a tmp-		getfile tmp = do-			ok <- Remote.retrieveKeyFileCheap remote key tmp-			if ok-				then return ok-				else do-					fast <- Annex.getState Annex.fast-					if fast-						then return False-						else Remote.retrieveKeyFile remote key tmp+		getfile tmp =+			ifM (Remote.retrieveKeyFileCheap remote key tmp)+				( return True+				, ifM (Annex.getState Annex.fast)+					( return False+					, Remote.retrieveKeyFile remote key tmp+					)+				)  {- To fsck a bare repository, fsck each key in the location log. -} withBarePresentKeys :: (Key -> CommandStart) -> CommandSeek@@ -129,6 +131,32 @@ 			| all (== True) vs = next $ return True 			| otherwise = stop ++{- Checks that the file's symlink points correctly to the content. -}+fixLink :: Key -> FilePath -> Annex Bool+fixLink key file = do+	want <- calcGitLink file key+	have <- liftIO $ readSymbolicLink file+	when (want /= have) $ do+		{- Version 3.20120227 had a bug that could cause content+		 - to be stored in the wrong hash directory. Clean up+		 - after the bug by moving the content.+		 -}+		whenM (liftIO $ doesFileExist file) $+			unlessM (inAnnex key) $ do+				showNote $ "fixing content location"+				dir <- liftIO $ parentDir <$> absPath file+				let content = absPathFrom dir have+				liftIO $ allowWrite (parentDir content)+				moveAnnex key content++		showNote $ "fixing link"+		liftIO $ createDirectoryIfMissing True (parentDir file)+		liftIO $ removeFile file+		liftIO $ createSymbolicLink want file+		Annex.Queue.add "add" [Param "--force", Param "--"] [file]+	return True+ {- Checks that the location log reflects the current status of the key,    in this repository only. -} verifyLocationLog :: Key -> String -> Annex Bool@@ -177,10 +205,10 @@ checkKeySize :: Key -> Annex Bool checkKeySize key = do 	file <- inRepo $ gitAnnexLocation key-	present <- liftIO $ doesFileExist file-	if present-		then checkKeySize' key file badContent-		else return True+	ifM (liftIO $ doesFileExist file)+		( checkKeySize' key file badContent+		, return True+		)  checkKeySizeRemote :: Key -> Remote -> Maybe FilePath -> Annex Bool checkKeySizeRemote _ _ Nothing = return True@@ -191,16 +219,22 @@ checkKeySize' key file bad = case Types.Key.keySize key of 	Nothing -> return True 	Just size -> do-		stat <- liftIO $ getFileStatus file-		let size' = fromIntegral (fileSize stat)-		if size == size'-			then return True-			else do-				msg <- bad key-				warning $ "Bad file size (" ++-					compareSizes storageUnits True size size' ++-					"); " ++ msg-				return False+		size' <- fromIntegral . fileSize+			<$> (liftIO $ getFileStatus file)+		comparesizes size size'+	where+		comparesizes a b = do+			let same = a == b+			unless same $ badsize a b+			return same+		badsize a b = do+			msg <- bad key+			warning $ concat+				[ "Bad file size ("+				, compareSizes storageUnits True a b+				, "); "+				, msg+				]  checkBackend :: Backend -> Key -> Annex Bool checkBackend backend key = do
Command/Get.hs view
@@ -42,37 +42,29 @@ {- Try to find a copy of the file in one of the remotes,  - and copy it to here. -} getKeyFile :: Key -> FilePath -> Annex Bool-getKeyFile key file = do-	remotes <- Remote.keyPossibilities key-	if null remotes-		then do+getKeyFile key file = dispatch =<< Remote.keyPossibilities key+	where+		dispatch [] = do 			showNote "not available" 			Remote.showLocations key [] 			return False-		else trycopy remotes remotes-	where+		dispatch remotes = trycopy remotes remotes 		trycopy full [] = do 			Remote.showTriedRemotes full 			Remote.showLocations key [] 			return False-		trycopy full (r:rs) = do-			probablythere <- probablyPresent r-			if probablythere-				then docopy r (trycopy full rs)-				else trycopy full rs+		trycopy full (r:rs) =+			ifM (probablyPresent r)+				( docopy r (trycopy full rs)+				, trycopy full rs+				) 		-- This check is to avoid an ugly message if a remote is a 		-- drive that is not mounted.-		probablyPresent r =-			if Remote.hasKeyCheap r-				then do-					res <- Remote.hasKey r key-					case res of-						Right b -> return b-						Left _ -> return False-				else return True+		probablyPresent r+			| Remote.hasKeyCheap r =+				either (const False) id <$> Remote.hasKey r key+			| otherwise = return True 		docopy r continue = do 			showAction $ "from " ++ Remote.name r-			copied <- Remote.retrieveKeyFile r key file-			if copied-				then return True-				else continue+			ifM (Remote.retrieveKeyFile r key file)+				( return True , continue)
Command/Map.hs view
@@ -41,14 +41,14 @@ 	trusted <- trustGet Trusted  	liftIO $ writeFile file (drawMap rs umap trusted)-	next $ next $ do-		fast <- Annex.getState Annex.fast-		if fast-			then return True-			else do+	next $ next $+		ifM (Annex.getState Annex.fast)+			( return True+			, do 				showLongNote $ "running: dot -Tx11 " ++ file 				showOutput 				liftIO $ boolSystem "dot" [Param "-Tx11", File file]+			) 	where 		file = "map.dot" 
Command/Move.hs view
@@ -131,13 +131,13 @@ 			return $ u /= Remote.uuid src && any (== src) remotes fromPerform :: Remote -> Bool -> Key -> CommandPerform fromPerform src move key = moveLock move key $ do-	ishere <- inAnnex key-	if ishere-		then handle move True-		else do+	ifM (inAnnex key)+		( handle move True+		, do 			showAction $ "from " ++ Remote.name src 			ok <- getViaTmp key $ Remote.retrieveKeyFile src key 			handle move ok+		) 	where 		handle _ False = stop -- failed 		handle False True = next $ return True -- copy complete
Command/PreCommit.hs view
@@ -7,6 +7,7 @@  module Command.PreCommit where +import Common.Annex import Command import qualified Command.Add import qualified Command.Fix@@ -26,7 +27,6 @@  perform :: FilePath -> CommandPerform perform file = do-	ok <- doCommand $ Command.Add.start file-	if ok-		then next $ return True-		else error $ "failed to add " ++ file ++ "; canceling commit"+	unlessM (doCommand $ Command.Add.start file) $+		error $ "failed to add " ++ file ++ "; canceling commit"+	next $ return True
Command/Status.hs view
@@ -5,12 +5,12 @@  - Licensed under the GNU GPL version 3 or higher.  -} +{-# LANGUAGE BangPatterns #-}+ module Command.Status where  import Control.Monad.State.Strict import qualified Data.Map as M-import qualified Data.Set as S-import Data.Set (Set) import Text.JSON  import Common.Annex@@ -32,10 +32,18 @@ -- a named computation that produces a statistic type Stat = StatState (Maybe (String, StatState String)) --- cached info that multiple Stats may need+-- data about a set of keys+data KeyData = KeyData+	{ countKeys :: Integer+	, sizeKeys :: Integer+	, unknownSizeKeys :: Integer+	, backendsKeys :: M.Map String Integer+	}++-- cached info that multiple Stats use data StatInfo = StatInfo-	{ keysPresentCache :: Maybe (Set Key)-	, keysReferencedCache :: Maybe (Set Key)+	{ presentData :: Maybe KeyData+	, referencedData :: Maybe KeyData 	}  -- a state monad for running Stats in@@ -68,6 +76,7 @@ 	, local_annex_size 	, known_annex_keys 	, known_annex_size+	, bloom_info 	, backend_usage 	] @@ -119,22 +128,38 @@ 	return $ if null s then "0" else show (length rs) ++ "\n" ++ beginning s 	where 		n = desc ++ " repositories"-+	 local_annex_size :: Stat local_annex_size = stat "local annex size" $ json id $-	keySizeSum <$> cachedKeysPresent+	showSizeKeys <$> cachedPresentData  local_annex_keys :: Stat local_annex_keys = stat "local annex keys" $ json show $-	S.size <$> cachedKeysPresent+	countKeys <$> cachedPresentData +bloom_info :: Stat+bloom_info = stat "bloom filter size" $ json id $ do+	localkeys <- countKeys <$> cachedPresentData+	capacity <- fromIntegral <$> lift Command.Unused.bloomCapacity+	let note = aside $+		if localkeys >= capacity+		then "appears too small for this repository; adjust annex.bloomcapacity"+		else "has room for " ++ show (capacity - localkeys) ++ " more local annex keys"++	-- Two bloom filters are used at the same time, so double the size+	-- of one.+	size <- roughSize memoryUnits True . (* 2) . fromIntegral . fst <$>+		lift Command.Unused.bloomBitsHashes++	return $ size ++ note+ known_annex_size :: Stat known_annex_size = stat "known annex size" $ json id $-	keySizeSum <$> cachedKeysReferenced+	showSizeKeys <$> cachedReferencedData  known_annex_keys :: Stat known_annex_keys = stat "known annex keys" $ json show $-	S.size <$> cachedKeysReferenced+	countKeys <$> cachedReferencedData  tmp_size :: Stat tmp_size = staleSize "temporary directory size" gitAnnexTmpDir@@ -144,55 +169,78 @@  backend_usage :: Stat backend_usage = stat "backend usage" $ nojson $-	calc <$> cachedKeysReferenced <*> cachedKeysPresent+	calc+		<$> (backendsKeys <$> cachedReferencedData)+		<*> (backendsKeys <$> cachedPresentData) 	where-		calc a b = pp "" $ reverse . sort $ map swap $ splits $ S.toList $ S.union a b-		splits :: [Key] -> [(String, Integer)]-		splits ks = M.toList $ M.fromListWith (+) $ map tcount ks-		tcount k = (keyBackendName k, 1)-		swap (a, b) = (b, a)+		calc a b = pp "" $ reverse . sort $ map swap $ M.toList $ M.unionWith (+) a b 		pp c [] = c 		pp c ((n, b):xs) = "\n\t" ++ b ++ ": " ++ show n ++ pp c xs+		swap (a, b) = (b, a) -cachedKeysPresent :: StatState (Set Key)-cachedKeysPresent = do+cachedPresentData :: StatState KeyData+cachedPresentData = do 	s <- get-	case keysPresentCache s of+	case presentData s of 		Just v -> return v 		Nothing -> do-			keys <- S.fromList <$> lift getKeysPresent-			put s { keysPresentCache = Just keys }-			return keys+			v <- foldKeys <$> lift getKeysPresent+			put s { presentData = Just v }+			return v -cachedKeysReferenced :: StatState (Set Key)-cachedKeysReferenced = do+cachedReferencedData :: StatState KeyData+cachedReferencedData = do 	s <- get-	case keysReferencedCache s of+	case referencedData s of 		Just v -> return v 		Nothing -> do-			keys <- S.fromList <$> lift Command.Unused.getKeysReferenced-			put s { keysReferencedCache = Just keys }-			return keys+			!v <- lift $ Command.Unused.withKeysReferenced+				emptyKeyData addKey+			put s { referencedData = Just v }+			return v -keySizeSum :: Set Key -> String-keySizeSum s = total ++ missingnote+emptyKeyData :: KeyData+emptyKeyData = KeyData 0 0 0 M.empty++foldKeys :: [Key] -> KeyData+foldKeys = foldl' (flip addKey) emptyKeyData++addKey :: Key -> KeyData -> KeyData+addKey key (KeyData count size unknownsize backends) =+	KeyData count' size' unknownsize' backends' 	where-		knownsizes = mapMaybe keySize $ S.toList s-		total = roughSize storageUnits False $ sum knownsizes-		missing = S.size s - genericLength knownsizes+		{- All calculations strict to avoid thunks when repeatedly+		 - applied to many keys. -}+		!count' = count + 1+		!backends' = M.insertWith' (+) (keyBackendName key) 1 backends+		!size' = maybe size (+ size) ks+		!unknownsize' = maybe (unknownsize + 1) (const unknownsize) ks+		ks = keySize key++showSizeKeys :: KeyData -> String+showSizeKeys d = total ++ missingnote+	where+		total = roughSize storageUnits False $ sizeKeys d 		missingnote-			| missing == 0 = ""+			| unknownSizeKeys d == 0 = "" 			| otherwise = aside $-				"+ " ++ show missing +++				"+ " ++ show (unknownSizeKeys d) ++ 				" keys of unknown size"  staleSize :: String -> (Git.Repo -> FilePath) -> Stat-staleSize label dirspec = do-	keys <- lift (Command.Unused.staleKeys dirspec)-	if null keys-		then nostat-		else stat label $ json (++ aside "clean up with git-annex unused") $-			return $ keySizeSum $ S.fromList keys+staleSize label dirspec = go =<< lift (Command.Unused.staleKeys dirspec)+	where+		go [] = nostat+		go keys = onsize =<< sum <$> keysizes keys+		onsize 0 = nostat+		onsize size = stat label $+			json (++ aside "clean up with git-annex unused") $+				return $ roughSize storageUnits False size+		keysizes keys = map (fromIntegral . fileSize) <$> stats keys+		stats keys = do+			dir <- lift $ fromRepo dirspec+			liftIO $ forM keys $ \k ->+				getFileStatus (dir </> keyFile k)  aside :: String -> String aside s = " (" ++ s ++ ")"
Command/Sync.hs view
@@ -51,22 +51,18 @@ remoteBranch remote = Git.Ref.under $ "refs/remotes/" ++ Remote.name remote  syncRemotes :: [String] -> Annex [Remote]-syncRemotes rs = do-	fast <- Annex.getState Annex.fast-	if fast-		then nub <$> pickfast-		else wanted+syncRemotes rs = ifM (Annex.getState Annex.fast) ( nub <$> pickfast , wanted ) 	where 		pickfast = (++) <$> listed <*> (good =<< fastest <$> available) 		wanted-			| null rs = good =<< available+			| null rs = good =<< concat . byspeed <$> available 			| otherwise = listed 		listed = catMaybes <$> mapM (Remote.byName . Just) rs 		available = filter nonspecial <$> Remote.enabledRemoteList 		good = filterM $ Remote.Git.repoAvail . Types.Remote.repo 		nonspecial r = Types.Remote.remotetype r == Remote.Git.remote-		fastest = fromMaybe [] . headMaybe .-			map snd . sort . M.toList . costmap+		fastest = fromMaybe [] . headMaybe . byspeed+		byspeed = map snd . sort . M.toList . costmap 		costmap = M.fromListWith (++) . map costpair 		costpair r = (Types.Remote.cost r, [r]) @@ -113,11 +109,11 @@ 	showStart "pull" (Remote.name remote) 	next $ do 		showOutput-		fetched <- inRepo $ Git.Command.runBool "fetch"+		stopUnless fetch $+			next $ mergeRemote remote branch+	where+		fetch = inRepo $ Git.Command.runBool "fetch" 			[Param $ Remote.name remote]-		if fetched-			then next $ mergeRemote remote branch-			else stop  {- The remote probably has both a master and a synced/master branch.  - Which to merge from? Well, the master has whatever latest changes@@ -159,15 +155,15 @@ changed :: Remote -> Git.Ref -> Annex Bool changed remote b = do 	let r = remoteBranch remote b-	e <- inRepo $ Git.Ref.exists r-	if e-		then inRepo $ Git.Branch.changed b r-		else return False+	ifM (inRepo $ Git.Ref.exists r)+		( inRepo $ Git.Branch.changed b r+		, return False+		)  newer :: Remote -> Git.Ref -> Annex Bool newer remote b = do 	let r = remoteBranch remote b-	e <- inRepo $ Git.Ref.exists r-	if e-		then inRepo $ Git.Branch.changed r b-		else return True+	ifM (inRepo $ Git.Ref.exists r)+		( inRepo $ Git.Branch.changed r b+		, return True+		)
Command/Unannex.hs view
@@ -47,16 +47,16 @@ 			Params "-m", Param "content removed from git annex", 			Param "--", File file] -	fast <- Annex.getState Annex.fast-	if fast-		then do+	ifM (Annex.getState Annex.fast)+		( do 			-- fast mode: hard link to content in annex 			src <- inRepo $ gitAnnexLocation key 			liftIO $ do 				createLink src file 				allowWrite file-		else do+		, do 			fromAnnex key file 			logStatus key InfoMissing+		)  	return True
Command/Unused.hs view
@@ -1,6 +1,6 @@ {- git-annex command  -- - Copyright 2010-2011 Joey Hess <joey@kitenet.net>+ - Copyright 2010-2012 Joey Hess <joey@kitenet.net>  -  - Licensed under the GNU GPL version 3 or higher.  -}@@ -12,6 +12,10 @@ import qualified Data.Set as S import qualified Data.Text.Lazy as L import qualified Data.Text.Lazy.Encoding as L+import Data.BloomFilter+import Data.BloomFilter.Easy+import Data.BloomFilter.Hash+import Control.Monad.ST  import Common.Annex import Command@@ -25,6 +29,7 @@ import qualified Git.Ref import qualified Git.LsFiles as LsFiles import qualified Git.LsTree as LsTree+import qualified Git.Config import qualified Backend import qualified Remote import qualified Annex.Branch@@ -54,33 +59,45 @@ 	next action  checkUnused :: CommandPerform-checkUnused = do-	(unused, stalebad, staletmp) <- unusedKeys-	_ <- list "" unusedMsg unused 0 >>=-		list "bad" staleBadMsg stalebad >>=-			list "tmp" staleTmpMsg staletmp-	next $ return True+checkUnused = chain 0+	[ check "" unusedMsg $ findunused =<< Annex.getState Annex.fast+	, check "bad" staleBadMsg $ staleKeysPrune gitAnnexBadDir+	, check "tmp" staleTmpMsg $ staleKeysPrune gitAnnexTmpDir+	] 	where-		list file msg l c = do-			let unusedlist = number c l-			unless (null l) $ showLongNote $ msg unusedlist-			writeUnusedFile file unusedlist-			return $ c + length l+		findunused True = do+			showNote "fast mode enabled; only finding stale files"+			return []+		findunused False = do+			showAction "checking for unused data"+			excludeReferenced =<< getKeysPresent+		chain _ [] = next $ return True+		chain v (a:as) = do+			v' <- a v+			chain v' as  checkRemoteUnused :: String -> CommandPerform-checkRemoteUnused name = do-	checkRemoteUnused' =<< fromJust <$> Remote.byName (Just name)-	next $ return True+checkRemoteUnused name = go =<< fromJust <$> Remote.byName (Just name)+	where+		go r = do+			showAction "checking for unused data"+			_ <- check "" (remoteUnusedMsg r) (remoteunused r) 0+			next $ return True+		remoteunused r =+			excludeReferenced =<< loggedKeysFor (Remote.uuid r) -checkRemoteUnused' :: Remote -> Annex ()-checkRemoteUnused' r = do-	showAction "checking for unused data"-	remotehas <- loggedKeysFor (Remote.uuid r)-	remoteunused <- excludeReferenced remotehas-	let list = number 0 remoteunused-	writeUnusedFile "" list-	unless (null remoteunused) $ showLongNote $ remoteUnusedMsg r list+check :: FilePath -> ([(Int, Key)] -> String) -> Annex [Key] -> Int -> Annex Int+check file msg a c = do+	l <- a+	let unusedlist = number c l+	unless (null l) $ showLongNote $ msg unusedlist+	writeUnusedFile file unusedlist+	return $ c + length l +number :: Int -> [a] -> [(Int, a)]+number _ [] = []+number n (x:xs) = (n+1, x) : number (n+1) xs+ writeUnusedFile :: FilePath -> [(Int, Key)] -> Annex () writeUnusedFile prefix l = do 	logfile <- fromRepo $ gitAnnexUnusedLog prefix@@ -93,10 +110,6 @@ 		cols (n,k) = "  " ++ pad 6 (show n) ++ "  " ++ show k 		pad n s = s ++ replicate (n - length s) ' ' -number :: Int -> [a] -> [(Int, a)]-number _ [] = []-number n (x:xs) = (n+1, x) : number (n+1) xs- staleTmpMsg :: [(Int, Key)] -> String staleTmpMsg t = unlines $  	["Some partially transferred data exists in temporary files:"]@@ -131,49 +144,32 @@ dropMsg' :: String -> String dropMsg' s = "\nTo remove unwanted data: git-annex dropunused" ++ s ++ " NUMBER\n" -{- Finds keys whose content is present, but that do not seem to be used- - by any files in the git repo, or that are only present as bad or tmp- - files. -}-unusedKeys :: Annex ([Key], [Key], [Key])-unusedKeys = do-	fast <- Annex.getState Annex.fast-	if fast-		then do-			showNote "fast mode enabled; only finding stale files"-			tmp <- staleKeys gitAnnexTmpDir-			bad <- staleKeys gitAnnexBadDir-			return ([], bad, tmp)-		else do-			showAction "checking for unused data"-			present <- getKeysPresent-			unused <- excludeReferenced present-			staletmp <- staleKeysPrune gitAnnexTmpDir present-			stalebad <- staleKeysPrune gitAnnexBadDir present-			return (unused, stalebad, staletmp)--{- Finds keys in the list that are not referenced in the git repository. -}+{- Finds keys in the list that are not referenced in the git repository.+ -+ - Strategy:+ -+ - * Build a bloom filter of all keys referenced by symlinks. This + -   is the fastest one to build and will filter out most keys.+ - * If keys remain, build a second bloom filter of keys referenced by+ -   all branches.+ - * The list is streamed through these bloom filters lazily, so both will+ -   exist at the same time. This means that twice the memory is used,+ -   but they're relatively small, so the added complexity of using a+ -   mutable bloom filter does not seem worthwhile.+ - * Generating the second bloom filter can take quite a while, since+ -   it needs enumerating all keys in all git branches. But, the common+ -   case, if the second filter is needed, is for some keys to be globally+ -   unused, and in that case, no short-circuit is possible.+ -   Short-circuiting if the first filter filters all the keys handles the+ -   other common case.+ -} excludeReferenced :: [Key] -> Annex [Key]-excludeReferenced [] = return [] -- optimisation-excludeReferenced l = do-	c <- inRepo $ Git.Command.pipeRead [Param "show-ref"]-	removewith (getKeysReferenced : map getKeysReferencedInGit (refs c))-		(S.fromList l)+excludeReferenced ks = runfilter firstlevel ks >>= runfilter secondlevel 	where-		-- Skip the git-annex branches, and get all other unique refs.-		refs = map (Git.Ref .  snd) .-			nubBy uniqref .-			filter ourbranches .-			map (separate (== ' ')) . lines-		uniqref (a, _) (b, _) = a == b-		ourbranchend = '/' : show Annex.Branch.name-		ourbranches (_, b) = not $ ourbranchend `isSuffixOf` b-		removewith [] s = return $ S.toList s-		removewith (a:as) s-			| s == S.empty = return [] -- optimisation-			| otherwise = do-				referenced <- a-				let !s' = s `S.difference` S.fromList referenced-				removewith as s'+		runfilter _ [] = return [] -- optimisation+		runfilter a l = bloomFilter show l <$> genBloomFilter show a+		firstlevel = withKeysReferencedM+		secondlevel = withKeysReferencedInGit  {- Finds items in the first, smaller list, that are not  - present in the second, larger list.@@ -187,41 +183,113 @@ 	where 		remove a b = foldl (flip S.delete) b a -{- List of keys referenced by symlinks in the git repo. -}-getKeysReferenced :: Annex [Key]-getKeysReferenced = do-	top <- fromRepo Git.workTree-	files <- inRepo $ LsFiles.inRepo [top]-	keypairs <- mapM Backend.lookupFile files-	return $ map fst $ catMaybes keypairs+{- A bloom filter capable of holding half a million keys with a+ - false positive rate of 1 in 1000 uses around 8 mb of memory,+ - so will easily fit on even my lowest memory systems.+ -}+bloomCapacity :: Annex Int+bloomCapacity = fromMaybe 500000 . readish+	<$> fromRepo (Git.Config.get "annex.bloomcapacity" "")+bloomAccuracy :: Annex Int+bloomAccuracy = fromMaybe 1000 . readish+	<$> fromRepo (Git.Config.get "annex.bloomaccuracy" "")+bloomBitsHashes :: Annex (Int, Int)+bloomBitsHashes = do+	capacity <- bloomCapacity+	accuracy <- bloomAccuracy+	return $ suggestSizing capacity (1/ fromIntegral accuracy) -{- List of keys referenced by symlinks in a git ref. -}-getKeysReferencedInGit :: Git.Ref -> Annex [Key]-getKeysReferencedInGit ref = do+{- Creates a bloom filter, and runs an action, such as withKeysReferenced,+ - to populate it.+ -+ - The action is passed a callback that it can use to feed values into the+ - bloom filter. + -+ - Once the action completes, the mutable filter is frozen+ - for later use.+ -}+genBloomFilter :: Hashable t => (v -> t) -> ((v -> Annex ()) -> Annex b) -> Annex (Bloom t)+genBloomFilter convert populate = do+	(numbits, numhashes) <- bloomBitsHashes+	bloom <- lift $ newMB (cheapHashes numhashes) numbits+	_ <- populate $ \v -> lift $ insertMB bloom (convert v)+	lift $ unsafeFreezeMB bloom+	where+		lift = liftIO . stToIO++bloomFilter :: Hashable t => (v -> t) -> [v] -> Bloom t -> [v]+bloomFilter convert l bloom = filter (\k -> convert k `notElemB` bloom) l++{- Given an initial value, folds it with each key referenced by+ - symlinks in the git repo. -}+withKeysReferenced :: v -> (Key -> v -> v) -> Annex v+withKeysReferenced initial a = withKeysReferenced' initial folda+	where+		folda k v = return $ a k v++{- Runs an action on each referenced key in the git repo. -}+withKeysReferencedM :: (Key -> Annex ()) -> Annex ()+withKeysReferencedM a = withKeysReferenced' () calla+	where+		calla k _ = a k++withKeysReferenced' :: v -> (Key -> v -> Annex v) -> Annex v+withKeysReferenced' initial a = go initial =<< files+	where+		files = do+			top <- fromRepo Git.workTree+			inRepo $ LsFiles.inRepo [top]+		go v [] = return v+		go v (f:fs) = do+			x <- Backend.lookupFile f+			case x of+				Nothing -> go v fs+				Just (k, _) -> do+					!v' <- a k v+					go v' fs+++withKeysReferencedInGit :: (Key -> Annex ()) -> Annex ()+withKeysReferencedInGit a = do+	rs <- relevantrefs <$> showref+	forM_ rs (withKeysReferencedInGitRef a)+	where+		showref = inRepo $ Git.Command.pipeRead [Param "show-ref"]+		relevantrefs = map (Git.Ref .  snd) .+			nubBy uniqref .+			filter ourbranches .+			map (separate (== ' ')) . lines+		uniqref (x, _) (y, _) = x == y+		ourbranchend = '/' : show Annex.Branch.name+		ourbranches (_, b) = not $ ourbranchend `isSuffixOf` b++withKeysReferencedInGitRef :: (Key -> Annex ()) -> Git.Ref -> Annex ()+withKeysReferencedInGitRef a ref = do 	showAction $ "checking " ++ Git.Ref.describe ref-	findkeys [] =<< inRepo (LsTree.lsTree ref)+	go =<< inRepo (LsTree.lsTree ref) 	where-		findkeys c [] = return c-		findkeys c (l:ls)+		go [] = return ()+		go (l:ls) 			| isSymLink (LsTree.mode l) = do 				content <- L.decodeUtf8 <$> catFile ref (LsTree.file l) 				case fileKey (takeFileName $ L.unpack content) of-					Nothing -> findkeys c ls-					Just k -> findkeys (k:c) ls-			| otherwise = findkeys c ls+					Nothing -> go ls+					Just k -> do+						a k+						go ls+			| otherwise = go ls  {- Looks in the specified directory for bad/tmp keys, and returns a list- - of those that might still have value, or might be stale and removable. + - of those that might still have value, or might be stale and removable.  - - - When a list of presently available keys is provided, stale keys- - that no longer have value are deleted.+ - Also, stale keys that can be proven to have no value are deleted.  -}-staleKeysPrune :: (Git.Repo -> FilePath) -> [Key] -> Annex [Key]-staleKeysPrune dirspec present = do+staleKeysPrune :: (Git.Repo -> FilePath) -> Annex [Key]+staleKeysPrune dirspec = do 	contents <- staleKeys dirspec 	-	let stale = contents `exclude` present-	let dups = contents `exclude` stale+	dups <- filterM inAnnex contents+	let stale = contents `exclude` dups  	dir <- fromRepo dirspec 	liftIO $ forM_ dups $ \t -> removeFile $ dir </> keyFile t@@ -231,11 +299,11 @@ staleKeys :: (Git.Repo -> FilePath) -> Annex [Key] staleKeys dirspec = do 	dir <- fromRepo dirspec-	exists <- liftIO $ doesDirectoryExist dir-	if not exists-		then return []-		else do+	ifM (liftIO $ doesDirectoryExist dir)+		( do 			contents <- liftIO $ getDirectoryContents dir 			files <- liftIO $ filterM doesFileExist $ 				map (dir </>) contents 			return $ mapMaybe (fileKey . takeFileName) files+		, return []+		)
Git.hs view
@@ -24,15 +24,19 @@ 	gitDir, 	configTrue, 	attributes,+	hookPath, 	assertLocal, ) where  import qualified Data.Map as M import Data.Char import Network.URI (uriPath, uriScheme, unEscapeString)+import System.Directory+import System.Posix.Files  import Common import Git.Types+import Utility.FileMode  {- User-visible description of a git repo. -} repoDescribe :: Repo -> String@@ -93,16 +97,28 @@ 			" is a bare repository; config not read"  {- Path to a repository's gitattributes file. -}-attributes :: Repo -> String+attributes :: Repo -> FilePath attributes repo 	| configBare repo = workTree repo ++ "/info/.gitattributes" 	| otherwise = workTree repo ++ "/.gitattributes"  {- Path to a repository's .git directory. -}-gitDir :: Repo -> String+gitDir :: Repo -> FilePath gitDir repo 	| configBare repo = workTree repo 	| otherwise = workTree repo </> ".git"++{- Path to a given hook script in a repository, only if the hook exists+ - and is executable. -}+hookPath :: String -> Repo -> IO (Maybe FilePath)+hookPath script repo = do+	let hook = gitDir repo </> "hooks" </> script+	e <- doesFileExist hook+	if e+		then do+			m <- fileMode <$> getFileStatus hook+			return $ if isExecutable m then Just hook else Nothing+		else return Nothing  {- Path to a repository's --work-tree, that is, its top.  -
+ GitAnnexShell.hs view
@@ -0,0 +1,116 @@+{- git-annex-shell main program+ -+ - Copyright 2010 Joey Hess <joey@kitenet.net>+ -+ - Licensed under the GNU GPL version 3 or higher.+ -}++module GitAnnexShell where++import System.Environment+import System.Console.GetOpt++import Common.Annex+import qualified Git.Construct+import CmdLine+import Command+import Annex.UUID+import qualified Option++import qualified Command.ConfigList+import qualified Command.InAnnex+import qualified Command.DropKey+import qualified Command.RecvKey+import qualified Command.SendKey+import qualified Command.Commit++cmds_readonly :: [Command]+cmds_readonly = concat+	[ Command.ConfigList.def+	, Command.InAnnex.def+	, Command.SendKey.def+	]++cmds_notreadonly :: [Command]+cmds_notreadonly = concat+	[ Command.RecvKey.def+	, Command.DropKey.def+	, Command.Commit.def+	]++cmds :: [Command]+cmds = map adddirparam $ cmds_readonly ++ cmds_notreadonly+	where+		adddirparam c = c+			{ cmdparamdesc = "DIRECTORY " ++ cmdparamdesc c+			}++options :: [OptDescr (Annex ())]+options = Option.common +++	[ Option [] ["uuid"] (ReqArg checkuuid paramUUID) "repository uuid"+	]+	where+		checkuuid expected = getUUID >>= check+			where+				check u | u == toUUID expected = return ()+				check NoUUID = unexpected "uninitialized repository"+				check u = unexpected $ "UUID " ++ fromUUID u+				unexpected s = error $+					"expected repository UUID " +++					expected ++ " but found " ++ s++header :: String+header = "Usage: git-annex-shell [-c] command [parameters ...] [option ..]"++run :: [String] -> IO ()+run [] = failure+-- skip leading -c options, passed by eg, ssh+run ("-c":p) = run p+-- a command can be either a builtin or something to pass to git-shell+run c@(cmd:dir:params)+	| cmd `elem` builtins = builtin cmd dir params+	| otherwise = external c+run c@(cmd:_)+	-- Handle the case of being the user's login shell. It will be passed+	-- a single string containing all the real parameters.+	| "git-annex-shell " `isPrefixOf` cmd = run $ drop 1 $ shellUnEscape cmd+	| cmd `elem` builtins = failure+	| otherwise = external c++builtins :: [String]+builtins = map cmdname cmds++builtin :: String -> String -> [String] -> IO ()+builtin cmd dir params = do+	checkNotReadOnly cmd+	dispatch (cmd : filterparams params) cmds options header $+		Git.Construct.repoAbsPath dir >>= Git.Construct.fromAbsPath++external :: [String] -> IO ()+external params = do+	checkNotLimited+	unlessM (boolSystem "git-shell" $ map Param $ "-c":filterparams params) $+		error "git-shell failed"++-- Drop all args after "--".+-- These tend to be passed by rsync and not useful.+filterparams :: [String] -> [String]+filterparams [] = []+filterparams ("--":_) = []+filterparams (a:as) = a:filterparams as++failure :: IO ()+failure = error $ "bad parameters\n\n" ++ usage header cmds options++checkNotLimited :: IO ()+checkNotLimited = checkEnv "GIT_ANNEX_SHELL_LIMITED"++checkNotReadOnly :: String -> IO ()+checkNotReadOnly cmd+	| cmd `elem` map cmdname cmds_readonly = return ()+	| otherwise = checkEnv "GIT_ANNEX_SHELL_READONLY"++checkEnv :: String -> IO ()+checkEnv var =+	whenM (not . null <$> catchDefaultIO (getEnv var) "") $+		error $ "Action blocked by " ++ var
INSTALL view
@@ -35,6 +35,7 @@   * [hS3](http://hackage.haskell.org/package/hS3)   * [json](http://hackage.haskell.org/package/json)   * [IfElse](http://hackage.haskell.org/package/IfElse)+  * [bloomfilter](http://hackage.haskell.org/package/bloomfilter) * Shell commands   * [git](http://git-scm.com/)   * [uuid](http://www.ossp.org/pkg/lib/uuid/)
Init.hs view
@@ -38,23 +38,22 @@ ensureInitialized :: Annex () ensureInitialized = getVersion >>= maybe needsinit checkVersion 	where-		needsinit = do-			annexed <- Annex.Branch.hasSibling-			if annexed-				then initialize Nothing-				else error "First run: git-annex init"+		needsinit = ifM Annex.Branch.hasSibling+				( initialize Nothing+				, error "First run: git-annex init"+				)  {- set up a git pre-commit hook, if one is not already present -} gitPreCommitHookWrite :: Annex () gitPreCommitHookWrite = unlessBare $ do 	hook <- preCommitHook-	exists <- liftIO $ doesFileExist hook-	if exists-		then warning $ "pre-commit hook (" ++ hook ++ ") already exists, not configuring"-		else liftIO $ do+	ifM (liftIO $ doesFileExist hook)+		( warning $ "pre-commit hook (" ++ hook ++ ") already exists, not configuring"+		, liftIO $ do 			viaTmp writeFile hook preCommitScript 			p <- getPermissions hook 			setPermissions hook $ p {executable = True}+		)  gitPreCommitHookUnWrite :: Annex () gitPreCommitHookUnWrite = unlessBare $ do
Locations.hs view
@@ -218,12 +218,12 @@ hashDirMixed k = addTrailingPathSeparator $ take 2 dir </> drop 2 dir 	where 		dir = take 4 $ display_32bits_as_dir =<< [a,b,c,d]-		ABCD (a,b,c,d) = md5 $ Str $ encodeFilePath $ show k+		ABCD (a,b,c,d) = md5 $ encodeFilePath $ show k  hashDirLower :: Hasher hashDirLower k = addTrailingPathSeparator $ take 3 dir </> drop 3 dir 	where-		dir = take 6 $ md5s $ Str $ encodeFilePath $ show k+		dir = take 6 $ md5s $ encodeFilePath $ show k  {- modified version of display_32bits_as_hex from Data.Hash.MD5  -   Copyright (C) 2001 Ian Lynagh 
Makefile view
@@ -1,15 +1,16 @@ PREFIX=/usr IGNORE=-ignore-package monads-fd-GHCFLAGS=-O2 -Wall $(IGNORE)+BASEFLAGS=-Wall $(IGNORE) -outputdir tmp+GHCFLAGS=-O2 $(BASEFLAGS)  ifdef PROFILE-GHCFLAGS=-prof -auto-all -rtsopts -caf-all -fforce-recomp $(IGNORE)+GHCFLAGS=-prof -auto-all -rtsopts -caf-all -fforce-recomp $(BASEFLAGS) endif  GHCMAKE=ghc $(GHCFLAGS) --make -bins=git-annex git-annex-shell git-union-merge-mans=git-annex.1 git-annex-shell.1 git-union-merge.1+bins=git-annex+mans=git-annex.1 git-annex-shell.1 sources=Build/SysConfig.hs Utility/StatFS.hs Utility/Touch.hs  all=$(bins) $(mans) docs@@ -24,7 +25,7 @@ sources: $(sources)  # Disables optimisation. Not for production use.-fast: GHCFLAGS=-Wall $(IGNORE)+fast: GHCFLAGS=$(BASEFLAGS) fast: $(bins)  Build/SysConfig.hs: configure.hs Build/TestConfig.hs Utility/StatFS.hs@@ -33,7 +34,6 @@  %.hs: %.hsc 	hsc2hs $<-	perl -i -pe 's/^{-# INCLUDE.*//' $@  $(bins): $(sources) 	$(GHCMAKE) $@@@ -48,6 +48,7 @@ install: all 	install -d $(DESTDIR)$(PREFIX)/bin 	install $(bins) $(DESTDIR)$(PREFIX)/bin+	ln -sf git-annex $(DESTDIR)$(PREFIX)/bin/git-annex-shell 	install -d $(DESTDIR)$(PREFIX)/share/man/man1 	install -m 0644 $(mans) $(DESTDIR)$(PREFIX)/share/man/man1 	install -d $(DESTDIR)$(PREFIX)/share/doc/git-annex@@ -66,7 +67,7 @@  testcoverage: 	rm -f test.tix test-	ghc -odir build/test -hidir build/test $(GHCFLAGS) --make -fhpc test+	ghc $(GHCFLAGS) -outputdir tmp/testcoverage --make -fhpc test 	./test 	@echo "" 	@hpc report test --exclude=Main --exclude=QC@@ -90,9 +91,8 @@ 		--exclude='news/.*'  clean:-	rm -rf build $(bins) $(mans) test configure  *.tix .hpc $(sources)-	rm -rf doc/.ikiwiki html dist-	find . \( -name \*.o -or -name \*.hi \) -exec rm {} \;+	rm -rf tmp $(bins) $(mans) test configure  *.tix .hpc $(sources) \+		doc/.ikiwiki html dist  # Workaround for cabal sdist not running Setup hooks, so I cannot # generate a file list there.
Remote.hs view
@@ -70,19 +70,13 @@  - (Or it can be a UUID.) Only finds currently configured git remotes. -} byName :: Maybe String -> Annex (Maybe Remote) byName Nothing = return Nothing-byName (Just n) = do-	res <- byName' n-	case res of-		Left e -> error e-		Right r -> return $ Just r+byName (Just n) = either error Just <$> byName' n byName' :: String -> Annex (Either String Remote) byName' "" = return $ Left "no remote specified"-byName' n = do-	match <- filter matching <$> remoteList-	if null match-		then return $ Left $ "there is no git remote named \"" ++ n ++ "\""-		else return $ Right $ Prelude.head match+byName' n = handle . filter matching <$> remoteList 	where+		handle [] = Left $ "there is no git remote named \"" ++ n ++ "\""+		handle match = Right $ Prelude.head match 		matching r = n == name r || toUUID n == uuid r  {- Looks up a remote by name (or by UUID, or even by description),
Remote/Git.hs view
@@ -290,10 +290,13 @@ 		then return $ o ++ eparam ++ [dummy, File file] 		else return $ o ++ eparam ++ [File file, dummy] 	where-		-- the rsync shell parameter controls where rsync+		-- The rsync shell parameter controls where rsync 		-- goes, so the source/dest parameter can be a dummy value, 		-- that just enables remote rsync mode.-		dummy = Param ":"+		-- For maximum compatability with some patched rsyncs,+		-- the dummy value needs to still contain a hostname,+		-- even though this hostname will never be used.+		dummy = Param "dummy:"  rsyncParams :: Git.Repo -> Annex [CommandParam] rsyncParams r = do
Setup.hs view
@@ -3,15 +3,10 @@ import Distribution.Simple import System.Cmd -main = defaultMainWithHooks simpleUserHooks {-	preConf = makeSources,-	postClean = makeClean-}+import qualified Build.Configure as Configure -makeSources _ _ = do-	system "make sources"-	return (Nothing, [])+main = defaultMainWithHooks simpleUserHooks { preConf = configure } -makeClean _ _ _ _ = do-	system "make clean"-	return ()+configure _ _ = do+	Configure.run Configure.tests+	return (Nothing, [])
Usage.hs view
@@ -29,8 +29,8 @@ 		-- be displayed after the command. 		alloptlines = filter (not . null) $ 			lines $ usageInfo "" $-				concatMap cmdoptions cmds ++ commonoptions-		(cmdlines, optlines) = go (sort cmds) alloptlines []+				concatMap cmdoptions scmds ++ commonoptions+		(cmdlines, optlines) = go scmds alloptlines [] 		go [] os ls = (ls, os) 		go (c:cs) os ls = go cs os' (ls++(l:o)) 			where@@ -46,6 +46,7 @@ 		namepad = pad $ longest cmdname + 1 		descpad = pad $ longest cmdparamdesc + 2 		longest f = foldl max 0 $ map (length . f) cmds+		scmds = sort cmds  {- Descriptions of params used in usage messages. -} paramPaths :: String
Utility/Directory.hs view
@@ -13,10 +13,21 @@ import Control.Exception (throw) import Control.Monad import Control.Monad.IfElse+import System.FilePath+import Control.Applicative  import Utility.SafeCommand import Utility.TempFile import Utility.Exception++{- Lists the contents of a directory.+ - Unlike getDirectoryContents, paths are not relative to the directory. -}+dirContents :: FilePath -> IO [FilePath]+dirContents d = map (d </>) . filter notcruft <$> getDirectoryContents d+	where+		notcruft "." = False+		notcruft ".." = False+		notcruft _ = True  {- Moves one filename to another.  - First tries a rename, but falls back to moving across devices if needed. -}
Utility/FileMode.hs view
@@ -34,3 +34,10 @@ {- Checks if a file mode indicates it's a symlink. -} isSymLink :: FileMode -> Bool isSymLink mode = symbolicLinkMode `intersectFileModes` mode == symbolicLinkMode++{- Checks if a file has any executable bits set. -}+isExecutable :: FileMode -> Bool+isExecutable mode = ebits `intersectFileModes` mode /= 0+	where+		ebits = ownerExecuteMode `unionFileModes`+			groupExecuteMode `unionFileModes` otherExecuteMode
Utility/FileSystemEncoding.hs view
@@ -12,6 +12,7 @@ import Foreign.C import System.IO import System.IO.Unsafe+import qualified Data.Hash.MD5 as MD5  {- Sets a Handle to use the filesystem encoding. This causes data  - written or read from it to be encoded/decoded the same@@ -28,8 +29,7 @@ withFilePath fp f = Encoding.getFileSystemEncoding 	>>= \enc -> GHC.withCString enc fp f -{- Encodes a FilePath into a String of encoded bytes, applying the- - filesystem encoding.+{- Encodes a FilePath into a Str, applying the filesystem encoding.  -  - This use of unsafePerformIO is belived to be safe; GHC's interface  - only allows doing this conversion with CStrings, and the CString buffer@@ -37,7 +37,7 @@  - effects.  -} {-# NOINLINE encodeFilePath #-}-encodeFilePath :: FilePath -> String-encodeFilePath fp = unsafePerformIO $ do+encodeFilePath :: FilePath -> MD5.Str+encodeFilePath fp = MD5.Str $ unsafePerformIO $ do 	enc <- Encoding.getFileSystemEncoding 	GHC.withCString enc fp $ GHC.peekCString Encoding.char8
Utility/Monad.hs view
@@ -1,6 +1,6 @@ {- monadic stuff  -- - Copyright 2010-2011 Joey Hess <joey@kitenet.net>+ - Copyright 2010-2012 Joey Hess <joey@kitenet.net>  -  - Licensed under the GNU GPL version 3 or higher.  -}@@ -14,11 +14,7 @@  - predicate -} firstM :: Monad m => (a -> m Bool) -> [a] -> m (Maybe a) firstM _ [] = return Nothing-firstM p (x:xs) = do-	q <- p x-	if q-		then return (Just x)-		else firstM p xs+firstM p (x:xs) = ifM (p x) (return $ Just x , firstM p xs)  {- Returns true if any value in the list satisfies the predicate,  - stopping once one is found. -}@@ -28,6 +24,12 @@ {- Runs an action on values from a list until it succeeds. -} untilTrue :: Monad m => [a] -> (a -> m Bool) -> m Bool untilTrue = flip anyM++{- if with a monadic conditional. -}+ifM :: Monad m => m Bool -> (m a, m a) -> m a+ifM cond (thenclause, elseclause) = do+	c <- cond+	if c then thenclause else elseclause  {- Runs an action, passing its value to an observer before returning it. -} observe :: Monad m => (a -> m b) -> m a -> m a
Utility/Path.hs view
@@ -128,15 +128,6 @@ runPreserveOrder :: ([FilePath] -> IO [FilePath]) -> [FilePath] -> IO [FilePath] runPreserveOrder a files = preserveOrder files <$> a files -{- Lists the contents of a directory.- - Unlike getDirectoryContents, paths are not relative to the directory. -}-dirContents :: FilePath -> IO [FilePath]-dirContents d = map (d </>) . filter notcruft <$> getDirectoryContents d-	where-		notcruft "." = False-		notcruft ".." = False-		notcruft _ = True- {- Current user's home directory. -} myHomeDir :: IO FilePath myHomeDir = homeDirectory <$> (getUserEntryForID =<< getEffectiveUserID)
Utility/Touch.hsc view
@@ -18,8 +18,6 @@ import Foreign import Foreign.C import Control.Monad (when)-import GHC.IO.Encoding (getFileSystemEncoding)-import GHC.Foreign as GHC  newtype TimeSpec = TimeSpec CTime 
configure.hs view
@@ -1,113 +1,21 @@-{- Checks system configuration and generates SysConfig.hs. -}+{- configure program -} -import System.Directory-import Data.List import Data.Maybe-import System.Cmd.Utils-import Control.Applicative +import qualified Build.Configure as Configure import Build.TestConfig import Utility.StatFS-import Utility.SafeCommand  tests :: [TestCase]-tests =-	[ TestCase "version" getVersion-	, TestCase "git" $ requireCmd "git" "git --version >/dev/null"-	, TestCase "git version" getGitVersion-	, testCp "cp_a" "-a"-	, testCp "cp_p" "-p"-	, testCp "cp_reflink_auto" "--reflink=auto"-	, TestCase "uuid generator" $ selectCmd "uuid" ["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"-	, TestCase "wget" $ testCmd "wget" "wget --version >/dev/null"-	, TestCase "bup" $ testCmd "bup" "bup --version >/dev/null"-	, TestCase "gpg" $ testCmd "gpg" "gpg --version >/dev/null"-	, TestCase "ssh connection caching" getSshConnectionCaching-	, TestCase "StatFS" testStatFS-	] ++ shaTestCases [1, 256, 512, 224, 384]--shaTestCases :: [Int] -> [TestCase]-shaTestCases l = map make l-	where make n =-		let-			cmds = map (\x -> "sha" ++ show n ++ x) ["", "sum"]-			key = "sha" ++ show n-		in TestCase key $ maybeSelectCmd key cmds "</dev/null"--tmpDir :: String-tmpDir = "tmp"--testFile :: String-testFile = tmpDir ++ "/testfile"--testCp :: ConfigKey -> String -> TestCase-testCp k option = TestCase cmd $ testCmd k run-	where-		cmd = "cp " ++ option-		run = cmd ++ " " ++ testFile ++ " " ++ testFile ++ ".new"--{- Pulls package version out of the changelog. -}-getVersion :: Test-getVersion = do-	version <- getVersionString-	return $ Config "packageversion" (StringConfig version)-	-getVersionString :: IO String-getVersionString = do-	changelog <- readFile "CHANGELOG"-	let verline = head $ lines changelog-	return $ middle (words verline !! 1)-	where-		middle = drop 1 . init--getGitVersion :: Test-getGitVersion = do-	(_, s) <- pipeFrom "git" ["--version"]-	let version = last $ words $ head $ lines s-	return $ Config "gitversion" (StringConfig version)--getSshConnectionCaching :: Test-getSshConnectionCaching = Config "sshconnectioncaching" . BoolConfig <$>-	boolSystem "sh" [Param "-c", Param "ssh -o ControlPersist=yes -V >/dev/null 2>/dev/null"]+tests = [ TestCase "StatFS" testStatFS+	] ++ Configure.tests +{- This test cannot be included in Build.Configure due to needing+ - Utility/StatFS.hs to be built. -} testStatFS :: Test testStatFS = do 	s <- getFileSystemStats "." 	return $ Config "statfs_sane" $ BoolConfig $ isJust s -{- Set up cabal file with version. -}-cabalSetup :: IO ()-cabalSetup = do-	version <- getVersionString-	cabal <- readFile cabalfile-	writeFile tmpcabalfile $ unlines $ -		map (setfield "Version" version) $-		lines cabal-	renameFile tmpcabalfile cabalfile-	where-		cabalfile = "git-annex.cabal"-		tmpcabalfile = cabalfile++".tmp"-		setfield field value s-			| fullfield `isPrefixOf` s = fullfield ++ value-			| otherwise = s-			where-				fullfield = field ++ ": "--setup :: IO ()-setup = do-	createDirectoryIfMissing True tmpDir-	writeFile testFile "test file contents"--cleanup :: IO ()-cleanup = removeDirectoryRecursive tmpDir- main :: IO ()-main = do-	setup-	config <- runTests tests-	writeSysConfig config-	cleanup-	cabalSetup+main = Configure.run tests
debian/changelog view
@@ -1,3 +1,27 @@+git-annex (3.20120315) unstable; urgency=low++  * fsck: Fix up any broken links and misplaced content caused by the+    directory hash calculation bug fixed in the last release.+  * sync: Sync to lower cost remotes first.+  * status: Fixed to run in constant space.+  * status: More accurate display of sizes of tmp and bad keys.+  * unused: Now uses a bloom filter, and runs in constant space.+    Use of a bloom filter does mean it will not notice a small+    number of unused keys. For repos with up to half a million keys,+    it will miss one key in 1000.+  * Added annex.bloomcapacity and annex.bloomaccuracy, which can be+    adjusted as desired to tune the bloom filter.+  * status: Display amount of memory used by bloom filter, and+    detect when it's too small for the number of keys in a repository.+  * git-annex-shell: Runs hooks/annex-content after content is received+    or dropped.+  * Work around a bug in rsync (IMHO) introduced by openSUSE's SIP patch.+  * git-annex now behaves as git-annex-shell if symlinked to and run by that+    name. The Makefile sets this up, saving some 8 mb of installed size.+  * git-union-merge is a demo program, so it is no longer built by default.++ -- Joey Hess <joeyh@debian.org>  Thu, 15 Mar 2012 11:05:28 -0400+ git-annex (3.20120309) unstable; urgency=low    * Fix key directory hash calculation code to behave as it did before 
debian/control view
@@ -18,6 +18,7 @@ 	libghc-lifted-base-dev, 	libghc-json-dev, 	libghc-ifelse-dev,+	libghc-bloomfilter-dev, 	ikiwiki, 	perlmagick, 	git,@@ -25,7 +26,7 @@ 	rsync, 	openssh-client, Maintainer: Joey Hess <joeyh@debian.org>-Standards-Version: 3.9.2+Standards-Version: 3.9.3 Vcs-Git: git://git.kitenet.net/git-annex Homepage: http://git-annex.branchable.com/ 
doc/download.mdwn view
@@ -23,7 +23,8 @@ * `debian-stable` contains the latest backport of git-annex to Debian   stable. * `no-s3` disables the S3 special remote, for systems that lack the- necessary haskell library.+ necessary haskell library. (merge it into master if you need it)+* `no-bloom` avoids using bloom filters. (merge it into master if you need it) * `old-monad-control` is for systems that don't have a newer monad-control   library. * `tweak-fetch` adds support for the git tweak-fetch hook, which has
+ doc/forum/Please_fix_compatibility_with_ghc_7.0.mdwn view
@@ -0,0 +1,1 @@+I'm having trouble installing the latest git-annex. It depends on 'base >= 4.5 && base < 5', but ghc 7.0 only ships base 3.0. I've tried upgrading ghc to 7.4 but that breaks a whole bunch of other things; for example, the Crypto module fails to compile, preventing me from installing ghc. Please fix compatibility with ghc 7.0.
+ doc/forum/post-copy__47__sync_hook.mdwn view
@@ -0,0 +1,14 @@+Hi,++I have the following setup:+- normal git repository with website code.+- git annex repository to hold large set of binary data (pdfs, flashmovies, etc) that belongs to the site.++I use git annex so I (and other developers) don't need to copy 1.4Gb+ of binary data for every working copy. (Data that is mostly left untouched.) Using git annex copy --to=origin I can simply only add new additions to this media/binary repository, without first pulling all the data. So far so good.++When commits are pushed to a certain branch on the normal git repository, a post-receive hook exports (GIT_WORK_TREE=/data/site/ git checkout $branch -f) the updated repository to an apache documentroot. Thereby updating the staging server of the website.++My question is, how can I do the same thing for my git annex repository? Since post-receive fires on receiving the annex hashes, and not the actual files. Those are rsynced, and I cannot find a way to trigger an action after all files are copied by git annex via rsync.++Any tips?+
+ doc/forum/post-copy__47__sync_hook/comment_1_c8322d4b9bbf5eac80b48c312a42fbcf._comment view
@@ -0,0 +1,11 @@+[[!comment format=mdwn+ username="http://joey.kitenet.net/"+ nickname="joey"+ subject="comment 1"+ date="2012-03-14T16:23:25Z"+ content="""+I've made git-annex-shell run the git `hooks/annex-content` after content is received or dropped. ++Note that the clients need to be running at least git-annex version 3.20120227 , which runs git-annex-shell commit, which runs the hook.++"""]]
+ doc/forum/windows_port__63__.mdwn view
@@ -0,0 +1,2 @@+Any progress on Windows port? That would be very nice to have!+Depending on the scale of it, I might be able to help.
+ doc/forum/windows_port__63__/comment_1_23fa9aa3b00940a1c1b3876c35eef019._comment view
@@ -0,0 +1,9 @@+[[!comment format=mdwn+ username="http://joey.kitenet.net/"+ nickname="joey"+ subject="comment 1"+ date="2012-03-12T06:43:02Z"+ content="""+[[todo/windows_support]] has everything I know about making a windows port. This badly needs someone who understand Windows to dive into it. The question of how to create a symbolic link (or the relevant Windows equivilant) from haskell on Windows+is a good starting point..+"""]]
doc/git-annex-shell.mdwn view
@@ -49,6 +49,7 @@ * commit    This commits any staged changes to the git-annex branch.+  It also runs the annex-content hook.  # OPTIONS @@ -59,6 +60,13 @@    git-annex uses this to specify the UUID of the repository it was expecting   git-annex-shell to access, as a sanity check.++# HOOK++After content is received or dropped from the repository by git-annex-shell,+it runs a hook, `.git/hooks/annex-content` (or `hooks/annex-content` on a bare+repository). The hook is not currently passed any information about what+changed.  # ENVIRONMENT 
doc/git-annex.mdwn view
@@ -598,6 +598,23 @@   of memory and are working with very large numbers of files, increasing   the queue size can speed it up. +* `annex.bloomcapacity`++  The `git annex unused` command uses a bloom filter to determine+  what data is no longer used. The default bloom filter is sized to handle+  up to 500000 keys. If your repository is larger than that,+  you can adjust this to avoid `git annex unused` not noticing some unused+  data files. Increasing this will make `git-annex unused` consume more memory;+  run `git annex status` for memory usage numbers.++* `annex.bloomaccuracy`++  Adjusts the accuracy of the bloom filter used by+  `git annex unused`. The default accuracy is 1000 -- +  1 unused file out of 1000 will be missed by `git annex unused`. Increasing+  the accuracy will make `git annex unused` consume more memory;+  run `git annex status` for memory usage numbers.+ * `annex.version`    Automatically maintained, and used to automate upgrades between versions.
doc/install.mdwn view
@@ -35,6 +35,7 @@   * [hS3](http://hackage.haskell.org/package/hS3)   * [json](http://hackage.haskell.org/package/json)   * [IfElse](http://hackage.haskell.org/package/IfElse)+  * [bloomfilter](http://hackage.haskell.org/package/bloomfilter) * Shell commands   * [git](http://git-scm.com/)   * [uuid](http://www.ossp.org/pkg/lib/uuid/)
+ doc/news/version_3.20120315.mdwn view
@@ -0,0 +1,21 @@+git-annex 3.20120315 released with [[!toggle text="these changes"]]+[[!toggleable text="""+   * fsck: Fix up any broken links and misplaced content caused by the+     directory hash calculation bug fixed in the last release.+   * sync: Sync to lower cost remotes first.+   * status: Fixed to run in constant space.+   * status: More accurate display of sizes of tmp and bad keys.+   * unused: Now uses a bloom filter, and runs in constant space.+     Use of a bloom filter does mean it will not notice a small+     number of unused keys. For repos with up to half a million keys,+     it will miss one key in 1000.+   * Added annex.bloomcapacity and annex.bloomaccuracy, which can be+     adjusted as desired to tune the bloom filter.+   * status: Display amount of memory used by bloom filter, and+     detect when it's too small for the number of keys in a repository.+   * git-annex-shell: Runs hooks/annex-content after content is received+     or dropped.+   * Work around a bug in rsync (IMHO) introduced by openSUSE's SIP patch.+   * git-annex now behaves as git-annex-shell if symlinked to and run by that+     name. The Makefile sets this up, saving some 8 mb of installed size.+   * git-union-merge is a demo program, so it is no longer built by default."""]]
doc/tips/using_box.com_as_a_special_remote.mdwn view
@@ -13,21 +13,30 @@ * Allow users to mount davfs filesystems, by ensuring that   `/sbin/mount.davfs` is setuid root. On Debian, just `sudo dpkg-reconfigure davfs2` * Add yourself to the davfs2 group.-	sudo adduser $(whoami) davfs2++        sudo adduser $(whoami) davfs2+ * Edit `/etc/fstab`, and add a line to mount Box using davfs.-	sudo mkdir -p /media/box.com-	echo "https://www.box.com/dav/	/media/box.com	davfs	noauto,user	0 0" | sudo tee -a /etc/fstab++        sudo mkdir -p /media/box.com+        echo "https://www.box.com/dav/	/media/box.com	davfs	noauto,user	0 0" | sudo tee -a /etc/fstab+ * Create `~/.davfs2/davfs2.conf` with some important settings:-	mkdir ~/.davfs2/-	echo use_locks 0 >> ~/.davfs2/davfs2.conf-	echo cache_size 1 >> ~/.davfs2/davfs2.conf-	echo delay_upload 0 >> ~/.davfs2/davfs2.conf++        mkdir ~/.davfs2/+        echo use_locks 0 >> ~/.davfs2/davfs2.conf+        echo cache_size 1 >> ~/.davfs2/davfs2.conf+        echo delay_upload 0 >> ~/.davfs2/davfs2.conf+ * Create `~/.davfs2/secrets`. This file contains your Box.com login and password.   Your login is probably the email address you signed up with.-	echo "/media/box.com joey@kitenet.net mypassword" > ~/.davfs2/secrets-	chmod 600 ~/.davfs2/secrets++        echo "/media/box.com joey@kitenet.net mypassword" > ~/.davfs2/secrets+        chmod 600 ~/.davfs2/secrets+ * Now you should be able to mount Box, as a non-root user:-	mount /media/box.com++        mount /media/box.com  ## git-annex setup 
doc/todo/git-annex_unused_eats_memory.mdwn view
@@ -1,17 +1,28 @@ `git-annex unused` has to compare large sets of data (all keys with content present in the repository, with all keys used by files in the repository), and so-uses more memory than git-annex typically needs; around-50 mb when run in a repository with 80 thousand files.+uses more memory than git-annex typically needs. -(Used to be 80 mb, but implementation improved.)+It used to be a lot worse (hundreds of megabytes). -I would like to reduce this. One idea is to use a bloom filter. +Now it only needs enough memory to store a Set of all Keys that currently+have content in the annex. On a lightly populated repository, it runs in+quite low memory use (like 8 mb) even if the git repo has 100 thousand+files. On a repository with lots of file contents, it will use more.++Still, I would like to reduce this to a purely constant memory use,+as running in constant memory no matter the repo size is a git-annex design+goal.++One idea is to use a bloom filter.  For example, construct a bloom filter of all keys used by files in the repository. Then for each key with content present, check if it's in the bloom filter. Since there can be false positives, this might miss finding some unused keys. The probability/size of filter could be tunable.++> Fixed in `bloom` branch in git. --[[Joey]] +>> [[done]]! --[[Joey]]   Another way might be to scan the git log for files that got removed or changed what key they pointed to. Correlate with keys with content
git-annex-shell.hs view
@@ -1,117 +1,13 @@ {- git-annex-shell main program  -- - Copyright 2010 Joey Hess <joey@kitenet.net>+ - Copyright 2012 Joey Hess <joey@kitenet.net>  -  - Licensed under the GNU GPL version 3 or higher.  -}  import System.Environment-import System.Console.GetOpt -import Common.Annex-import qualified Git.Construct-import CmdLine-import Command-import Annex.UUID-import qualified Option--import qualified Command.ConfigList-import qualified Command.InAnnex-import qualified Command.DropKey-import qualified Command.RecvKey-import qualified Command.SendKey-import qualified Command.Commit--cmds_readonly :: [Command]-cmds_readonly = concat-	[ Command.ConfigList.def-	, Command.InAnnex.def-	, Command.SendKey.def-	]--cmds_notreadonly :: [Command]-cmds_notreadonly = concat-	[ Command.RecvKey.def-	, Command.DropKey.def-	, Command.Commit.def-	]--cmds :: [Command]-cmds = map adddirparam $ cmds_readonly ++ cmds_notreadonly-	where-		adddirparam c = c-			{ cmdparamdesc = "DIRECTORY " ++ cmdparamdesc c-			}--options :: [OptDescr (Annex ())]-options = Option.common ++-	[ Option [] ["uuid"] (ReqArg checkuuid paramUUID) "repository uuid"-	]-	where-		checkuuid expected = getUUID >>= check-			where-				check u | u == toUUID expected = return ()-				check NoUUID = unexpected "uninitialized repository"-				check u = unexpected $ "UUID " ++ fromUUID u-				unexpected s = error $-					"expected repository UUID " ++-					expected ++ " but found " ++ s--header :: String-header = "Usage: git-annex-shell [-c] command [parameters ...] [option ..]"+import GitAnnexShell  main :: IO ()-main = main' =<< getArgs--main' :: [String] -> IO ()-main' [] = failure--- skip leading -c options, passed by eg, ssh-main' ("-c":p) = main' p--- a command can be either a builtin or something to pass to git-shell-main' c@(cmd:dir:params)-	| cmd `elem` builtins = builtin cmd dir params-	| otherwise = external c-main' c@(cmd:_)-	-- Handle the case of being the user's login shell. It will be passed-	-- a single string containing all the real parameters.-	| "git-annex-shell " `isPrefixOf` cmd = main' $ drop 1 $ shellUnEscape cmd-	| cmd `elem` builtins = failure-	| otherwise = external c--builtins :: [String]-builtins = map cmdname cmds--builtin :: String -> String -> [String] -> IO ()-builtin cmd dir params = do-	checkNotReadOnly cmd-	dispatch (cmd : filterparams params) cmds options header $-		Git.Construct.repoAbsPath dir >>= Git.Construct.fromAbsPath--external :: [String] -> IO ()-external params = do-	checkNotLimited-	unlessM (boolSystem "git-shell" $ map Param $ "-c":filterparams params) $-		error "git-shell failed"---- Drop all args after "--".--- These tend to be passed by rsync and not useful.-filterparams :: [String] -> [String]-filterparams [] = []-filterparams ("--":_) = []-filterparams (a:as) = a:filterparams as--failure :: IO ()-failure = error $ "bad parameters\n\n" ++ usage header cmds options--checkNotLimited :: IO ()-checkNotLimited = checkEnv "GIT_ANNEX_SHELL_LIMITED"--checkNotReadOnly :: String -> IO ()-checkNotReadOnly cmd-	| cmd `elem` map cmdname cmds_readonly = return ()-	| otherwise = checkEnv "GIT_ANNEX_SHELL_READONLY"--checkEnv :: String -> IO ()-checkEnv var =-	whenM (not . null <$> catchDefaultIO (getEnv var) "") $-		error $ "Action blocked by " ++ var+main = run =<< getArgs
git-annex.cabal view
@@ -1,5 +1,5 @@ Name: git-annex-Version: 3.20120309+Version: 3.20120315 Cabal-Version: >= 1.6 License: GPL Maintainer: Joey Hess <joey@kitenet.net>@@ -7,7 +7,7 @@ Stability: Stable Copyright: 2010-2012 Joey Hess License-File: GPL-Extra-Source-Files: ./debian/NEWS ./debian/control ./debian/rules ./debian/changelog ./debian/doc-base ./debian/copyright ./debian/compat ./Messages/JSON.hs ./NEWS ./Option.hs ./configure.hs ./Annex.hs ./Seek.hs ./Crypto.hs ./Common.hs ./README ./Command/Merge.hs ./Command/AddUrl.hs ./Command/Whereis.hs ./Command/Unlock.hs ./Command/Commit.hs ./Command/Version.hs ./Command/FromKey.hs ./Command/PreCommit.hs ./Command/Sync.hs ./Command/Map.hs ./Command/Unused.hs ./Command/Uninit.hs ./Command/ReKey.hs ./Command/Migrate.hs ./Command/Init.hs ./Command/ConfigList.hs ./Command/Trust.hs ./Command/Lock.hs ./Command/SendKey.hs ./Command/RecvKey.hs ./Command/Reinject.hs ./Command/Add.hs ./Command/Fix.hs ./Command/Untrust.hs ./Command/Dead.hs ./Command/InitRemote.hs ./Command/Semitrust.hs ./Command/Fsck.hs ./Command/Move.hs ./Command/DropUnused.hs ./Command/Get.hs ./Command/Upgrade.hs ./Command/Describe.hs ./Command/Drop.hs ./Command/DropKey.hs ./Command/InAnnex.hs ./Command/Find.hs ./Command/Log.hs ./Command/Unannex.hs ./Command/Status.hs ./Command/Copy.hs ./Init.hs ./Types.hs ./Common/Annex.hs ./Makefile ./git-annex.cabal ./Upgrade/V1.hs ./Upgrade/V2.hs ./Upgrade/V0.hs ./CHANGELOG ./Git/LsFiles.hs ./Git/Version.hs ./Git/UnionMerge.hs ./Git/Url.hs ./Git/HashObject.hs ./Git/Types.hs ./Git/CatFile.hs ./Git/Queue.hs ./Git/Ref.hs ./Git/Filename.hs ./Git/Branch.hs ./Git/Sha.hs ./Git/LsTree.hs ./Git/Config.hs ./Git/CheckAttr.hs ./Git/Command.hs ./Git/Construct.hs ./Git/Index.hs ./doc/upgrades.mdwn ./doc/forum/Recommended_number_of_repositories.mdwn ./doc/forum/unlock__47__lock_always_gets_me.mdwn ./doc/forum/wishlist:_define_remotes_that_must_have_all_files.mdwn ./doc/forum/Will_git_annex_work_on_a_FAT32_formatted_key__63__.mdwn ./doc/forum/wishlist:_command_options_changes/comment_2_f6a637c78c989382e3c22d41b7fb4cc2._comment ./doc/forum/wishlist:_command_options_changes/comment_3_bf1114533d2895804e531e76eb6b8095._comment ./doc/forum/wishlist:_command_options_changes/comment_1_bfba72a696789bf21b2435dea15f967a._comment ./doc/forum/pure_git-annex_only_workflow/comment_4_dc8a3f75533906ad3756fcc47f7e96bb._comment ./doc/forum/pure_git-annex_only_workflow/comment_15_cb7c856d8141b2de3cc95874753f1ee5._comment ./doc/forum/pure_git-annex_only_workflow/comment_7_33db51096f568c65b22b4be0b5538c0d._comment ./doc/forum/pure_git-annex_only_workflow/comment_9_ace319652f9c7546883b5152ddc82591._comment ./doc/forum/pure_git-annex_only_workflow/comment_12_ca8ca35d6cd4a9f94568536736c12adc._comment ./doc/forum/pure_git-annex_only_workflow/comment_10_683768c9826b0bf0f267e8734b9eb872._comment ./doc/forum/pure_git-annex_only_workflow/comment_11_6b541ed834ef45606f3b98779a25a148._comment ./doc/forum/pure_git-annex_only_workflow/comment_14_b63568b327215ef8f646a39d760fdfc0._comment ./doc/forum/pure_git-annex_only_workflow/comment_8_6e5b42fdb7801daadc0b3046cbc3d51e._comment ./doc/forum/pure_git-annex_only_workflow/comment_1_a32f7efd18d174845099a4ed59e6feae._comment ./doc/forum/pure_git-annex_only_workflow/comment_13_00c82d320c7b4bb51078beba17e14dc8._comment ./doc/forum/pure_git-annex_only_workflow/comment_3_9b7d89da52f7ebb7801f9ec8545c3aba._comment ./doc/forum/pure_git-annex_only_workflow/comment_6_3660d45c5656f68924acbd23790024ee._comment ./doc/forum/pure_git-annex_only_workflow/comment_2_66dc9b65523a9912411db03c039ba848._comment ./doc/forum/pure_git-annex_only_workflow/comment_5_afe5035a6b35ed2c7e193fb69cc182e2._comment ./doc/forum/wishlist:_git-annex_replicate/comment_3_c13f4f9c3d5884fc6255fd04feadc2b1._comment ./doc/forum/wishlist:_git-annex_replicate/comment_1_9926132ec6052760cdf28518a24e2358._comment ./doc/forum/wishlist:_git-annex_replicate/comment_2_c43932f4194aba8fb2470b18e0817599._comment ./doc/forum/wishlist:_git-annex_replicate/comment_4_63f24abf086d644dced8b01e1a9948c9._comment ./doc/forum/Podcast_syncing_use-case/comment_1_ace6f9d3a950348a3ac0ff592b62e786._comment ./doc/forum/Podcast_syncing_use-case/comment_2_930a6620b4d516e69ed952f9da5371bb._comment ./doc/forum/Behaviour_of_fsck/comment_4_e4911dc6793f98fb81151daacbe49968._comment ./doc/forum/Behaviour_of_fsck/comment_3_97848f9a3db89c0427cfb671ba13300e._comment ./doc/forum/Behaviour_of_fsck/comment_2_ead36a23c3e6efa1c41e4555f93e014e._comment ./doc/forum/Behaviour_of_fsck/comment_1_0e40f158b3f4ccdcaab1408d858b68b8._comment ./doc/forum/incompatible_versions__63__/comment_1_629f28258746d413e452cbd42a1a43f4._comment ./doc/forum/vlc_and_git-annex/comment_1_9c9ab8ce463cf74418aa2f385955f165._comment ./doc/forum/vlc_and_git-annex/comment_2_037f94c1deeac873dbdb36cd4c927e45._comment ./doc/forum/Recommended_number_of_repositories/comment_1_3ef256230756be8a9679b107cdbfd018._comment ./doc/forum/migration_to_git-annex_and_rsync.mdwn ./doc/forum/hashing_objects_directories.mdwn ./doc/forum/git_annex_ls___47___metadata_in_git_annex_whereis.mdwn ./doc/forum/unlock__47__lock_always_gets_me/comment_1_dee73a7ea3e1a5154601adb59782831f._comment ./doc/forum/git-subtree_support__63__.mdwn ./doc/forum/Podcast_syncing_use-case.mdwn ./doc/forum/hashing_objects_directories/comment_5_ef6cfd49d24c180c2d0a062e5bd3a0be._comment ./doc/forum/hashing_objects_directories/comment_1_c55c56076be4f54251b0b7f79f28a607._comment ./doc/forum/hashing_objects_directories/comment_2_504c96959c779176f991f4125ea22009._comment ./doc/forum/hashing_objects_directories/comment_3_9134bde0a13aac0b6a4e5ebabd7f22e8._comment ./doc/forum/hashing_objects_directories/comment_4_0de9170e429cbfea66f5afa8980d45ac._comment ./doc/forum/location_tracking_cleanup.mdwn ./doc/forum/Wishlist:_Ways_of_selecting_files_based_on_meta-information.mdwn ./doc/forum/confusion_with_remotes__44___map.mdwn ./doc/forum/git-annex_on_OSX.mdwn ./doc/forum/A_really_stupid_question.mdwn ./doc/forum/git_tag_missing_for_3.20111011/comment_1_7a53bf273f3078ab3351369ef2b5f2a6._comment ./doc/forum/version_3_upgrade/comment_1_05fc9c9cad26c520bebb98c852c71e35._comment ./doc/forum/example_of_massively_disconnected_operation.mdwn ./doc/forum/git-annex_communication_channels/comment_2_c7aeefa6ef9a2e75d8667b479ade1b7f._comment ./doc/forum/git-annex_communication_channels/comment_5_404b723a681eb93fee015cea8024b6bc._comment ./doc/forum/git-annex_communication_channels/comment_1_198325d2e9337c90f026396de89eec0e._comment ./doc/forum/git-annex_communication_channels/comment_4_1ba6ddf54843c17c7d19a9996f2ab712._comment ./doc/forum/git-annex_communication_channels/comment_6_0d87d0e26461494b1d7f8a701a924729._comment ./doc/forum/git-annex_communication_channels/comment_3_1ff08a3e0e63fa0e560cbc9602245caa._comment ./doc/forum/git-annex_communication_channels/comment_7_2c87c7a0648fe87c2bf6b4391f1cc468._comment ./doc/forum/wishlist:_git-annex_replicate.mdwn ./doc/forum/advantages_of_SHA__42___over_WORM/comment_1_96c354cac4b5ce5cf6664943bc84db1d._comment ./doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk.mdwn ./doc/forum/Behaviour_of_fsck.mdwn ./doc/forum/git_annex_add_crash_and_subsequent_recovery.mdwn ./doc/forum/Handling_web_special_remote_when_content_changes__63__.mdwn ./doc/forum/nfs_mounted_repo_results_in_errors_on_drop__47__move.mdwn ./doc/forum/working_without_git-annex_commits.mdwn ./doc/forum/migrate_existing_git_repository_to_git-annex.mdwn ./doc/forum/__34__git_annex_lock__34___very_slow_for_big_repo.mdwn ./doc/forum/wishlist:_traffic_accounting_for_git-annex.mdwn ./doc/forum/git_pull_remote_git-annex.mdwn ./doc/forum/rsync_over_ssh__63__.mdwn ./doc/forum/unannex_alternatives/comment_3_b1687fc8f9e7744327bbeb6f0635d1cd._comment ./doc/forum/unannex_alternatives/comment_1_dcd4cd41280b41512bbdffafaf307993._comment ./doc/forum/unannex_alternatives/comment_2_58a72a9fe0f58c7af0b4d7927a2dd21d._comment ./doc/forum/wishlist:_git_annex_status/comment_4_9aeeb83d202dc8fb33ff364b0705ad94._comment ./doc/forum/wishlist:_git_annex_status/comment_3_d1fd70c67243971c96d59e1ffb7ef6e7._comment ./doc/forum/wishlist:_git_annex_status/comment_2_c2b0ce025805b774dc77ce264a222824._comment ./doc/forum/wishlist:_git_annex_status/comment_1_994bfd12c5d82e08040d6116915c5090._comment ./doc/forum/git_pull_remote_git-annex/comment_7_24c45ee981b18bc78325c768242e635d._comment ./doc/forum/git_pull_remote_git-annex/comment_2_0f7f4a311b0ec1d89613e80847e69b42._comment ./doc/forum/git_pull_remote_git-annex/comment_1_9c245db3518d8b889ecdf5115ad9e053._comment ./doc/forum/git_pull_remote_git-annex/comment_5_4f2a05ef6551806dd0ec65372f183ca4._comment ./doc/forum/git_pull_remote_git-annex/comment_4_646f2077edcabc000a7d9cb75a93cf55._comment ./doc/forum/git_pull_remote_git-annex/comment_8_7e76ee9b6520cbffaf484c9299a63ad3._comment ./doc/forum/git_pull_remote_git-annex/comment_3_1aa89725b5196e40a16edeeb5ccfa371._comment ./doc/forum/git_pull_remote_git-annex/comment_6_3925d1aa56bce9380f712e238d63080f._comment ./doc/forum/wishlist:_command_options_changes.mdwn ./doc/forum/location_tracking_cleanup/comment_3_c15428cec90e969284a5e690fb4b2fde._comment ./doc/forum/location_tracking_cleanup/comment_2_e7395cb6e01f42da72adf71ea3ebcde4._comment ./doc/forum/location_tracking_cleanup/comment_1_7d6319e8c94dfe998af9cfcbf170efb2._comment ./doc/forum/new_microfeatures/comment_2_41ad904c68e89c85e1fc49c9e9106969._comment ./doc/forum/new_microfeatures/comment_1_058bd517c6fffaf3446b1f5d5be63623._comment ./doc/forum/new_microfeatures/comment_3_a1a9347b5bc517f2a89a8b292c3f8517._comment ./doc/forum/new_microfeatures/comment_7_94045b9078b1fff877933b012d1b49e2._comment ./doc/forum/new_microfeatures/comment_5_3c627d275586ff499d928a8f8136babf._comment ./doc/forum/new_microfeatures/comment_4_5a6786dc52382fff5cc42fdb05770196._comment ./doc/forum/new_microfeatures/comment_6_31ea08c008500560c0b96c6601bc6362._comment ./doc/forum/Error_while_adding_a_file___34__createSymbolicLink:_already_exists__34__.mdwn ./doc/forum/How_to_expire_old_versions_of_files_that_have_been_edited__63__.mdwn ./doc/forum/advantages_of_SHA__42___over_WORM.mdwn ./doc/forum/wishlist:_git_annex_put_--_same_as_get__44___but_for_defaults.mdwn ./doc/forum/cloud_services_to_support.mdwn ./doc/forum/OSX__39__s_default_sshd_behaviour_has_limited_paths_set.mdwn ./doc/forum/Auto_archiving.mdwn ./doc/forum/bainstorming:_git_annex_push___38___pull.mdwn ./doc/forum/sparse_git_checkouts_with_annex.mdwn ./doc/forum/Need_new_build_instructions_for_Debian_stable.mdwn ./doc/forum/batch_check_on_remote_when_using_copy.mdwn ./doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs.mdwn ./doc/forum/wishlist:alias_system.mdwn ./doc/forum/incompatible_versions__63__.mdwn ./doc/forum/Automatic_commit_messages_for_git_annex_sync.mdwn ./doc/forum/fsck_gives_false_positives.mdwn ./doc/forum/Preserving_file_access_rights_in_directory_tree_below_objects__47__.mdwn ./doc/forum/A_really_stupid_question/comment_1_40e02556de0b00b94f245a0196b5a89f._comment ./doc/forum/wishlist:_git_backend_for_git-annex.mdwn ./doc/forum/vlc_and_git-annex.mdwn ./doc/forum/seems_to_build_fine_on_haskell_platform_2011.mdwn ./doc/forum/rsync_over_ssh__63__/comment_1_ee21f32e90303e20339e0a568321bbbe._comment ./doc/forum/rsync_over_ssh__63__/comment_2_aa690da6ecfb2b30fc5080ad76dc77b1._comment ./doc/forum/wishlist:_special_remote_for_sftp_or_rsync.mdwn ./doc/forum/OSX__39__s_haskell-platform_statically_links_things.mdwn ./doc/forum/using_git_annex_to_merge_and_synchronize_2_directories___40__like_unison__41__.mdwn ./doc/forum/git_tag_missing_for_3.20111011.mdwn ./doc/forum/unannex_alternatives.mdwn ./doc/forum/can_git-annex_replace_ddm__63__.mdwn ./doc/forum/sparse_git_checkouts_with_annex/comment_2_e357db3ccc4079f07a291843975535eb._comment ./doc/forum/sparse_git_checkouts_with_annex/comment_1_c7dc199c5740a0e7ba606dfb5e3e579a._comment ./doc/forum/sparse_git_checkouts_with_annex/comment_3_fcfafca994194d57dccf5319c7c9e646._comment ./doc/forum/sparse_git_checkouts_with_annex/comment_4_04dc14880f31eee2b6d767d4d4258c5a._comment ./doc/forum/syncing_non-git_trees_with_git-annex.mdwn ./doc/forum/git-annex_communication_channels.mdwn ./doc/forum/fsck_gives_false_positives/comment_4_7ceb395bf8a2e6a041ccd8de63b1b6eb._comment ./doc/forum/fsck_gives_false_positives/comment_3_692d6d4cd2f75a497e7d314041a768d2._comment ./doc/forum/fsck_gives_false_positives/comment_5_86484a504c3bbcecd5876982b9c95688._comment ./doc/forum/fsck_gives_false_positives/comment_2_f51c53f3f6e6ee1ad463992657db5828._comment ./doc/forum/fsck_gives_false_positives/comment_1_b91070218b9d5fb687eeee1f244237ad._comment ./doc/forum/can_git-annex_replace_ddm__63__/comment_3_4c69097fe2ee81359655e59a03a9bb8d._comment ./doc/forum/can_git-annex_replace_ddm__63__/comment_2_008554306dd082d7f543baf283510e92._comment ./doc/forum/can_git-annex_replace_ddm__63__/comment_1_aa05008dfe800474ff76678a400099e1._comment ./doc/forum/version_3_upgrade.mdwn ./doc/forum/relying_on_git_for_numcopies/comment_3_43d8e1513eb9947f8a503f094c03f307._comment ./doc/forum/relying_on_git_for_numcopies/comment_2_be6acbc26008a9cb54e7b8f498f2c2a2._comment ./doc/forum/relying_on_git_for_numcopies/comment_1_8ad3cccd7f66f6423341d71241ba89fc._comment ./doc/forum/confusion_with_remotes__44___map/comment_1_a38ded23b7f288292a843abcb1a56f38._comment ./doc/forum/confusion_with_remotes__44___map/comment_2_cd1c98b1276444e859a22c3dbd6f2a79._comment ./doc/forum/confusion_with_remotes__44___map/comment_6_496b0d9b86869bbac3a1356d53a3dda4._comment ./doc/forum/confusion_with_remotes__44___map/comment_5_27801584325d259fa490f67273f2ff71._comment ./doc/forum/confusion_with_remotes__44___map/comment_4_3b89b6d1518267fcbc050c9de038b9ca._comment ./doc/forum/confusion_with_remotes__44___map/comment_3_18531754089c991b6caefc57a5c17fe9._comment ./doc/forum/confusion_with_remotes__44___map/comment_7_9a456f61f956a3d5e81e723d5a90794c._comment ./doc/forum/--print0_option_as_in___34__find__34__.mdwn ./doc/forum/relying_on_git_for_numcopies.mdwn ./doc/forum/wishlist:_do_round_robin_downloading_of_data.mdwn ./doc/forum/pure_git-annex_only_workflow.mdwn ./doc/forum/wishlist:_git_annex_status.mdwn ./doc/forum/getting_git_annex_to_do_a_force_copy_to_a_remote.mdwn ./doc/forum/Problems_with_large_numbers_of_files.mdwn ./doc/forum/Can_I_store_normal_files_in_the_git-annex_git_repository__63__.mdwn ./doc/forum/Is_an_automagic_upgrade_of_the_object_directory_safe__63__.mdwn ./doc/forum/wishlist:_push_to_cia.vc_from_the_website__39__s_repo__44___not_your_personal_one.mdwn ./doc/forum/new_microfeatures.mdwn ./doc/forum/git-subtree_support__63__/comment_2_73d2a015b1ac79ec99e071a8b1e29034._comment ./doc/forum/git-subtree_support__63__/comment_1_4f333cb71ed1ff259bbfd86704806aa6._comment ./doc/forum/git-subtree_support__63__/comment_4_75b0e072e668aa46ff0a8d62a6620306._comment ./doc/forum/git-subtree_support__63__/comment_3_c533400e22c306c033fcd56e64761b0b._comment ./doc/forum/git-subtree_support__63__/comment_6_85df530f7b6d76b74ac8017c6034f95e._comment ./doc/forum/git-subtree_support__63__/comment_5_f5ec9649d9f1dc122e715de5533bc674._comment ./doc/backends.mdwn ./doc/bugs/__39__annex_add__39___fails_to___39__git_add__39___for_parent_relative_path.mdwn ./doc/bugs/uuid.log_trust.log_and_remote.log_merge_wackiness.mdwn ./doc/bugs/Remote_repo_and_set_operation_with_find.mdwn ./doc/bugs/softlink_mtime.mdwn ./doc/bugs/uninit_should_not_run_when_branch_git-annex_is_checked_out.mdwn ./doc/bugs/ordering.mdwn ./doc/bugs/dropping_files_with_a_URL_backend_fails.mdwn ./doc/bugs/fsck__47__fix_should_check__47__fix_the_permissions_of_.git__47__annex.mdwn ./doc/bugs/dropunused_doesn__39__t_handle_double_spaces_in_filename.mdwn ./doc/bugs/add_script-friendly_output_options.mdwn ./doc/bugs/uninit_does_not_work_in_old_repos.mdwn ./doc/bugs/conq:_invalid_command_syntax.mdwn ./doc/bugs/git_annex_get_choke_when_remote_is_an_ssh_url_with_a_port.mdwn ./doc/bugs/unannex_and_uninit_do_not_work_when_git_index_is_broken.mdwn ./doc/bugs/git_annex_migrate_leaves_old_backend_versions_around.mdwn ./doc/bugs/git_annex_unused_failes_on_empty_repository.mdwn ./doc/bugs/git_annex_add_eats_files_when_filename_is_too_long.mdwn ./doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing.mdwn ./doc/bugs/problem_with_upgrade_v2_-__62___v3.mdwn ./doc/bugs/git_annex_copy_--fast_does_not_copy_files.mdwn ./doc/bugs/Cabal_dependency_monadIO_missing.mdwn ./doc/bugs/dotdot_problem.mdwn ./doc/bugs/Problems_running_make_on_osx.mdwn ./doc/bugs/free_space_checking/comment_2_8a65f6d3dcf5baa3f7f2dbe1346e2615._comment ./doc/bugs/free_space_checking/comment_3_0fc6ff79a357b1619d13018ccacc7c10._comment ./doc/bugs/free_space_checking/comment_1_a868e805be43c5a7c19c41f1af8e41e6._comment ./doc/bugs/copy_doesn__39__t_scale.mdwn ./doc/bugs/Error_when_moving_annexed_file_to_a_.gitignored_location.mdwn ./doc/bugs/done.mdwn ./doc/bugs/git_annex_copy_-f_REMOTE_._doesn__39__t_work_as_expected.mdwn ./doc/bugs/Displayed_copy_speed_is_wrong/comment_2_8b240de1d5ae9229fa2d77d1cc15a552._comment ./doc/bugs/Displayed_copy_speed_is_wrong/comment_1_74de3091e8bfd7acd6795e61f39f07c6._comment ./doc/bugs/Build_error_on_Mac_OSX_10.6.mdwn ./doc/bugs/bare_git_repos.mdwn ./doc/bugs/nfs_mounted_repo_results_in_errors_on_drop_move.mdwn ./doc/bugs/fat_support.mdwn ./doc/bugs/problems_with_utf8_names.mdwn ./doc/bugs/error_with_file_names_starting_with_dash.mdwn ./doc/bugs/not_possible_to_have_annex_on_a_separate_filesystem.mdwn ./doc/bugs/Lost_S3_Remote.mdwn ./doc/bugs/unhappy_without_UTF8_locale.mdwn ./doc/bugs/S3_memory_leaks.mdwn ./doc/bugs/git_annex_map_has_problems_with_urls_containing___126__.mdwn ./doc/bugs/interrupting_migration_causes_problems.mdwn ./doc/bugs/upgrade_left_untracked_.git-annex__47____42___directories.mdwn ./doc/bugs/cyclic_drop.mdwn ./doc/bugs/Problems_running_make_on_osx/comment_9_cc283b485b3c95ba7eebc8f0c96969b3._comment ./doc/bugs/Problems_running_make_on_osx/comment_4_c52be386f79f14c8570a8f1397c68581._comment ./doc/bugs/Problems_running_make_on_osx/comment_18_64fab50d95de619eb2e8f08f90237de1._comment ./doc/bugs/Problems_running_make_on_osx/comment_16_5c2dd6002aadaab30841b77a5f5aed34._comment ./doc/bugs/Problems_running_make_on_osx/comment_10_94e4ac430140042a2d0fb5a16d86b4e5._comment ./doc/bugs/Problems_running_make_on_osx/comment_15_6b8867b8e48bf807c955779c9f8f0909._comment ./doc/bugs/Problems_running_make_on_osx/comment_11_56f1143fa191361d63b441741699e17f._comment ./doc/bugs/Problems_running_make_on_osx/comment_20_7db27d1a22666c831848bc6c06d66a84._comment ./doc/bugs/Problems_running_make_on_osx/comment_12_ec5131624d0d2285d3b6880e47033f97._comment ./doc/bugs/Problems_running_make_on_osx/comment_3_68f0f8ae953589ae26d57310b40c878d._comment ./doc/bugs/Problems_running_make_on_osx/comment_14_89a960b6706ed703b390a81a8bc4e311._comment ./doc/bugs/Problems_running_make_on_osx/comment_17_62fccb04b0e4b695312f7a3f32fb96ee._comment ./doc/bugs/Problems_running_make_on_osx/comment_19_4253988ed178054c8b6400beeed68a29._comment ./doc/bugs/Problems_running_make_on_osx/comment_6_0c46f5165ceb5a7b9ea9689c33b3a4f8._comment ./doc/bugs/Problems_running_make_on_osx/comment_1_34120e82331ace01a6a4960862d38f2d._comment ./doc/bugs/Problems_running_make_on_osx/comment_7_237a137cce58a28abcc736cbf2c420b0._comment ./doc/bugs/Problems_running_make_on_osx/comment_5_7f1330a1e541b0f3e2192e596d7f7bee._comment ./doc/bugs/Problems_running_make_on_osx/comment_2_cc53d1681d576186dbc868dd9801d551._comment ./doc/bugs/Problems_running_make_on_osx/comment_13_88ed095a448096bf8a69015a04e64df1._comment ./doc/bugs/Problems_running_make_on_osx/comment_8_efafa203addf8fa79e33e21a87fb5a2b._comment ./doc/bugs/git-annex_directory_hashing_problems_on_osx.mdwn ./doc/bugs/No_easy_way_to_re-inject_a_file_into_an_annex.mdwn ./doc/bugs/git_annex_unlock_is_not_atomic.mdwn ./doc/bugs/free_space_checking.mdwn ./doc/bugs/wishlist:_more_descriptive_commit_messages_in_git-annex_branch.mdwn ./doc/bugs/Displayed_copy_speed_is_wrong.mdwn ./doc/bugs/git_annex_should_use___39__git_add_-f__39___internally.mdwn ./doc/bugs/minor_bug:_errors_are_not_verbose_enough.mdwn ./doc/bugs/__34__make_test__34___fails_silently.mdwn ./doc/bugs/No_version_information_from_cli.mdwn ./doc/bugs/Error_while_adding_a_file___34__createSymbolicLink:_already_exists__34__.mdwn ./doc/bugs/conq:_invalid_command_syntax/comment_1_f33b83025ce974e496f83f248275a66a._comment ./doc/bugs/conq:_invalid_command_syntax/comment_2_195106ca8dedad5f4d755f625e38e8af._comment ./doc/bugs/conq:_invalid_command_syntax/comment_3_55af43e2f43a4c373f7a0a33678d0b1c._comment ./doc/bugs/old_data_isn__39__t_unused_after_migration.mdwn ./doc/bugs/fails_to_handle_lot_of_files.mdwn ./doc/bugs/tests_fail_when_there_is_no_global_.gitconfig_for_the_user.mdwn ./doc/bugs/git_annex_initremote_walks_.git-annex.mdwn ./doc/bugs/copy_doesn__39__t_scale/comment_1_7c12499c9ac28a9883c029f8c659eb57._comment ./doc/bugs/copy_doesn__39__t_scale/comment_2_f85d8023cdbc203bb439644cf7245d4e._comment ./doc/bugs/copy_doesn__39__t_scale/comment_3_4592765c3d77bb5664b8d16867e9d79c._comment ./doc/bugs/signal_weirdness.mdwn ./doc/bugs/git-annex_incorrectly_parses_bare_IPv6_addresses.mdwn ./doc/bugs/git_annex_version_should_without_being_in_a_repo_.mdwn ./doc/bugs/Can__39__t___34__git-annex_get__34___with_3.20111203.mdwn ./doc/bugs/Prevent_accidental_merges/comment_1_4c46a193915eab8f308a04175cb2e40a._comment ./doc/bugs/conflicting_haskell_packages/comment_1_e552a6cc6d7d1882e14130edfc2d6b3b._comment ./doc/bugs/tmp_file_handling.mdwn ./doc/bugs/annex_add_in_annex.mdwn ./doc/bugs/making_annex-merge_try_a_fast-forward.mdwn ./doc/bugs/bad_behaviour_with_file_names_with_newline_in_them.mdwn ./doc/bugs/Lost_S3_Remote/comment_2_c99c65882a3924f4890e500f9492b442._comment ./doc/bugs/Lost_S3_Remote/comment_3_1e434d5a20a692cd9dc7f6f8f20f30dd._comment ./doc/bugs/Lost_S3_Remote/comment_1_6e80e6db6671581d471fc9a54181c04c._comment ./doc/bugs/on--git-dir_and_--work-tree_options.mdwn ./doc/bugs/Makefile_is_missing_dependancies.mdwn ./doc/bugs/test_suite_shouldn__39__t_fail_silently.mdwn ./doc/bugs/git_annex_upgrade_output_is_inconsistent_and_spammy.mdwn ./doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_4_91439d4dbbf1461e281b276eb0003691._comment ./doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_6_f360f0006bc9115bc5a3e2eb9fe58abd._comment ./doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_3_86d9e7244ae492bcbe62720b8c4fc4a9._comment ./doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_2_cd0123392b16d89db41b45464165c247._comment ./doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_1_5f60006c9bb095167d817f234a14d20b._comment ./doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_5_ca33a9ca0df33f7c1b58353d7ffb943d._comment ./doc/bugs/wishlist:_query_things_like_description__44___trust_level.mdwn ./doc/bugs/git_rename_detection_on_file_move/comment_9_75e0973f6d573df615e01005ebcea87d._comment ./doc/bugs/git_rename_detection_on_file_move/comment_7_7f20d0b2f6ed1c34021a135438037306._comment ./doc/bugs/git_rename_detection_on_file_move/comment_3_57010bcaca42089b451ad8659a1e018e._comment ./doc/bugs/git_rename_detection_on_file_move/comment_4_79d96599f757757f34d7b784e6c0e81c._comment ./doc/bugs/git_rename_detection_on_file_move/comment_5_d61f5693d947b9736b29fca1dbc7ad76._comment ./doc/bugs/git_rename_detection_on_file_move/comment_8_6a00500b24ba53248c78e1ffc8d1a591._comment ./doc/bugs/git_rename_detection_on_file_move/comment_2_7101d07400ad5935f880dc00d89bf90e._comment ./doc/bugs/git_rename_detection_on_file_move/comment_6_f63de6fe2f7189c8c2908cc41c4bc963._comment ./doc/bugs/git_rename_detection_on_file_move/comment_1_0531dcfa833b0321a7009526efe3df33._comment ./doc/bugs/fsck_claims_failed_checksum_when_less_copies_than_required_are_found.mdwn ./doc/bugs/add_range_argument_to___34__git_annex_dropunused__34___.mdwn ./doc/bugs/git_rename_detection_on_file_move.mdwn ./doc/bugs/problem_commit_normal_links.mdwn ./doc/bugs/extraneous_shell_escaping_for_rsync_remotes.mdwn ./doc/bugs/problems_with_utf8_names/comment_1_3c7e3f021c2c94277eecf9c8af6cec5f._comment ./doc/bugs/problems_with_utf8_names/comment_7_0cc588f787d6eecfa19a8f6cee4b07b5._comment ./doc/bugs/problems_with_utf8_names/comment_8_ff5c6da9eadfee20c18c86b648a62c47._comment ./doc/bugs/problems_with_utf8_names/comment_4_93bee35f5fa7744834994bc7a253a6f9._comment ./doc/bugs/problems_with_utf8_names/comment_3_4f936a5d3f9c7df64c8a87e62b7fbfdc._comment ./doc/bugs/problems_with_utf8_names/comment_5_519cda534c7aea7f5ad5acd3f76e21fa._comment ./doc/bugs/problems_with_utf8_names/comment_6_52e0bfff2b177b6f92e226b25d2f3ff1._comment ./doc/bugs/problems_with_utf8_names/comment_2_bad4c4c5f54358d1bc0ab2adc713782a._comment ./doc/bugs/git_annex_unused_seems_to_check_for_current_path.mdwn ./doc/bugs/Makefile_is_missing_dependancies/comment_6_24119fc5d5963ce9dd669f7dcf006859._comment ./doc/bugs/Makefile_is_missing_dependancies/comment_3_c38b6f4abc9b9ad413c3b83ca04386c3._comment ./doc/bugs/Makefile_is_missing_dependancies/comment_8_a3555e3286cdc2bfeb9cde0ff727ba74._comment ./doc/bugs/Makefile_is_missing_dependancies/comment_2_416f12dbd0c2b841fac8164645b81df5._comment ./doc/bugs/Makefile_is_missing_dependancies/comment_5_0a1c52e2c96d19b9c3eb7e99b8c2434f._comment ./doc/bugs/Makefile_is_missing_dependancies/comment_7_96fd4725df4b54e670077a18d3ac4943._comment ./doc/bugs/Makefile_is_missing_dependancies/comment_1_5a3da5f79c8563c7a450aa29728abe7c._comment ./doc/bugs/Makefile_is_missing_dependancies/comment_4_cc13873175edf191047282700315beee._comment ./doc/bugs/Trouble_initializing_git_annex_on_NFS.mdwn ./doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems.mdwn ./doc/bugs/build_issue_with_latest_release_0.20110522-1-gde817ba.mdwn ./doc/bugs/weird_local_clone_confuses.mdwn ./doc/bugs/fsck_output.mdwn ./doc/bugs/git_annex_add_memory_leak.mdwn ./doc/bugs/git-annex_branch_push_race.mdwn ./doc/bugs/wishlist:_allow_users_to_provide_UUID_when_running___96__git_annex_init__96__.mdwn ./doc/bugs/git-annex_has_issues_with_git_when_staging__47__commiting_logs.mdwn ./doc/bugs/git_annex_gets_confused_about_remotes_with_dots_in_their_names.mdwn ./doc/bugs/unannex_vs_unlock_hook_confusion.mdwn ./doc/bugs/Cabal_dependency_monadIO_missing/comment_2_4f4d8e1e00a2a4f7e8a8ab082e16adac._comment ./doc/bugs/Cabal_dependency_monadIO_missing/comment_1_14be660aa57fadec0d81b32a8b52c66f._comment ./doc/bugs/conflicting_haskell_packages.mdwn ./doc/bugs/git_command_line_constructed_by_unannex_command_has_tons_of_redundant_-a_paramters.mdwn ./doc/bugs/backend_version_upgrade_leaves_repo_unusable.mdwn ./doc/bugs/fat_support/comment_3_df3b943bc1081a8f3f7434ae0c8e061e._comment ./doc/bugs/fat_support/comment_4_90a8a15bedd94480945a374f9d706b86._comment ./doc/bugs/fat_support/comment_5_64bbf89de0836673224b83fdefa0407b._comment ./doc/bugs/fat_support/comment_1_04bcc4795d431e8cb32293aab29bbfe2._comment ./doc/bugs/fat_support/comment_2_bb4a97ebadb5c53809fc78431eabd7c8._comment ./doc/bugs/unannex_command_doesn__39__t_all_files.mdwn ./doc/bugs/annex_unannex__47__uninit_should_handle_copies.mdwn ./doc/bugs/git-annex_branch_corruption.mdwn ./doc/bugs/git_annex_fsck_is_a_no-op_in_bare_repos.mdwn ./doc/bugs/show_version_without_having_to_be_in_a_git_repo.mdwn ./doc/bugs/Unfortunate_interaction_with_Calibre.mdwn ./doc/bugs/error_propigation.mdwn ./doc/bugs/wishlist:_support_drop__44___find_on_special_remotes.mdwn ./doc/bugs/scp_interrupt_to_background.mdwn ./doc/bugs/copy_fast_confusing_with_broken_locationlog.mdwn ./doc/bugs/uninit_does_not_work_in_old_repos/comment_1_bc0619c6e17139df74639448aa6a0f72._comment ./doc/bugs/git-annex_losing_rsync_remotes_with_encryption_enabled.mdwn ./doc/bugs/configure_script_should_detect_uuidgen_instead_of_just_uuid.mdwn ./doc/bugs/check_for_curl_in_configure.hs.mdwn ./doc/bugs/fails_to_handle_lot_of_files/comment_1_09d8e4e66d8273fab611bd29e82dc7fc._comment ./doc/bugs/fails_to_handle_lot_of_files/comment_2_fd2ec05f4b5a7a6ae6bd9f5dbc3156de._comment ./doc/bugs/Name_scheme_does_not_follow_git__39__s_rules.mdwn ./doc/bugs/concurrent_git-annex_processes_can_lead_to_locking_issues.mdwn ./doc/bugs/Prevent_accidental_merges.mdwn ./doc/bugs/building_on_lenny.mdwn ./doc/bugs/case_sensitivity_on_FAT.mdwn ./doc/bugs/encrypted_S3_stalls.mdwn ./doc/bugs/support_bare_git_repo__44___with_the_annex_directory_exposed_to_http.mdwn ./doc/bugs/WORM:_Handle_long_filenames_correctly.mdwn ./doc/logo_small.png ./doc/tips.mdwn ./doc/use_case/Bob.mdwn ./doc/use_case/Alice.mdwn ./doc/upgrades/SHA_size.mdwn ./doc/news/sharebox_a_FUSE_filesystem_for_git-annex.mdwn ./doc/news/version_3.20120229.mdwn ./doc/news/version_3.20120309.mdwn ./doc/news/version_3.20120230/comment_2_899de1196cd1ba4a393e4ef574d7aa5e._comment ./doc/news/version_3.20120230/comment_1_b975cbd3a01ba5c2fa0f24fe739d3433._comment ./doc/news/Presentation_at_FOSDEM.mdwn ./doc/news/version_3.20120229/comment_5_7dbf131ff4611abbfc8fbf1ee0f66dbe._comment ./doc/news/version_3.20120229/comment_2_03436ddda42decf8cb1b4d5316d88a75._comment ./doc/news/version_3.20120229/comment_3_8f7f8d4758804f1b695925934219745a._comment ./doc/news/version_3.20120229/comment_4_cd90223f78571e5bdd3dfc07ab1369d7._comment ./doc/news/version_3.20120229/comment_1_18158b9be2313f49509d59295c7d3c90._comment ./doc/news/LWN_article.mdwn ./doc/news/version_3.20120230.mdwn ./doc/news/version_3.20120227/comment_2_ea5075cfecc50d5da2364931ef7a02d1._comment ./doc/news/version_3.20120227/comment_1_f8fc894680f2a2e5b5e757a677414b42._comment ./doc/news/version_3.20120106/comment_1_fb1a3135e2d9f39f2c372ccc2c50c85a._comment ./doc/news/version_3.20120106/comment_2_ae292ca7294b6790233e545086c3ac2f._comment ./doc/news/version_3.20120106/comment_3_29ccda9ac458fd5cc9ec5508c62df6ea._comment ./doc/git-union-merge.mdwn ./doc/special_remotes/S3.mdwn ./doc/special_remotes/web.mdwn ./doc/special_remotes/bup.mdwn ./doc/special_remotes/directory.mdwn ./doc/special_remotes/hook.mdwn ./doc/special_remotes/rsync.mdwn ./doc/how_it_works.mdwn ./doc/sitemap.mdwn ./doc/users/joey.mdwn ./doc/users/fmarier.mdwn ./doc/users/chrysn.mdwn ./doc/users/gebi.mdwn ./doc/templates/walkthrough.tmpl ./doc/templates/bugtemplate.mdwn ./doc/templates/bare.tmpl ./doc/index.mdwn ./doc/sync/comment_1_59681be5568f568f5c54eb0445163dd2._comment ./doc/summary.mdwn ./doc/forum.mdwn ./doc/encryption/comment_1_1afca8d7182075d46db41f6ad3dd5911._comment ./doc/transferring_data.mdwn ./doc/download.mdwn ./doc/future_proofing.mdwn ./doc/todo/redundancy_stats_in_status.mdwn ./doc/todo/auto_remotes/discussion.mdwn ./doc/todo/link_file_to_remote_repo_feature.mdwn ./doc/todo/file_copy_progress_bar.mdwn ./doc/todo/use_cp_reflink.mdwn ./doc/todo/gitrm.mdwn ./doc/todo/exclude_files_on_a_given_remote.mdwn ./doc/todo/git-annex_unused_eats_memory.mdwn ./doc/todo/Please_abort_build_if___34__make_test__34___fails.mdwn ./doc/todo/fsck_special_remotes.mdwn ./doc/todo/add_--exclude_option_to_git_annex_find.mdwn ./doc/todo/tahoe_lfs_for_reals/comment_2_80b9e848edfdc7be21baab7d0cef0e3a._comment ./doc/todo/tahoe_lfs_for_reals/comment_1_0a4793ce6a867638f6e510e71dd4bb44._comment ./doc/todo/object_dir_reorg_v2.mdwn ./doc/todo/S3.mdwn ./doc/todo/auto_remotes.mdwn ./doc/todo/wishlist:_support_for_more_ssh_urls_.mdwn ./doc/todo/support-non-utf8-locales.mdwn ./doc/todo/done.mdwn ./doc/todo/fsck.mdwn ./doc/todo/support_S3_multipart_uploads.mdwn ./doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates.mdwn ./doc/todo/pushpull.mdwn ./doc/todo/smudge.mdwn ./doc/todo/cache_key_info/comment_1_578df1b3b2cbfdc4aa1805378f35dc48._comment ./doc/todo/windows_support.mdwn ./doc/todo/optimise_git-annex_merge.mdwn ./doc/todo/object_dir_reorg_v2/comment_3_79bdf9c51dec9f52372ce95b53233bb2._comment ./doc/todo/object_dir_reorg_v2/comment_7_42501404c82ca07147e2cce0cff59474._comment ./doc/todo/object_dir_reorg_v2/comment_5_821c382987f105da72a50e0a5ce61fdc._comment ./doc/todo/object_dir_reorg_v2/comment_1_ba03333dc76ff49eccaba375e68cb525._comment ./doc/todo/object_dir_reorg_v2/comment_2_81276ac309959dc741bc90101c213ab7._comment ./doc/todo/object_dir_reorg_v2/comment_6_8834c3a3f1258c4349d23aff8549bf35._comment ./doc/todo/object_dir_reorg_v2/comment_4_93aada9b1680fed56cc6f0f7c3aca5e5._comment ./doc/todo/union_mounting.mdwn ./doc/todo/wishlist:_swift_backend.mdwn ./doc/todo/Please_add_support_for_monad-control_0.3.x.mdwn ./doc/todo/wishlist:_swift_backend/comment_1_e6efbb35f61ee521b473a92674036788._comment ./doc/todo/wishlist:_swift_backend/comment_2_5d8c83b0485112e98367b7abaab3f4e3._comment ./doc/todo/git_annex_init_:_include_repo_description_and__47__or_UUID_in_commit_message.mdwn ./doc/todo/gitolite_and_gitosis_support.mdwn ./doc/todo/wishlist:___34__git_annex_add__34___multiple_processes.mdwn ./doc/todo/hidden_files.mdwn ./doc/todo/smudge/comment_1_4ea616bcdbc9e9a6fae9f2e2795c31c9._comment ./doc/todo/smudge/comment_2_e04b32caa0d2b4c577cdaf382a3ff7f6._comment ./doc/todo/network_remotes.mdwn ./doc/todo/add_a_git_backend.mdwn ./doc/todo/parallel_possibilities/comment_1_d8e34fc2bc4e5cf761574608f970d496._comment ./doc/todo/parallel_possibilities/comment_2_adb76f06a7997abe4559d3169a3181c3._comment ./doc/todo/checkout.mdwn ./doc/todo/immutable_annexed_files.mdwn ./doc/todo/wishlist:_Prevent_repeated_password_prompts_for_one_command.mdwn ./doc/todo/git-annex-shell.mdwn ./doc/todo/speed_up_fsck.mdwn ./doc/todo/tahoe_lfs_for_reals.mdwn ./doc/todo/avoid_unnecessary_union_merges.mdwn ./doc/todo/support_fsck_in_bare_repos.mdwn ./doc/todo/add_-all_option.mdwn ./doc/todo/using_url_backend.mdwn ./doc/todo/branching.mdwn ./doc/todo/rsync.mdwn ./doc/todo/backendSHA1.mdwn ./doc/todo/cache_key_info.mdwn ./doc/todo/parallel_possibilities.mdwn ./doc/todo/symlink_farming_commit_hook.mdwn ./doc/feeds.mdwn ./doc/sync.mdwn ./doc/copies.mdwn ./doc/repomap.png ./doc/scalability.mdwn ./doc/special_remotes.mdwn ./doc/todo.mdwn ./doc/walkthrough/using_ssh_remotes.mdwn ./doc/walkthrough/automatically_managing_content.mdwn ./doc/walkthrough/removing_files/comment_1_cb65e7c510b75be1c51f655b058667c6._comment ./doc/walkthrough/removing_files/comment_2_64709ea4558915edd5c8ca4486965b07._comment ./doc/walkthrough/moving_file_content_between_repositories.mdwn ./doc/walkthrough/modifying_annexed_files.mdwn ./doc/walkthrough/more.mdwn ./doc/walkthrough/removing_files.mdwn ./doc/walkthrough/creating_a_repository.mdwn ./doc/walkthrough/adding_a_remote.mdwn ./doc/walkthrough/adding_a_remote/comment_1_0a59355bd33a796aec97173607e6adc9._comment ./doc/walkthrough/adding_a_remote/comment_2_f8cd79ef1593a8181a7f1086a87713e8._comment ./doc/walkthrough/adding_a_remote/comment_3_60691af4400521b5a8c8d75efe3b44cb._comment ./doc/walkthrough/adding_a_remote/comment_4_6f7cf5c330272c96b3abeb6612075c9d._comment ./doc/walkthrough/removing_files:_When_things_go_wrong.mdwn ./doc/walkthrough/renaming_files.mdwn ./doc/walkthrough/using_bup.mdwn ./doc/walkthrough/fsck:_when_things_go_wrong.mdwn ./doc/walkthrough/syncing.mdwn ./doc/walkthrough/adding_files.mdwn ./doc/walkthrough/unused_data.mdwn ./doc/walkthrough/fsck:_verifying_your_data.mdwn ./doc/walkthrough/getting_file_content.mdwn ./doc/walkthrough/backups.mdwn ./doc/walkthrough/transferring_files:_When_things_go_wrong.mdwn ./doc/GPL ./doc/logo.png ./doc/location_tracking.mdwn ./doc/design.mdwn ./doc/news.mdwn ./doc/tips/visualizing_repositories_with_gource/screenshot.jpg ./doc/tips/untrusted_repositories.mdwn ./doc/tips/using_box.com_as_a_special_remote.mdwn ./doc/tips/automatically_getting_files_on_checkout.mdwn ./doc/tips/what_to_do_when_a_repository_is_corrupted.mdwn ./doc/tips/Internet_Archive_via_S3.mdwn ./doc/tips/what_to_do_when_you_lose_a_repository.mdwn ./doc/tips/using_Amazon_S3.mdwn ./doc/tips/using_the_web_as_a_special_remote.mdwn ./doc/tips/assume-unstaged.mdwn ./doc/tips/powerful_file_matching.mdwn ./doc/tips/using_gitolite_with_git-annex.mdwn ./doc/tips/recover_data_from_lost+found.mdwn ./doc/tips/visualizing_repositories_with_gource.mdwn ./doc/tips/centralized_git_repository_tutorial.mdwn ./doc/tips/finding_duplicate_files/comment_1_ddb477ca242ffeb21e0df394d8fdf5d2._comment ./doc/tips/using_git_annex_with_no_fixed_hostname_and_optimising_ssh.mdwn ./doc/tips/using_gitolite_with_git-annex/comment_4_eb81f824aadc97f098379c5f7e4fba4c._comment ./doc/tips/using_gitolite_with_git-annex/comment_6_3e203e010a4df5bf03899f867718adc5._comment ./doc/tips/using_gitolite_with_git-annex/comment_1_9a2a2a8eac9af97e0c984ad105763a73._comment ./doc/tips/using_gitolite_with_git-annex/comment_8_8249772c142117f88e37975d058aa936._comment ./doc/tips/using_gitolite_with_git-annex/comment_5_f688309532d2993630e9e72e87fb9c46._comment ./doc/tips/using_gitolite_with_git-annex/comment_7_f8fd08b6ab47378ad88c87348057220d._comment ./doc/tips/using_gitolite_with_git-annex/comment_3_807035f38509ccb9f93f1929ecd37417._comment ./doc/tips/using_gitolite_with_git-annex/comment_9_28418635a6ed7231b89e02211cd3c236._comment ./doc/tips/using_gitolite_with_git-annex/comment_2_d8efea4ab9576555fadbb47666ecefa9._comment ./doc/tips/finding_duplicate_files.mdwn ./doc/tips/centralised_repository:_starting_from_nothing.mdwn ./doc/tips/using_the_SHA1_backend.mdwn ./doc/tips/migrating_data_to_a_new_backend.mdwn ./doc/encryption.mdwn ./doc/not.mdwn ./doc/download/comment_7_a5eebd214b135f34b18274a682211943._comment ./doc/download/comment_3_cf6044ebe99f71158034e21197228abd._comment ./doc/download/comment_5_c6b1bc40226fc2c8ba3e558150856992._comment ./doc/download/comment_6_3a52993d3553deb9a413debec9a5f92d._comment ./doc/download/comment_2_f85f72b33aedc3425f0c0c47867d02f3._comment ./doc/download/comment_8_59a976de6c7d333709b92f7cd5830850._comment ./doc/download/comment_4_10fc013865c7542c2ed9d6c0963bb391._comment ./doc/download/comment_1_fbd8b6d39e9d3c71791551358c863966._comment ./doc/contact.mdwn ./doc/trust.mdwn ./doc/bare_repositories.mdwn ./doc/NixOS.mdwn ./doc/distributed_version_control.mdwn ./doc/install.mdwn ./doc/git-annex-shell.mdwn ./doc/bugs.mdwn ./doc/meta.mdwn ./doc/design/encryption/comment_2_a610b3d056a059899178859a3a821ea5._comment ./doc/design/encryption/comment_3_cca186a9536cd3f6e86994631b14231c._comment ./doc/design/encryption/comment_1_4715ffafb3c4a9915bc33f2b26aaa9c1._comment ./doc/design/encryption/comment_4_8f3ba3e504b058791fc6e6f9c38154cf._comment ./doc/design/encryption.mdwn ./doc/comments.mdwn ./doc/git-annex.mdwn ./doc/internals.mdwn ./doc/users.mdwn ./doc/install/Ubuntu.mdwn ./doc/install/Debian.mdwn ./doc/install/openSUSE.mdwn ./doc/install/OSX.mdwn ./doc/install/FreeBSD.mdwn ./doc/install/OSX/comment_1_0a1760bf0db1f1ba89bdb4c62032f631._comment ./doc/install/ArchLinux.mdwn ./doc/install/Debian/comment_2_648e3467e260cdf233acdb0b53313ce0._comment ./doc/install/Debian/comment_1_029486088d098c2d4f1099f2f0e701a9._comment ./doc/install/Fedora.mdwn ./doc/walkthrough.mdwn ./CmdLine.hs ./Messages.hs ./Setup.hs ./GPL ./mdwn2man ./Remote.hs ./git-annex.hs ./Locations.hs ./Usage.hs ./Backend/WORM.hs ./Backend/URL.hs ./Backend/SHA.hs ./git-annex-shell.hs ./test.hs ./INSTALL ./Remote/Web.hs ./Remote/Helper/Encryptable.hs ./Remote/Helper/Ssh.hs ./Remote/Helper/Special.hs ./Remote/Helper/Hooks.hs ./Remote/Directory.hs ./Remote/List.hs ./Remote/Bup.hs ./Remote/Hook.hs ./Remote/S3.hs ./Remote/Rsync.hs ./Remote/Git.hs ./Build/TestConfig.hs ./Upgrade.hs ./Annex/Version.hs ./Annex/Exception.hs ./Annex/Journal.hs ./Annex/CatFile.hs ./Annex/Ssh.hs ./Annex/Queue.hs ./Annex/Branch.hs ./Annex/UUID.hs ./Annex/LockPool.hs ./Annex/BranchState.hs ./Annex/CheckAttr.hs ./Annex/Content.hs ./git-union-merge.hs ./Utility/Path.hs ./Utility/Matcher.hs ./Utility/TempFile.hs ./Utility/State.hs ./Utility/Url.hs ./Utility/DataUnits.hs ./Utility/StatFS.hsc ./Utility/CoProcess.hs ./Utility/Exception.hs ./Utility/Monad.hs ./Utility/RsyncFile.hs ./Utility/CopyFile.hs ./Utility/Misc.hs ./Utility/SafeCommand.hs ./Utility/Gpg.hs ./Utility/Directory.hs ./Utility/FileSystemEncoding.hs ./Utility/FileMode.hs ./Utility/PartialPrelude.hs ./Utility/JSONStream.hs ./Utility/Dot.hs ./Utility/Touch.hsc ./Utility/Base64.hs ./Utility/Format.hs ./Types/Option.hs ./Types/Crypto.hs ./Types/UUID.hs ./Types/TrustLevel.hs ./Types/Remote.hs ./Types/BranchState.hs ./Types/Command.hs ./Types/Backend.hs ./Types/Key.hs ./Config.hs ./Checks.hs ./Command.hs ./.gitignore ./Backend.hs ./Logs/Web.hs ./Logs/UUIDBased.hs ./Logs/Trust.hs ./Logs/Location.hs ./Logs/UUID.hs ./Logs/Remote.hs ./Logs/Presence.hs ./.gitattributes ./Git.hs ./Limit.hs ./GitAnnex.hs+Extra-Source-Files: ./debian/NEWS ./debian/control ./debian/rules ./debian/changelog ./debian/doc-base ./debian/copyright ./debian/compat ./Messages/JSON.hs ./NEWS ./Option.hs ./configure.hs ./Annex.hs ./Seek.hs ./Crypto.hs ./Common.hs ./README ./Command/Merge.hs ./Command/AddUrl.hs ./Command/Whereis.hs ./Command/Unlock.hs ./Command/Commit.hs ./Command/Version.hs ./Command/FromKey.hs ./Command/PreCommit.hs ./Command/Sync.hs ./Command/Map.hs ./Command/Unused.hs ./Command/Uninit.hs ./Command/ReKey.hs ./Command/Migrate.hs ./Command/Init.hs ./Command/ConfigList.hs ./Command/Trust.hs ./Command/Lock.hs ./Command/SendKey.hs ./Command/RecvKey.hs ./Command/Reinject.hs ./Command/Add.hs ./Command/Fix.hs ./Command/Untrust.hs ./Command/Dead.hs ./Command/InitRemote.hs ./Command/Semitrust.hs ./Command/Fsck.hs ./Command/Move.hs ./Command/DropUnused.hs ./Command/Get.hs ./Command/Upgrade.hs ./Command/Describe.hs ./Command/Drop.hs ./Command/DropKey.hs ./Command/InAnnex.hs ./Command/Find.hs ./Command/Log.hs ./Command/Unannex.hs ./Command/Status.hs ./Command/Copy.hs ./Init.hs ./Types.hs ./Common/Annex.hs ./Makefile ./git-annex.cabal ./Upgrade/V1.hs ./Upgrade/V2.hs ./Upgrade/V0.hs ./GitAnnexShell.hs ./CHANGELOG ./Git/LsFiles.hs ./Git/Version.hs ./Git/UnionMerge.hs ./Git/Url.hs ./Git/HashObject.hs ./Git/Types.hs ./Git/CatFile.hs ./Git/Queue.hs ./Git/Ref.hs ./Git/Filename.hs ./Git/Branch.hs ./Git/Sha.hs ./Git/LsTree.hs ./Git/Config.hs ./Git/CheckAttr.hs ./Git/Command.hs ./Git/Construct.hs ./Git/Index.hs ./doc/upgrades.mdwn ./doc/forum/Recommended_number_of_repositories.mdwn ./doc/forum/unlock__47__lock_always_gets_me.mdwn ./doc/forum/wishlist:_define_remotes_that_must_have_all_files.mdwn ./doc/forum/Will_git_annex_work_on_a_FAT32_formatted_key__63__.mdwn ./doc/forum/wishlist:_command_options_changes/comment_2_f6a637c78c989382e3c22d41b7fb4cc2._comment ./doc/forum/wishlist:_command_options_changes/comment_3_bf1114533d2895804e531e76eb6b8095._comment ./doc/forum/wishlist:_command_options_changes/comment_1_bfba72a696789bf21b2435dea15f967a._comment ./doc/forum/pure_git-annex_only_workflow/comment_4_dc8a3f75533906ad3756fcc47f7e96bb._comment ./doc/forum/pure_git-annex_only_workflow/comment_15_cb7c856d8141b2de3cc95874753f1ee5._comment ./doc/forum/pure_git-annex_only_workflow/comment_7_33db51096f568c65b22b4be0b5538c0d._comment ./doc/forum/pure_git-annex_only_workflow/comment_9_ace319652f9c7546883b5152ddc82591._comment ./doc/forum/pure_git-annex_only_workflow/comment_12_ca8ca35d6cd4a9f94568536736c12adc._comment ./doc/forum/pure_git-annex_only_workflow/comment_10_683768c9826b0bf0f267e8734b9eb872._comment ./doc/forum/pure_git-annex_only_workflow/comment_11_6b541ed834ef45606f3b98779a25a148._comment ./doc/forum/pure_git-annex_only_workflow/comment_14_b63568b327215ef8f646a39d760fdfc0._comment ./doc/forum/pure_git-annex_only_workflow/comment_8_6e5b42fdb7801daadc0b3046cbc3d51e._comment ./doc/forum/pure_git-annex_only_workflow/comment_1_a32f7efd18d174845099a4ed59e6feae._comment ./doc/forum/pure_git-annex_only_workflow/comment_13_00c82d320c7b4bb51078beba17e14dc8._comment ./doc/forum/pure_git-annex_only_workflow/comment_3_9b7d89da52f7ebb7801f9ec8545c3aba._comment ./doc/forum/pure_git-annex_only_workflow/comment_6_3660d45c5656f68924acbd23790024ee._comment ./doc/forum/pure_git-annex_only_workflow/comment_2_66dc9b65523a9912411db03c039ba848._comment ./doc/forum/pure_git-annex_only_workflow/comment_5_afe5035a6b35ed2c7e193fb69cc182e2._comment ./doc/forum/wishlist:_git-annex_replicate/comment_3_c13f4f9c3d5884fc6255fd04feadc2b1._comment ./doc/forum/wishlist:_git-annex_replicate/comment_1_9926132ec6052760cdf28518a24e2358._comment ./doc/forum/wishlist:_git-annex_replicate/comment_2_c43932f4194aba8fb2470b18e0817599._comment ./doc/forum/wishlist:_git-annex_replicate/comment_4_63f24abf086d644dced8b01e1a9948c9._comment ./doc/forum/Podcast_syncing_use-case/comment_1_ace6f9d3a950348a3ac0ff592b62e786._comment ./doc/forum/Podcast_syncing_use-case/comment_2_930a6620b4d516e69ed952f9da5371bb._comment ./doc/forum/Behaviour_of_fsck/comment_4_e4911dc6793f98fb81151daacbe49968._comment ./doc/forum/Behaviour_of_fsck/comment_3_97848f9a3db89c0427cfb671ba13300e._comment ./doc/forum/Behaviour_of_fsck/comment_2_ead36a23c3e6efa1c41e4555f93e014e._comment ./doc/forum/Behaviour_of_fsck/comment_1_0e40f158b3f4ccdcaab1408d858b68b8._comment ./doc/forum/incompatible_versions__63__/comment_1_629f28258746d413e452cbd42a1a43f4._comment ./doc/forum/vlc_and_git-annex/comment_1_9c9ab8ce463cf74418aa2f385955f165._comment ./doc/forum/vlc_and_git-annex/comment_2_037f94c1deeac873dbdb36cd4c927e45._comment ./doc/forum/Recommended_number_of_repositories/comment_1_3ef256230756be8a9679b107cdbfd018._comment ./doc/forum/migration_to_git-annex_and_rsync.mdwn ./doc/forum/hashing_objects_directories.mdwn ./doc/forum/git_annex_ls___47___metadata_in_git_annex_whereis.mdwn ./doc/forum/unlock__47__lock_always_gets_me/comment_1_dee73a7ea3e1a5154601adb59782831f._comment ./doc/forum/git-subtree_support__63__.mdwn ./doc/forum/Podcast_syncing_use-case.mdwn ./doc/forum/hashing_objects_directories/comment_5_ef6cfd49d24c180c2d0a062e5bd3a0be._comment ./doc/forum/hashing_objects_directories/comment_1_c55c56076be4f54251b0b7f79f28a607._comment ./doc/forum/hashing_objects_directories/comment_2_504c96959c779176f991f4125ea22009._comment ./doc/forum/hashing_objects_directories/comment_3_9134bde0a13aac0b6a4e5ebabd7f22e8._comment ./doc/forum/hashing_objects_directories/comment_4_0de9170e429cbfea66f5afa8980d45ac._comment ./doc/forum/location_tracking_cleanup.mdwn ./doc/forum/Wishlist:_Ways_of_selecting_files_based_on_meta-information.mdwn ./doc/forum/confusion_with_remotes__44___map.mdwn ./doc/forum/git-annex_on_OSX.mdwn ./doc/forum/A_really_stupid_question.mdwn ./doc/forum/post-copy__47__sync_hook.mdwn ./doc/forum/git_tag_missing_for_3.20111011/comment_1_7a53bf273f3078ab3351369ef2b5f2a6._comment ./doc/forum/version_3_upgrade/comment_1_05fc9c9cad26c520bebb98c852c71e35._comment ./doc/forum/example_of_massively_disconnected_operation.mdwn ./doc/forum/git-annex_communication_channels/comment_2_c7aeefa6ef9a2e75d8667b479ade1b7f._comment ./doc/forum/git-annex_communication_channels/comment_5_404b723a681eb93fee015cea8024b6bc._comment ./doc/forum/git-annex_communication_channels/comment_1_198325d2e9337c90f026396de89eec0e._comment ./doc/forum/git-annex_communication_channels/comment_4_1ba6ddf54843c17c7d19a9996f2ab712._comment ./doc/forum/git-annex_communication_channels/comment_6_0d87d0e26461494b1d7f8a701a924729._comment ./doc/forum/git-annex_communication_channels/comment_3_1ff08a3e0e63fa0e560cbc9602245caa._comment ./doc/forum/git-annex_communication_channels/comment_7_2c87c7a0648fe87c2bf6b4391f1cc468._comment ./doc/forum/wishlist:_git-annex_replicate.mdwn ./doc/forum/advantages_of_SHA__42___over_WORM/comment_1_96c354cac4b5ce5cf6664943bc84db1d._comment ./doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk.mdwn ./doc/forum/Behaviour_of_fsck.mdwn ./doc/forum/git_annex_add_crash_and_subsequent_recovery.mdwn ./doc/forum/Handling_web_special_remote_when_content_changes__63__.mdwn ./doc/forum/nfs_mounted_repo_results_in_errors_on_drop__47__move.mdwn ./doc/forum/working_without_git-annex_commits.mdwn ./doc/forum/migrate_existing_git_repository_to_git-annex.mdwn ./doc/forum/__34__git_annex_lock__34___very_slow_for_big_repo.mdwn ./doc/forum/wishlist:_traffic_accounting_for_git-annex.mdwn ./doc/forum/git_pull_remote_git-annex.mdwn ./doc/forum/rsync_over_ssh__63__.mdwn ./doc/forum/unannex_alternatives/comment_3_b1687fc8f9e7744327bbeb6f0635d1cd._comment ./doc/forum/unannex_alternatives/comment_1_dcd4cd41280b41512bbdffafaf307993._comment ./doc/forum/unannex_alternatives/comment_2_58a72a9fe0f58c7af0b4d7927a2dd21d._comment ./doc/forum/wishlist:_git_annex_status/comment_4_9aeeb83d202dc8fb33ff364b0705ad94._comment ./doc/forum/wishlist:_git_annex_status/comment_3_d1fd70c67243971c96d59e1ffb7ef6e7._comment ./doc/forum/wishlist:_git_annex_status/comment_2_c2b0ce025805b774dc77ce264a222824._comment ./doc/forum/wishlist:_git_annex_status/comment_1_994bfd12c5d82e08040d6116915c5090._comment ./doc/forum/git_pull_remote_git-annex/comment_7_24c45ee981b18bc78325c768242e635d._comment ./doc/forum/git_pull_remote_git-annex/comment_2_0f7f4a311b0ec1d89613e80847e69b42._comment ./doc/forum/git_pull_remote_git-annex/comment_1_9c245db3518d8b889ecdf5115ad9e053._comment ./doc/forum/git_pull_remote_git-annex/comment_5_4f2a05ef6551806dd0ec65372f183ca4._comment ./doc/forum/git_pull_remote_git-annex/comment_4_646f2077edcabc000a7d9cb75a93cf55._comment ./doc/forum/git_pull_remote_git-annex/comment_8_7e76ee9b6520cbffaf484c9299a63ad3._comment ./doc/forum/git_pull_remote_git-annex/comment_3_1aa89725b5196e40a16edeeb5ccfa371._comment ./doc/forum/git_pull_remote_git-annex/comment_6_3925d1aa56bce9380f712e238d63080f._comment ./doc/forum/Please_fix_compatibility_with_ghc_7.0.mdwn ./doc/forum/wishlist:_command_options_changes.mdwn ./doc/forum/location_tracking_cleanup/comment_3_c15428cec90e969284a5e690fb4b2fde._comment ./doc/forum/location_tracking_cleanup/comment_2_e7395cb6e01f42da72adf71ea3ebcde4._comment ./doc/forum/location_tracking_cleanup/comment_1_7d6319e8c94dfe998af9cfcbf170efb2._comment ./doc/forum/new_microfeatures/comment_2_41ad904c68e89c85e1fc49c9e9106969._comment ./doc/forum/new_microfeatures/comment_1_058bd517c6fffaf3446b1f5d5be63623._comment ./doc/forum/new_microfeatures/comment_3_a1a9347b5bc517f2a89a8b292c3f8517._comment ./doc/forum/new_microfeatures/comment_7_94045b9078b1fff877933b012d1b49e2._comment ./doc/forum/new_microfeatures/comment_5_3c627d275586ff499d928a8f8136babf._comment ./doc/forum/new_microfeatures/comment_4_5a6786dc52382fff5cc42fdb05770196._comment ./doc/forum/new_microfeatures/comment_6_31ea08c008500560c0b96c6601bc6362._comment ./doc/forum/Error_while_adding_a_file___34__createSymbolicLink:_already_exists__34__.mdwn ./doc/forum/How_to_expire_old_versions_of_files_that_have_been_edited__63__.mdwn ./doc/forum/advantages_of_SHA__42___over_WORM.mdwn ./doc/forum/wishlist:_git_annex_put_--_same_as_get__44___but_for_defaults.mdwn ./doc/forum/cloud_services_to_support.mdwn ./doc/forum/OSX__39__s_default_sshd_behaviour_has_limited_paths_set.mdwn ./doc/forum/Auto_archiving.mdwn ./doc/forum/bainstorming:_git_annex_push___38___pull.mdwn ./doc/forum/sparse_git_checkouts_with_annex.mdwn ./doc/forum/Need_new_build_instructions_for_Debian_stable.mdwn ./doc/forum/batch_check_on_remote_when_using_copy.mdwn ./doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs.mdwn ./doc/forum/wishlist:alias_system.mdwn ./doc/forum/incompatible_versions__63__.mdwn ./doc/forum/Automatic_commit_messages_for_git_annex_sync.mdwn ./doc/forum/fsck_gives_false_positives.mdwn ./doc/forum/Preserving_file_access_rights_in_directory_tree_below_objects__47__.mdwn ./doc/forum/A_really_stupid_question/comment_1_40e02556de0b00b94f245a0196b5a89f._comment ./doc/forum/wishlist:_git_backend_for_git-annex.mdwn ./doc/forum/vlc_and_git-annex.mdwn ./doc/forum/seems_to_build_fine_on_haskell_platform_2011.mdwn ./doc/forum/rsync_over_ssh__63__/comment_1_ee21f32e90303e20339e0a568321bbbe._comment ./doc/forum/rsync_over_ssh__63__/comment_2_aa690da6ecfb2b30fc5080ad76dc77b1._comment ./doc/forum/wishlist:_special_remote_for_sftp_or_rsync.mdwn ./doc/forum/OSX__39__s_haskell-platform_statically_links_things.mdwn ./doc/forum/using_git_annex_to_merge_and_synchronize_2_directories___40__like_unison__41__.mdwn ./doc/forum/git_tag_missing_for_3.20111011.mdwn ./doc/forum/unannex_alternatives.mdwn ./doc/forum/can_git-annex_replace_ddm__63__.mdwn ./doc/forum/sparse_git_checkouts_with_annex/comment_2_e357db3ccc4079f07a291843975535eb._comment ./doc/forum/sparse_git_checkouts_with_annex/comment_1_c7dc199c5740a0e7ba606dfb5e3e579a._comment ./doc/forum/sparse_git_checkouts_with_annex/comment_3_fcfafca994194d57dccf5319c7c9e646._comment ./doc/forum/sparse_git_checkouts_with_annex/comment_4_04dc14880f31eee2b6d767d4d4258c5a._comment ./doc/forum/syncing_non-git_trees_with_git-annex.mdwn ./doc/forum/git-annex_communication_channels.mdwn ./doc/forum/fsck_gives_false_positives/comment_4_7ceb395bf8a2e6a041ccd8de63b1b6eb._comment ./doc/forum/fsck_gives_false_positives/comment_3_692d6d4cd2f75a497e7d314041a768d2._comment ./doc/forum/fsck_gives_false_positives/comment_5_86484a504c3bbcecd5876982b9c95688._comment ./doc/forum/fsck_gives_false_positives/comment_2_f51c53f3f6e6ee1ad463992657db5828._comment ./doc/forum/fsck_gives_false_positives/comment_1_b91070218b9d5fb687eeee1f244237ad._comment ./doc/forum/can_git-annex_replace_ddm__63__/comment_3_4c69097fe2ee81359655e59a03a9bb8d._comment ./doc/forum/can_git-annex_replace_ddm__63__/comment_2_008554306dd082d7f543baf283510e92._comment ./doc/forum/can_git-annex_replace_ddm__63__/comment_1_aa05008dfe800474ff76678a400099e1._comment ./doc/forum/version_3_upgrade.mdwn ./doc/forum/relying_on_git_for_numcopies/comment_3_43d8e1513eb9947f8a503f094c03f307._comment ./doc/forum/relying_on_git_for_numcopies/comment_2_be6acbc26008a9cb54e7b8f498f2c2a2._comment ./doc/forum/relying_on_git_for_numcopies/comment_1_8ad3cccd7f66f6423341d71241ba89fc._comment ./doc/forum/confusion_with_remotes__44___map/comment_1_a38ded23b7f288292a843abcb1a56f38._comment ./doc/forum/confusion_with_remotes__44___map/comment_2_cd1c98b1276444e859a22c3dbd6f2a79._comment ./doc/forum/confusion_with_remotes__44___map/comment_6_496b0d9b86869bbac3a1356d53a3dda4._comment ./doc/forum/confusion_with_remotes__44___map/comment_5_27801584325d259fa490f67273f2ff71._comment ./doc/forum/confusion_with_remotes__44___map/comment_4_3b89b6d1518267fcbc050c9de038b9ca._comment ./doc/forum/confusion_with_remotes__44___map/comment_3_18531754089c991b6caefc57a5c17fe9._comment ./doc/forum/confusion_with_remotes__44___map/comment_7_9a456f61f956a3d5e81e723d5a90794c._comment ./doc/forum/--print0_option_as_in___34__find__34__.mdwn ./doc/forum/relying_on_git_for_numcopies.mdwn ./doc/forum/wishlist:_do_round_robin_downloading_of_data.mdwn ./doc/forum/pure_git-annex_only_workflow.mdwn ./doc/forum/post-copy__47__sync_hook/comment_1_c8322d4b9bbf5eac80b48c312a42fbcf._comment ./doc/forum/wishlist:_git_annex_status.mdwn ./doc/forum/getting_git_annex_to_do_a_force_copy_to_a_remote.mdwn ./doc/forum/Problems_with_large_numbers_of_files.mdwn ./doc/forum/Can_I_store_normal_files_in_the_git-annex_git_repository__63__.mdwn ./doc/forum/Is_an_automagic_upgrade_of_the_object_directory_safe__63__.mdwn ./doc/forum/windows_port__63__.mdwn ./doc/forum/windows_port__63__/comment_1_23fa9aa3b00940a1c1b3876c35eef019._comment ./doc/forum/wishlist:_push_to_cia.vc_from_the_website__39__s_repo__44___not_your_personal_one.mdwn ./doc/forum/new_microfeatures.mdwn ./doc/forum/git-subtree_support__63__/comment_2_73d2a015b1ac79ec99e071a8b1e29034._comment ./doc/forum/git-subtree_support__63__/comment_1_4f333cb71ed1ff259bbfd86704806aa6._comment ./doc/forum/git-subtree_support__63__/comment_4_75b0e072e668aa46ff0a8d62a6620306._comment ./doc/forum/git-subtree_support__63__/comment_3_c533400e22c306c033fcd56e64761b0b._comment ./doc/forum/git-subtree_support__63__/comment_6_85df530f7b6d76b74ac8017c6034f95e._comment ./doc/forum/git-subtree_support__63__/comment_5_f5ec9649d9f1dc122e715de5533bc674._comment ./doc/backends.mdwn ./doc/bugs/__39__annex_add__39___fails_to___39__git_add__39___for_parent_relative_path.mdwn ./doc/bugs/uuid.log_trust.log_and_remote.log_merge_wackiness.mdwn ./doc/bugs/Remote_repo_and_set_operation_with_find.mdwn ./doc/bugs/softlink_mtime.mdwn ./doc/bugs/uninit_should_not_run_when_branch_git-annex_is_checked_out.mdwn ./doc/bugs/ordering.mdwn ./doc/bugs/dropping_files_with_a_URL_backend_fails.mdwn ./doc/bugs/fsck__47__fix_should_check__47__fix_the_permissions_of_.git__47__annex.mdwn ./doc/bugs/dropunused_doesn__39__t_handle_double_spaces_in_filename.mdwn ./doc/bugs/add_script-friendly_output_options.mdwn ./doc/bugs/uninit_does_not_work_in_old_repos.mdwn ./doc/bugs/conq:_invalid_command_syntax.mdwn ./doc/bugs/git_annex_get_choke_when_remote_is_an_ssh_url_with_a_port.mdwn ./doc/bugs/unannex_and_uninit_do_not_work_when_git_index_is_broken.mdwn ./doc/bugs/git_annex_migrate_leaves_old_backend_versions_around.mdwn ./doc/bugs/git_annex_unused_failes_on_empty_repository.mdwn ./doc/bugs/git_annex_add_eats_files_when_filename_is_too_long.mdwn ./doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing.mdwn ./doc/bugs/problem_with_upgrade_v2_-__62___v3.mdwn ./doc/bugs/git_annex_copy_--fast_does_not_copy_files.mdwn ./doc/bugs/Cabal_dependency_monadIO_missing.mdwn ./doc/bugs/dotdot_problem.mdwn ./doc/bugs/Problems_running_make_on_osx.mdwn ./doc/bugs/free_space_checking/comment_2_8a65f6d3dcf5baa3f7f2dbe1346e2615._comment ./doc/bugs/free_space_checking/comment_3_0fc6ff79a357b1619d13018ccacc7c10._comment ./doc/bugs/free_space_checking/comment_1_a868e805be43c5a7c19c41f1af8e41e6._comment ./doc/bugs/copy_doesn__39__t_scale.mdwn ./doc/bugs/Error_when_moving_annexed_file_to_a_.gitignored_location.mdwn ./doc/bugs/done.mdwn ./doc/bugs/git_annex_copy_-f_REMOTE_._doesn__39__t_work_as_expected.mdwn ./doc/bugs/Displayed_copy_speed_is_wrong/comment_2_8b240de1d5ae9229fa2d77d1cc15a552._comment ./doc/bugs/Displayed_copy_speed_is_wrong/comment_1_74de3091e8bfd7acd6795e61f39f07c6._comment ./doc/bugs/Build_error_on_Mac_OSX_10.6.mdwn ./doc/bugs/bare_git_repos.mdwn ./doc/bugs/nfs_mounted_repo_results_in_errors_on_drop_move.mdwn ./doc/bugs/fat_support.mdwn ./doc/bugs/problems_with_utf8_names.mdwn ./doc/bugs/error_with_file_names_starting_with_dash.mdwn ./doc/bugs/not_possible_to_have_annex_on_a_separate_filesystem.mdwn ./doc/bugs/Lost_S3_Remote.mdwn ./doc/bugs/unhappy_without_UTF8_locale.mdwn ./doc/bugs/S3_memory_leaks.mdwn ./doc/bugs/git_annex_map_has_problems_with_urls_containing___126__.mdwn ./doc/bugs/interrupting_migration_causes_problems.mdwn ./doc/bugs/upgrade_left_untracked_.git-annex__47____42___directories.mdwn ./doc/bugs/cyclic_drop.mdwn ./doc/bugs/Problems_running_make_on_osx/comment_9_cc283b485b3c95ba7eebc8f0c96969b3._comment ./doc/bugs/Problems_running_make_on_osx/comment_4_c52be386f79f14c8570a8f1397c68581._comment ./doc/bugs/Problems_running_make_on_osx/comment_18_64fab50d95de619eb2e8f08f90237de1._comment ./doc/bugs/Problems_running_make_on_osx/comment_16_5c2dd6002aadaab30841b77a5f5aed34._comment ./doc/bugs/Problems_running_make_on_osx/comment_10_94e4ac430140042a2d0fb5a16d86b4e5._comment ./doc/bugs/Problems_running_make_on_osx/comment_15_6b8867b8e48bf807c955779c9f8f0909._comment ./doc/bugs/Problems_running_make_on_osx/comment_11_56f1143fa191361d63b441741699e17f._comment ./doc/bugs/Problems_running_make_on_osx/comment_20_7db27d1a22666c831848bc6c06d66a84._comment ./doc/bugs/Problems_running_make_on_osx/comment_12_ec5131624d0d2285d3b6880e47033f97._comment ./doc/bugs/Problems_running_make_on_osx/comment_3_68f0f8ae953589ae26d57310b40c878d._comment ./doc/bugs/Problems_running_make_on_osx/comment_14_89a960b6706ed703b390a81a8bc4e311._comment ./doc/bugs/Problems_running_make_on_osx/comment_17_62fccb04b0e4b695312f7a3f32fb96ee._comment ./doc/bugs/Problems_running_make_on_osx/comment_19_4253988ed178054c8b6400beeed68a29._comment ./doc/bugs/Problems_running_make_on_osx/comment_6_0c46f5165ceb5a7b9ea9689c33b3a4f8._comment ./doc/bugs/Problems_running_make_on_osx/comment_1_34120e82331ace01a6a4960862d38f2d._comment ./doc/bugs/Problems_running_make_on_osx/comment_7_237a137cce58a28abcc736cbf2c420b0._comment ./doc/bugs/Problems_running_make_on_osx/comment_5_7f1330a1e541b0f3e2192e596d7f7bee._comment ./doc/bugs/Problems_running_make_on_osx/comment_2_cc53d1681d576186dbc868dd9801d551._comment ./doc/bugs/Problems_running_make_on_osx/comment_13_88ed095a448096bf8a69015a04e64df1._comment ./doc/bugs/Problems_running_make_on_osx/comment_8_efafa203addf8fa79e33e21a87fb5a2b._comment ./doc/bugs/git-annex_directory_hashing_problems_on_osx.mdwn ./doc/bugs/No_easy_way_to_re-inject_a_file_into_an_annex.mdwn ./doc/bugs/git_annex_unlock_is_not_atomic.mdwn ./doc/bugs/free_space_checking.mdwn ./doc/bugs/wishlist:_more_descriptive_commit_messages_in_git-annex_branch.mdwn ./doc/bugs/Displayed_copy_speed_is_wrong.mdwn ./doc/bugs/git_annex_should_use___39__git_add_-f__39___internally.mdwn ./doc/bugs/minor_bug:_errors_are_not_verbose_enough.mdwn ./doc/bugs/__34__make_test__34___fails_silently.mdwn ./doc/bugs/No_version_information_from_cli.mdwn ./doc/bugs/Error_while_adding_a_file___34__createSymbolicLink:_already_exists__34__.mdwn ./doc/bugs/conq:_invalid_command_syntax/comment_1_f33b83025ce974e496f83f248275a66a._comment ./doc/bugs/conq:_invalid_command_syntax/comment_2_195106ca8dedad5f4d755f625e38e8af._comment ./doc/bugs/conq:_invalid_command_syntax/comment_3_55af43e2f43a4c373f7a0a33678d0b1c._comment ./doc/bugs/old_data_isn__39__t_unused_after_migration.mdwn ./doc/bugs/fails_to_handle_lot_of_files.mdwn ./doc/bugs/tests_fail_when_there_is_no_global_.gitconfig_for_the_user.mdwn ./doc/bugs/git_annex_initremote_walks_.git-annex.mdwn ./doc/bugs/copy_doesn__39__t_scale/comment_1_7c12499c9ac28a9883c029f8c659eb57._comment ./doc/bugs/copy_doesn__39__t_scale/comment_2_f85d8023cdbc203bb439644cf7245d4e._comment ./doc/bugs/copy_doesn__39__t_scale/comment_3_4592765c3d77bb5664b8d16867e9d79c._comment ./doc/bugs/signal_weirdness.mdwn ./doc/bugs/git-annex_incorrectly_parses_bare_IPv6_addresses.mdwn ./doc/bugs/git_annex_version_should_without_being_in_a_repo_.mdwn ./doc/bugs/Can__39__t___34__git-annex_get__34___with_3.20111203.mdwn ./doc/bugs/Prevent_accidental_merges/comment_1_4c46a193915eab8f308a04175cb2e40a._comment ./doc/bugs/conflicting_haskell_packages/comment_1_e552a6cc6d7d1882e14130edfc2d6b3b._comment ./doc/bugs/tmp_file_handling.mdwn ./doc/bugs/annex_add_in_annex.mdwn ./doc/bugs/making_annex-merge_try_a_fast-forward.mdwn ./doc/bugs/bad_behaviour_with_file_names_with_newline_in_them.mdwn ./doc/bugs/Lost_S3_Remote/comment_2_c99c65882a3924f4890e500f9492b442._comment ./doc/bugs/Lost_S3_Remote/comment_3_1e434d5a20a692cd9dc7f6f8f20f30dd._comment ./doc/bugs/Lost_S3_Remote/comment_1_6e80e6db6671581d471fc9a54181c04c._comment ./doc/bugs/on--git-dir_and_--work-tree_options.mdwn ./doc/bugs/Makefile_is_missing_dependancies.mdwn ./doc/bugs/test_suite_shouldn__39__t_fail_silently.mdwn ./doc/bugs/git_annex_upgrade_output_is_inconsistent_and_spammy.mdwn ./doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_4_91439d4dbbf1461e281b276eb0003691._comment ./doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_6_f360f0006bc9115bc5a3e2eb9fe58abd._comment ./doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_3_86d9e7244ae492bcbe62720b8c4fc4a9._comment ./doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_2_cd0123392b16d89db41b45464165c247._comment ./doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_1_5f60006c9bb095167d817f234a14d20b._comment ./doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_5_ca33a9ca0df33f7c1b58353d7ffb943d._comment ./doc/bugs/wishlist:_query_things_like_description__44___trust_level.mdwn ./doc/bugs/git_rename_detection_on_file_move/comment_9_75e0973f6d573df615e01005ebcea87d._comment ./doc/bugs/git_rename_detection_on_file_move/comment_7_7f20d0b2f6ed1c34021a135438037306._comment ./doc/bugs/git_rename_detection_on_file_move/comment_3_57010bcaca42089b451ad8659a1e018e._comment ./doc/bugs/git_rename_detection_on_file_move/comment_4_79d96599f757757f34d7b784e6c0e81c._comment ./doc/bugs/git_rename_detection_on_file_move/comment_5_d61f5693d947b9736b29fca1dbc7ad76._comment ./doc/bugs/git_rename_detection_on_file_move/comment_8_6a00500b24ba53248c78e1ffc8d1a591._comment ./doc/bugs/git_rename_detection_on_file_move/comment_2_7101d07400ad5935f880dc00d89bf90e._comment ./doc/bugs/git_rename_detection_on_file_move/comment_6_f63de6fe2f7189c8c2908cc41c4bc963._comment ./doc/bugs/git_rename_detection_on_file_move/comment_1_0531dcfa833b0321a7009526efe3df33._comment ./doc/bugs/fsck_claims_failed_checksum_when_less_copies_than_required_are_found.mdwn ./doc/bugs/add_range_argument_to___34__git_annex_dropunused__34___.mdwn ./doc/bugs/git_rename_detection_on_file_move.mdwn ./doc/bugs/problem_commit_normal_links.mdwn ./doc/bugs/extraneous_shell_escaping_for_rsync_remotes.mdwn ./doc/bugs/problems_with_utf8_names/comment_1_3c7e3f021c2c94277eecf9c8af6cec5f._comment ./doc/bugs/problems_with_utf8_names/comment_7_0cc588f787d6eecfa19a8f6cee4b07b5._comment ./doc/bugs/problems_with_utf8_names/comment_8_ff5c6da9eadfee20c18c86b648a62c47._comment ./doc/bugs/problems_with_utf8_names/comment_4_93bee35f5fa7744834994bc7a253a6f9._comment ./doc/bugs/problems_with_utf8_names/comment_3_4f936a5d3f9c7df64c8a87e62b7fbfdc._comment ./doc/bugs/problems_with_utf8_names/comment_5_519cda534c7aea7f5ad5acd3f76e21fa._comment ./doc/bugs/problems_with_utf8_names/comment_6_52e0bfff2b177b6f92e226b25d2f3ff1._comment ./doc/bugs/problems_with_utf8_names/comment_2_bad4c4c5f54358d1bc0ab2adc713782a._comment ./doc/bugs/git_annex_unused_seems_to_check_for_current_path.mdwn ./doc/bugs/Makefile_is_missing_dependancies/comment_6_24119fc5d5963ce9dd669f7dcf006859._comment ./doc/bugs/Makefile_is_missing_dependancies/comment_3_c38b6f4abc9b9ad413c3b83ca04386c3._comment ./doc/bugs/Makefile_is_missing_dependancies/comment_8_a3555e3286cdc2bfeb9cde0ff727ba74._comment ./doc/bugs/Makefile_is_missing_dependancies/comment_2_416f12dbd0c2b841fac8164645b81df5._comment ./doc/bugs/Makefile_is_missing_dependancies/comment_5_0a1c52e2c96d19b9c3eb7e99b8c2434f._comment ./doc/bugs/Makefile_is_missing_dependancies/comment_7_96fd4725df4b54e670077a18d3ac4943._comment ./doc/bugs/Makefile_is_missing_dependancies/comment_1_5a3da5f79c8563c7a450aa29728abe7c._comment ./doc/bugs/Makefile_is_missing_dependancies/comment_4_cc13873175edf191047282700315beee._comment ./doc/bugs/Trouble_initializing_git_annex_on_NFS.mdwn ./doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems.mdwn ./doc/bugs/build_issue_with_latest_release_0.20110522-1-gde817ba.mdwn ./doc/bugs/weird_local_clone_confuses.mdwn ./doc/bugs/fsck_output.mdwn ./doc/bugs/git_annex_add_memory_leak.mdwn ./doc/bugs/git-annex_branch_push_race.mdwn ./doc/bugs/wishlist:_allow_users_to_provide_UUID_when_running___96__git_annex_init__96__.mdwn ./doc/bugs/git-annex_has_issues_with_git_when_staging__47__commiting_logs.mdwn ./doc/bugs/git_annex_gets_confused_about_remotes_with_dots_in_their_names.mdwn ./doc/bugs/unannex_vs_unlock_hook_confusion.mdwn ./doc/bugs/Cabal_dependency_monadIO_missing/comment_2_4f4d8e1e00a2a4f7e8a8ab082e16adac._comment ./doc/bugs/Cabal_dependency_monadIO_missing/comment_1_14be660aa57fadec0d81b32a8b52c66f._comment ./doc/bugs/conflicting_haskell_packages.mdwn ./doc/bugs/git_command_line_constructed_by_unannex_command_has_tons_of_redundant_-a_paramters.mdwn ./doc/bugs/backend_version_upgrade_leaves_repo_unusable.mdwn ./doc/bugs/fat_support/comment_3_df3b943bc1081a8f3f7434ae0c8e061e._comment ./doc/bugs/fat_support/comment_4_90a8a15bedd94480945a374f9d706b86._comment ./doc/bugs/fat_support/comment_5_64bbf89de0836673224b83fdefa0407b._comment ./doc/bugs/fat_support/comment_1_04bcc4795d431e8cb32293aab29bbfe2._comment ./doc/bugs/fat_support/comment_2_bb4a97ebadb5c53809fc78431eabd7c8._comment ./doc/bugs/unannex_command_doesn__39__t_all_files.mdwn ./doc/bugs/annex_unannex__47__uninit_should_handle_copies.mdwn ./doc/bugs/git-annex_branch_corruption.mdwn ./doc/bugs/git_annex_fsck_is_a_no-op_in_bare_repos.mdwn ./doc/bugs/show_version_without_having_to_be_in_a_git_repo.mdwn ./doc/bugs/Unfortunate_interaction_with_Calibre.mdwn ./doc/bugs/error_propigation.mdwn ./doc/bugs/wishlist:_support_drop__44___find_on_special_remotes.mdwn ./doc/bugs/scp_interrupt_to_background.mdwn ./doc/bugs/copy_fast_confusing_with_broken_locationlog.mdwn ./doc/bugs/uninit_does_not_work_in_old_repos/comment_1_bc0619c6e17139df74639448aa6a0f72._comment ./doc/bugs/git-annex_losing_rsync_remotes_with_encryption_enabled.mdwn ./doc/bugs/configure_script_should_detect_uuidgen_instead_of_just_uuid.mdwn ./doc/bugs/check_for_curl_in_configure.hs.mdwn ./doc/bugs/fails_to_handle_lot_of_files/comment_1_09d8e4e66d8273fab611bd29e82dc7fc._comment ./doc/bugs/fails_to_handle_lot_of_files/comment_2_fd2ec05f4b5a7a6ae6bd9f5dbc3156de._comment ./doc/bugs/Name_scheme_does_not_follow_git__39__s_rules.mdwn ./doc/bugs/concurrent_git-annex_processes_can_lead_to_locking_issues.mdwn ./doc/bugs/Prevent_accidental_merges.mdwn ./doc/bugs/building_on_lenny.mdwn ./doc/bugs/case_sensitivity_on_FAT.mdwn ./doc/bugs/encrypted_S3_stalls.mdwn ./doc/bugs/support_bare_git_repo__44___with_the_annex_directory_exposed_to_http.mdwn ./doc/bugs/WORM:_Handle_long_filenames_correctly.mdwn ./doc/logo_small.png ./doc/tips.mdwn ./doc/use_case/Bob.mdwn ./doc/use_case/Alice.mdwn ./doc/upgrades/SHA_size.mdwn ./doc/news/sharebox_a_FUSE_filesystem_for_git-annex.mdwn ./doc/news/version_3.20120229.mdwn ./doc/news/version_3.20120309.mdwn ./doc/news/version_3.20120315.mdwn ./doc/news/version_3.20120230/comment_2_899de1196cd1ba4a393e4ef574d7aa5e._comment ./doc/news/version_3.20120230/comment_1_b975cbd3a01ba5c2fa0f24fe739d3433._comment ./doc/news/Presentation_at_FOSDEM.mdwn ./doc/news/version_3.20120229/comment_5_7dbf131ff4611abbfc8fbf1ee0f66dbe._comment ./doc/news/version_3.20120229/comment_2_03436ddda42decf8cb1b4d5316d88a75._comment ./doc/news/version_3.20120229/comment_3_8f7f8d4758804f1b695925934219745a._comment ./doc/news/version_3.20120229/comment_4_cd90223f78571e5bdd3dfc07ab1369d7._comment ./doc/news/version_3.20120229/comment_1_18158b9be2313f49509d59295c7d3c90._comment ./doc/news/LWN_article.mdwn ./doc/news/version_3.20120230.mdwn ./doc/news/version_3.20120227/comment_2_ea5075cfecc50d5da2364931ef7a02d1._comment ./doc/news/version_3.20120227/comment_1_f8fc894680f2a2e5b5e757a677414b42._comment ./doc/news/version_3.20120106/comment_1_fb1a3135e2d9f39f2c372ccc2c50c85a._comment ./doc/news/version_3.20120106/comment_2_ae292ca7294b6790233e545086c3ac2f._comment ./doc/news/version_3.20120106/comment_3_29ccda9ac458fd5cc9ec5508c62df6ea._comment ./doc/git-union-merge.mdwn ./doc/special_remotes/S3.mdwn ./doc/special_remotes/web.mdwn ./doc/special_remotes/bup.mdwn ./doc/special_remotes/directory.mdwn ./doc/special_remotes/hook.mdwn ./doc/special_remotes/rsync.mdwn ./doc/how_it_works.mdwn ./doc/sitemap.mdwn ./doc/users/joey.mdwn ./doc/users/fmarier.mdwn ./doc/users/chrysn.mdwn ./doc/users/gebi.mdwn ./doc/templates/walkthrough.tmpl ./doc/templates/bugtemplate.mdwn ./doc/templates/bare.tmpl ./doc/index.mdwn ./doc/sync/comment_1_59681be5568f568f5c54eb0445163dd2._comment ./doc/summary.mdwn ./doc/forum.mdwn ./doc/encryption/comment_1_1afca8d7182075d46db41f6ad3dd5911._comment ./doc/transferring_data.mdwn ./doc/download.mdwn ./doc/future_proofing.mdwn ./doc/todo/redundancy_stats_in_status.mdwn ./doc/todo/auto_remotes/discussion.mdwn ./doc/todo/link_file_to_remote_repo_feature.mdwn ./doc/todo/file_copy_progress_bar.mdwn ./doc/todo/use_cp_reflink.mdwn ./doc/todo/gitrm.mdwn ./doc/todo/exclude_files_on_a_given_remote.mdwn ./doc/todo/git-annex_unused_eats_memory.mdwn ./doc/todo/Please_abort_build_if___34__make_test__34___fails.mdwn ./doc/todo/fsck_special_remotes.mdwn ./doc/todo/add_--exclude_option_to_git_annex_find.mdwn ./doc/todo/tahoe_lfs_for_reals/comment_2_80b9e848edfdc7be21baab7d0cef0e3a._comment ./doc/todo/tahoe_lfs_for_reals/comment_1_0a4793ce6a867638f6e510e71dd4bb44._comment ./doc/todo/object_dir_reorg_v2.mdwn ./doc/todo/S3.mdwn ./doc/todo/auto_remotes.mdwn ./doc/todo/wishlist:_support_for_more_ssh_urls_.mdwn ./doc/todo/support-non-utf8-locales.mdwn ./doc/todo/done.mdwn ./doc/todo/fsck.mdwn ./doc/todo/support_S3_multipart_uploads.mdwn ./doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates.mdwn ./doc/todo/pushpull.mdwn ./doc/todo/smudge.mdwn ./doc/todo/cache_key_info/comment_1_578df1b3b2cbfdc4aa1805378f35dc48._comment ./doc/todo/windows_support.mdwn ./doc/todo/optimise_git-annex_merge.mdwn ./doc/todo/object_dir_reorg_v2/comment_3_79bdf9c51dec9f52372ce95b53233bb2._comment ./doc/todo/object_dir_reorg_v2/comment_7_42501404c82ca07147e2cce0cff59474._comment ./doc/todo/object_dir_reorg_v2/comment_5_821c382987f105da72a50e0a5ce61fdc._comment ./doc/todo/object_dir_reorg_v2/comment_1_ba03333dc76ff49eccaba375e68cb525._comment ./doc/todo/object_dir_reorg_v2/comment_2_81276ac309959dc741bc90101c213ab7._comment ./doc/todo/object_dir_reorg_v2/comment_6_8834c3a3f1258c4349d23aff8549bf35._comment ./doc/todo/object_dir_reorg_v2/comment_4_93aada9b1680fed56cc6f0f7c3aca5e5._comment ./doc/todo/union_mounting.mdwn ./doc/todo/wishlist:_swift_backend.mdwn ./doc/todo/Please_add_support_for_monad-control_0.3.x.mdwn ./doc/todo/wishlist:_swift_backend/comment_1_e6efbb35f61ee521b473a92674036788._comment ./doc/todo/wishlist:_swift_backend/comment_2_5d8c83b0485112e98367b7abaab3f4e3._comment ./doc/todo/git_annex_init_:_include_repo_description_and__47__or_UUID_in_commit_message.mdwn ./doc/todo/gitolite_and_gitosis_support.mdwn ./doc/todo/wishlist:___34__git_annex_add__34___multiple_processes.mdwn ./doc/todo/hidden_files.mdwn ./doc/todo/smudge/comment_1_4ea616bcdbc9e9a6fae9f2e2795c31c9._comment ./doc/todo/smudge/comment_2_e04b32caa0d2b4c577cdaf382a3ff7f6._comment ./doc/todo/network_remotes.mdwn ./doc/todo/add_a_git_backend.mdwn ./doc/todo/parallel_possibilities/comment_1_d8e34fc2bc4e5cf761574608f970d496._comment ./doc/todo/parallel_possibilities/comment_2_adb76f06a7997abe4559d3169a3181c3._comment ./doc/todo/checkout.mdwn ./doc/todo/immutable_annexed_files.mdwn ./doc/todo/wishlist:_Prevent_repeated_password_prompts_for_one_command.mdwn ./doc/todo/git-annex-shell.mdwn ./doc/todo/speed_up_fsck.mdwn ./doc/todo/tahoe_lfs_for_reals.mdwn ./doc/todo/avoid_unnecessary_union_merges.mdwn ./doc/todo/support_fsck_in_bare_repos.mdwn ./doc/todo/add_-all_option.mdwn ./doc/todo/using_url_backend.mdwn ./doc/todo/branching.mdwn ./doc/todo/rsync.mdwn ./doc/todo/backendSHA1.mdwn ./doc/todo/cache_key_info.mdwn ./doc/todo/parallel_possibilities.mdwn ./doc/todo/symlink_farming_commit_hook.mdwn ./doc/feeds.mdwn ./doc/sync.mdwn ./doc/copies.mdwn ./doc/repomap.png ./doc/scalability.mdwn ./doc/special_remotes.mdwn ./doc/todo.mdwn ./doc/walkthrough/using_ssh_remotes.mdwn ./doc/walkthrough/automatically_managing_content.mdwn ./doc/walkthrough/removing_files/comment_1_cb65e7c510b75be1c51f655b058667c6._comment ./doc/walkthrough/removing_files/comment_2_64709ea4558915edd5c8ca4486965b07._comment ./doc/walkthrough/moving_file_content_between_repositories.mdwn ./doc/walkthrough/modifying_annexed_files.mdwn ./doc/walkthrough/more.mdwn ./doc/walkthrough/removing_files.mdwn ./doc/walkthrough/creating_a_repository.mdwn ./doc/walkthrough/adding_a_remote.mdwn ./doc/walkthrough/adding_a_remote/comment_1_0a59355bd33a796aec97173607e6adc9._comment ./doc/walkthrough/adding_a_remote/comment_2_f8cd79ef1593a8181a7f1086a87713e8._comment ./doc/walkthrough/adding_a_remote/comment_3_60691af4400521b5a8c8d75efe3b44cb._comment ./doc/walkthrough/adding_a_remote/comment_4_6f7cf5c330272c96b3abeb6612075c9d._comment ./doc/walkthrough/removing_files:_When_things_go_wrong.mdwn ./doc/walkthrough/renaming_files.mdwn ./doc/walkthrough/using_bup.mdwn ./doc/walkthrough/fsck:_when_things_go_wrong.mdwn ./doc/walkthrough/syncing.mdwn ./doc/walkthrough/adding_files.mdwn ./doc/walkthrough/unused_data.mdwn ./doc/walkthrough/fsck:_verifying_your_data.mdwn ./doc/walkthrough/getting_file_content.mdwn ./doc/walkthrough/backups.mdwn ./doc/walkthrough/transferring_files:_When_things_go_wrong.mdwn ./doc/GPL ./doc/logo.png ./doc/location_tracking.mdwn ./doc/design.mdwn ./doc/news.mdwn ./doc/tips/visualizing_repositories_with_gource/screenshot.jpg ./doc/tips/untrusted_repositories.mdwn ./doc/tips/using_box.com_as_a_special_remote.mdwn ./doc/tips/automatically_getting_files_on_checkout.mdwn ./doc/tips/what_to_do_when_a_repository_is_corrupted.mdwn ./doc/tips/Internet_Archive_via_S3.mdwn ./doc/tips/what_to_do_when_you_lose_a_repository.mdwn ./doc/tips/using_Amazon_S3.mdwn ./doc/tips/using_the_web_as_a_special_remote.mdwn ./doc/tips/assume-unstaged.mdwn ./doc/tips/powerful_file_matching.mdwn ./doc/tips/using_gitolite_with_git-annex.mdwn ./doc/tips/recover_data_from_lost+found.mdwn ./doc/tips/visualizing_repositories_with_gource.mdwn ./doc/tips/centralized_git_repository_tutorial.mdwn ./doc/tips/finding_duplicate_files/comment_1_ddb477ca242ffeb21e0df394d8fdf5d2._comment ./doc/tips/using_git_annex_with_no_fixed_hostname_and_optimising_ssh.mdwn ./doc/tips/using_gitolite_with_git-annex/comment_4_eb81f824aadc97f098379c5f7e4fba4c._comment ./doc/tips/using_gitolite_with_git-annex/comment_6_3e203e010a4df5bf03899f867718adc5._comment ./doc/tips/using_gitolite_with_git-annex/comment_1_9a2a2a8eac9af97e0c984ad105763a73._comment ./doc/tips/using_gitolite_with_git-annex/comment_8_8249772c142117f88e37975d058aa936._comment ./doc/tips/using_gitolite_with_git-annex/comment_5_f688309532d2993630e9e72e87fb9c46._comment ./doc/tips/using_gitolite_with_git-annex/comment_7_f8fd08b6ab47378ad88c87348057220d._comment ./doc/tips/using_gitolite_with_git-annex/comment_3_807035f38509ccb9f93f1929ecd37417._comment ./doc/tips/using_gitolite_with_git-annex/comment_9_28418635a6ed7231b89e02211cd3c236._comment ./doc/tips/using_gitolite_with_git-annex/comment_2_d8efea4ab9576555fadbb47666ecefa9._comment ./doc/tips/finding_duplicate_files.mdwn ./doc/tips/centralised_repository:_starting_from_nothing.mdwn ./doc/tips/using_the_SHA1_backend.mdwn ./doc/tips/migrating_data_to_a_new_backend.mdwn ./doc/encryption.mdwn ./doc/not.mdwn ./doc/download/comment_7_a5eebd214b135f34b18274a682211943._comment ./doc/download/comment_3_cf6044ebe99f71158034e21197228abd._comment ./doc/download/comment_5_c6b1bc40226fc2c8ba3e558150856992._comment ./doc/download/comment_6_3a52993d3553deb9a413debec9a5f92d._comment ./doc/download/comment_2_f85f72b33aedc3425f0c0c47867d02f3._comment ./doc/download/comment_8_59a976de6c7d333709b92f7cd5830850._comment ./doc/download/comment_4_10fc013865c7542c2ed9d6c0963bb391._comment ./doc/download/comment_1_fbd8b6d39e9d3c71791551358c863966._comment ./doc/contact.mdwn ./doc/trust.mdwn ./doc/bare_repositories.mdwn ./doc/NixOS.mdwn ./doc/distributed_version_control.mdwn ./doc/install.mdwn ./doc/git-annex-shell.mdwn ./doc/bugs.mdwn ./doc/meta.mdwn ./doc/design/encryption/comment_2_a610b3d056a059899178859a3a821ea5._comment ./doc/design/encryption/comment_3_cca186a9536cd3f6e86994631b14231c._comment ./doc/design/encryption/comment_1_4715ffafb3c4a9915bc33f2b26aaa9c1._comment ./doc/design/encryption/comment_4_8f3ba3e504b058791fc6e6f9c38154cf._comment ./doc/design/encryption.mdwn ./doc/comments.mdwn ./doc/git-annex.mdwn ./doc/internals.mdwn ./doc/users.mdwn ./doc/install/Ubuntu.mdwn ./doc/install/Debian.mdwn ./doc/install/openSUSE.mdwn ./doc/install/OSX.mdwn ./doc/install/FreeBSD.mdwn ./doc/install/OSX/comment_1_0a1760bf0db1f1ba89bdb4c62032f631._comment ./doc/install/ArchLinux.mdwn ./doc/install/Debian/comment_2_648e3467e260cdf233acdb0b53313ce0._comment ./doc/install/Debian/comment_1_029486088d098c2d4f1099f2f0e701a9._comment ./doc/install/Fedora.mdwn ./doc/walkthrough.mdwn ./CmdLine.hs ./Messages.hs ./Setup.hs ./GPL ./mdwn2man ./Remote.hs ./git-annex.hs ./Locations.hs ./Usage.hs ./Backend/WORM.hs ./Backend/URL.hs ./Backend/SHA.hs ./git-annex-shell.hs ./test.hs ./INSTALL ./Remote/Web.hs ./Remote/Helper/Encryptable.hs ./Remote/Helper/Ssh.hs ./Remote/Helper/Special.hs ./Remote/Helper/Hooks.hs ./Remote/Directory.hs ./Remote/List.hs ./Remote/Bup.hs ./Remote/Hook.hs ./Remote/S3.hs ./Remote/Rsync.hs ./Remote/Git.hs ./Build/TestConfig.hs ./Build/Configure.hs ./Upgrade.hs ./Annex/Version.hs ./Annex/Exception.hs ./Annex/Journal.hs ./Annex/CatFile.hs ./Annex/Ssh.hs ./Annex/Queue.hs ./Annex/Branch.hs ./Annex/UUID.hs ./Annex/LockPool.hs ./Annex/BranchState.hs ./Annex/CheckAttr.hs ./Annex/Content.hs ./git-union-merge.hs ./Utility/Path.hs ./Utility/Matcher.hs ./Utility/TempFile.hs ./Utility/State.hs ./Utility/Url.hs ./Utility/DataUnits.hs ./Utility/StatFS.hsc ./Utility/CoProcess.hs ./Utility/Exception.hs ./Utility/Monad.hs ./Utility/RsyncFile.hs ./Utility/CopyFile.hs ./Utility/Misc.hs ./Utility/SafeCommand.hs ./Utility/Gpg.hs ./Utility/Directory.hs ./Utility/FileSystemEncoding.hs ./Utility/FileMode.hs ./Utility/PartialPrelude.hs ./Utility/JSONStream.hs ./Utility/Dot.hs ./Utility/Touch.hsc ./Utility/Base64.hs ./Utility/Format.hs ./Types/Option.hs ./Types/Crypto.hs ./Types/UUID.hs ./Types/TrustLevel.hs ./Types/Remote.hs ./Types/BranchState.hs ./Types/Command.hs ./Types/Backend.hs ./Types/Key.hs ./Config.hs ./Checks.hs ./Command.hs ./.gitignore ./Backend.hs ./Logs/Web.hs ./Logs/UUIDBased.hs ./Logs/Trust.hs ./Logs/Location.hs ./Logs/UUID.hs ./Logs/Remote.hs ./Logs/Presence.hs ./.gitattributes ./Git.hs ./Limit.hs ./GitAnnex.hs Homepage: http://git-annex.branchable.com/ Build-type: Custom Category: Utility@@ -31,15 +31,13 @@   Build-Depends: MissingH, hslogger, directory, filepath,    unix, containers, utf8-string, network, mtl, bytestring, old-locale, time,    pcre-light, extensible-exceptions, dataenc, SHA, process, hS3, json, HTTP,-   base >= 4.5, base < 5, monad-control, transformers-base, lifted-base, IfElse,-   QuickCheck >= 2.1+   base >= 4.5, base < 5, monad-control, transformers-base, lifted-base,+   IfElse, text, QuickCheck >= 2.1, bloomfilter+  Other-Modules: Utility.StatFS, Utility.Touch  Executable git-annex-shell   Main-Is: git-annex-shell.hs--Executable git-union-merge-  Main-Is: git-union-merge.hs-  Build-Depends: text+  Other-Modules: Utility.StatFS  source-repository head   type: git
git-annex.hs view
@@ -1,13 +1,21 @@ {- git-annex main program stub  -- - Copyright 2010 Joey Hess <joey@kitenet.net>+ - Copyright 2010,2012 Joey Hess <joey@kitenet.net>  -  - Licensed under the GNU GPL version 3 or higher.  -}  import System.Environment+import System.FilePath -import GitAnnex+import qualified GitAnnex+import qualified GitAnnexShell  main :: IO ()-main = run =<< getArgs+main = run =<< getProgName+	where+		run n+			| isshell n = go GitAnnexShell.run+			| otherwise = go GitAnnex.run+		isshell n = takeFileName n == "git-annex-shell"+		go a = a =<< getArgs