initial support for annexobjects=yes
Works but some commands may need changes to support special remotes configured this way.
This commit is contained in:
		
					parent
					
						
							
								169fd414eb
							
						
					
				
			
			
				commit
				
					
						28b29f63dc
					
				
			
		
					 14 changed files with 163 additions and 41 deletions
				
			
		| 
						 | 
				
			
			@ -27,6 +27,7 @@ module Annex.Locations (
 | 
			
		|||
	gitAnnexInodeSentinalCache,
 | 
			
		||||
	annexLocationsBare,
 | 
			
		||||
	annexLocationsNonBare,
 | 
			
		||||
	annexLocation,
 | 
			
		||||
	gitAnnexDir,
 | 
			
		||||
	gitAnnexObjectDir,
 | 
			
		||||
	gitAnnexTmpOtherDir,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -100,6 +100,12 @@ exportTree = fromMaybe False . getRemoteConfigValue exportTreeField
 | 
			
		|||
importTree :: ParsedRemoteConfig -> Bool
 | 
			
		||||
importTree = fromMaybe False . getRemoteConfigValue importTreeField
 | 
			
		||||
 | 
			
		||||
annexObjectsField :: RemoteConfigField
 | 
			
		||||
annexObjectsField = Accepted "annexobjects"
 | 
			
		||||
 | 
			
		||||
annexObjects :: ParsedRemoteConfig -> Bool
 | 
			
		||||
annexObjects = fromMaybe False . getRemoteConfigValue annexObjectsField
 | 
			
		||||
 | 
			
		||||
{- Parsers for fields that are common to all special remotes. -}
 | 
			
		||||
commonFieldParsers :: [RemoteConfigFieldParser]
 | 
			
		||||
commonFieldParsers =
 | 
			
		||||
| 
						 | 
				
			
			@ -124,6 +130,8 @@ essentialFieldParsers =
 | 
			
		|||
		(FieldDesc "export trees of files to this remote")
 | 
			
		||||
	, yesNoParser importTreeField (Just False)
 | 
			
		||||
		(FieldDesc "import trees of files from this remote")
 | 
			
		||||
	, yesNoParser annexObjectsField (Just False)
 | 
			
		||||
		(FieldDesc "store other objects in remote along with exported trees")
 | 
			
		||||
	]
 | 
			
		||||
 | 
			
		||||
autoEnableFieldParser :: RemoteConfigFieldParser
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,10 @@
 | 
			
		|||
git-annex (10.20240732) UNRELEASED; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * Avoid loading cluster log at startup.
 | 
			
		||||
  * Remotes configured with exporttree=yes annexobjects=yes 
 | 
			
		||||
    can store objects in .git/annex/objects, as well as an exported tree.
 | 
			
		||||
  * git-remote-annex: Store objects in exportree=yes special remotes
 | 
			
		||||
    in the same paths used by annexobjects=yes.
 | 
			
		||||
 | 
			
		||||
 -- Joey Hess <id@joeyh.name>  Wed, 31 Jul 2024 15:52:03 -0400
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,30 +1,35 @@
 | 
			
		|||
{- Helper to make remotes support export and import (or not).
 | 
			
		||||
 -
 | 
			
		||||
 - Copyright 2017-2019 Joey Hess <id@joeyh.name>
 | 
			
		||||
 - Copyright 2017-2024 Joey Hess <id@joeyh.name>
 | 
			
		||||
 -
 | 
			
		||||
 - Licensed under the GNU AGPL version 3 or higher.
 | 
			
		||||
 -}
 | 
			
		||||
 | 
			
		||||
{-# LANGUAGE FlexibleInstances, FlexibleContexts #-}
 | 
			
		||||
{-# LANGUAGE OverloadedStrings #-}
 | 
			
		||||
 | 
			
		||||
module Remote.Helper.ExportImport where
 | 
			
		||||
 | 
			
		||||
import Annex.Common
 | 
			
		||||
import qualified Annex
 | 
			
		||||
import Types.Remote
 | 
			
		||||
import Types.Key
 | 
			
		||||
import Types.ProposedAccepted
 | 
			
		||||
import Annex.Verify
 | 
			
		||||
import Types.Export
 | 
			
		||||
import Remote.Helper.Encryptable (encryptionIsEnabled)
 | 
			
		||||
import qualified Database.Export as Export
 | 
			
		||||
import qualified Database.ContentIdentifier as ContentIdentifier
 | 
			
		||||
import Annex.Export
 | 
			
		||||
import Annex.LockFile
 | 
			
		||||
import Annex.SpecialRemote.Config
 | 
			
		||||
import Annex.Verify
 | 
			
		||||
import Annex.Content
 | 
			
		||||
import Git.Types (fromRef)
 | 
			
		||||
import Logs.Export
 | 
			
		||||
import Logs.ContentIdentifier (recordContentIdentifier)
 | 
			
		||||
 | 
			
		||||
import Control.Concurrent.STM
 | 
			
		||||
import qualified System.FilePath.ByteString as P
 | 
			
		||||
 | 
			
		||||
-- | Use for remotes that do not support exports.
 | 
			
		||||
class HasExportUnsupported a where
 | 
			
		||||
| 
						 | 
				
			
			@ -123,12 +128,15 @@ adjustExportImport r rs = do
 | 
			
		|||
				else importUnsupported
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	let annexobjects = isexport && annexObjects (config r)
 | 
			
		||||
	if not isexport && not isimport
 | 
			
		||||
		then return r'
 | 
			
		||||
		else adjustExportImport' isexport isimport r' rs
 | 
			
		||||
		else do
 | 
			
		||||
			gc <- Annex.getGitConfig
 | 
			
		||||
			adjustExportImport' isexport isimport annexobjects r' rs gc
 | 
			
		||||
 | 
			
		||||
adjustExportImport' :: Bool -> Bool -> Remote -> RemoteStateHandle -> Annex Remote
 | 
			
		||||
adjustExportImport' isexport isimport r rs = do
 | 
			
		||||
adjustExportImport' :: Bool -> Bool -> Bool -> Remote -> RemoteStateHandle -> GitConfig -> Annex Remote
 | 
			
		||||
adjustExportImport' isexport isimport annexobjects r rs gc = do
 | 
			
		||||
	dbv <- prepdbv
 | 
			
		||||
	ciddbv <- prepciddb
 | 
			
		||||
	let versioned = versionedExport (exportActions r)
 | 
			
		||||
| 
						 | 
				
			
			@ -141,42 +149,48 @@ adjustExportImport' isexport isimport r rs = do
 | 
			
		|||
		, importActions = if isimport
 | 
			
		||||
			then importActions r
 | 
			
		||||
			else importUnsupported
 | 
			
		||||
		, storeKey = \k af p ->
 | 
			
		||||
			-- Storing a key on an export could be implemented,
 | 
			
		||||
			-- but it would perform unnecessary work
 | 
			
		||||
		, storeKey = \k af o p ->
 | 
			
		||||
			-- Storing a key to an export location could be
 | 
			
		||||
			-- implemented, but it would perform unnecessary work
 | 
			
		||||
			-- when another repository has already stored the
 | 
			
		||||
			-- key, and the local repository does not know
 | 
			
		||||
			-- about it. To avoid unnecessary costs, don't do it.
 | 
			
		||||
			if thirdpartypopulated
 | 
			
		||||
				then giveup "remote is not populated by git-annex"
 | 
			
		||||
				else if isexport
 | 
			
		||||
					then giveup "remote is configured with exporttree=yes; use `git-annex export` to store content on it"
 | 
			
		||||
					then if annexobjects
 | 
			
		||||
						then storeannexobject k o p
 | 
			
		||||
						else giveup "remote is configured with exporttree=yes; use `git-annex export` to store content on it"
 | 
			
		||||
					else if isimport
 | 
			
		||||
						then giveup "remote is configured with importtree=yes and without exporttree=yes; cannot modify content stored on it"
 | 
			
		||||
						else storeKey r k af p
 | 
			
		||||
		, removeKey = \k -> 
 | 
			
		||||
			-- Removing a key from an export would need to
 | 
			
		||||
			-- change the tree in the export log to not include
 | 
			
		||||
						else storeKey r k af o p
 | 
			
		||||
		, removeKey = \proof k -> 
 | 
			
		||||
			-- Removing a key from an export location would need
 | 
			
		||||
			-- to change the tree in the export log to not include
 | 
			
		||||
			-- the file. Otherwise, conflicts when removing
 | 
			
		||||
			-- files would not be dealt with correctly.
 | 
			
		||||
			-- There does not seem to be a good use case for
 | 
			
		||||
			-- removing a key from an export in any case.
 | 
			
		||||
			-- removing a key from an exported tree in any case.
 | 
			
		||||
			if thirdpartypopulated
 | 
			
		||||
				then giveup "dropping content from this remote is not supported"
 | 
			
		||||
				else if isexport
 | 
			
		||||
					then giveup "dropping content from an export is not supported; use `git annex export` to export a tree that lacks the files you want to remove"
 | 
			
		||||
					then if annexobjects
 | 
			
		||||
						then removeannexobject k
 | 
			
		||||
						else giveup "dropping content from an export is not supported; use `git annex export` to export a tree that lacks the files you want to remove"
 | 
			
		||||
					else if isimport
 | 
			
		||||
						then giveup "dropping content from this remote is not supported because it is configured with importtree=yes"
 | 
			
		||||
						else removeKey r k
 | 
			
		||||
						else removeKey r proof k
 | 
			
		||||
		, lockContent = if versioned
 | 
			
		||||
			then lockContent r
 | 
			
		||||
			else Nothing
 | 
			
		||||
		, retrieveKeyFile = \k af dest p vc ->
 | 
			
		||||
			if isimport
 | 
			
		||||
				then supportversionedretrieve k af dest p vc $
 | 
			
		||||
					supportretrieveannexobject dbv k dest p $
 | 
			
		||||
						retrieveKeyFileFromImport dbv ciddbv k af dest p
 | 
			
		||||
				else if isexport
 | 
			
		||||
					then supportversionedretrieve k af dest p vc $
 | 
			
		||||
						supportretrieveannexobject dbv k dest p $
 | 
			
		||||
							retrieveKeyFileFromExport dbv k af dest p
 | 
			
		||||
					else retrieveKeyFile r k af dest p vc
 | 
			
		||||
		, retrieveKeyFileCheap = if versioned
 | 
			
		||||
| 
						 | 
				
			
			@ -185,7 +199,8 @@ adjustExportImport' isexport isimport r rs = do
 | 
			
		|||
		, checkPresent = \k -> if versioned
 | 
			
		||||
			then checkPresent r k
 | 
			
		||||
			else if isimport
 | 
			
		||||
				then anyM (checkPresentImport ciddbv k)
 | 
			
		||||
				then checkpresentwith k $
 | 
			
		||||
					anyM (checkPresentImport ciddbv k)
 | 
			
		||||
						=<< getanyexportlocs dbv k
 | 
			
		||||
				else if isexport
 | 
			
		||||
					-- Check if any of the files a key
 | 
			
		||||
| 
						 | 
				
			
			@ -197,7 +212,8 @@ adjustExportImport' isexport isimport r rs = do
 | 
			
		|||
					-- to it. Remotes that have such 
 | 
			
		||||
					-- problems are made untrusted,
 | 
			
		||||
					-- so it's not worried about here.
 | 
			
		||||
					then anyM (checkPresentExport (exportActions r) k)
 | 
			
		||||
					then checkpresentwith k $
 | 
			
		||||
						anyM (checkPresentExport (exportActions r) k)
 | 
			
		||||
							=<< getanyexportlocs dbv k
 | 
			
		||||
					else checkPresent r k
 | 
			
		||||
		-- checkPresent from an export is more expensive
 | 
			
		||||
| 
						 | 
				
			
			@ -226,7 +242,13 @@ adjustExportImport' isexport isimport r rs = do
 | 
			
		|||
				then do
 | 
			
		||||
					ts <- map fromRef . exportedTreeishes
 | 
			
		||||
						<$> getExport (uuid r)
 | 
			
		||||
					return (is++[("exporttree", "yes"), ("exportedtree", unwords ts)])
 | 
			
		||||
					return $ is ++ catMaybes
 | 
			
		||||
						[ Just ("exporttree", "yes")
 | 
			
		||||
						, Just ("exportedtree", unwords ts)
 | 
			
		||||
						, if annexobjects
 | 
			
		||||
							then Just ("annexobjects", "yes")
 | 
			
		||||
							else Nothing
 | 
			
		||||
						]
 | 
			
		||||
				else return is
 | 
			
		||||
			return $ if isimport && not thirdpartypopulated
 | 
			
		||||
				then (is'++[("importtree", "yes")])
 | 
			
		||||
| 
						 | 
				
			
			@ -313,7 +335,7 @@ adjustExportImport' isexport isimport r rs = do
 | 
			
		|||
				, liftIO $ atomically (readTMVar dbv)
 | 
			
		||||
				)
 | 
			
		||||
 | 
			
		||||
	getexportinconflict (_, _, v) = v
 | 
			
		||||
	isexportinconflict (_, _, v) = liftIO $ atomically $ readTVar v
 | 
			
		||||
 | 
			
		||||
	updateexportdb db exportinconflict =
 | 
			
		||||
		Export.updateExportTreeFromLog db >>= \case
 | 
			
		||||
| 
						 | 
				
			
			@ -329,8 +351,8 @@ adjustExportImport' isexport isimport r rs = do
 | 
			
		|||
	
 | 
			
		||||
	getexportlocs dbv k = do
 | 
			
		||||
		db <- getexportdb dbv
 | 
			
		||||
		liftIO $ Export.getExportTree db k >>= \case
 | 
			
		||||
			[] -> ifM (atomically $ readTVar $ getexportinconflict dbv)
 | 
			
		||||
		liftIO (Export.getExportTree db k) >>= \case
 | 
			
		||||
			[] -> ifM (isexportinconflict dbv)
 | 
			
		||||
				( giveup "unknown export location, likely due to the export conflict"
 | 
			
		||||
				, return []
 | 
			
		||||
				)
 | 
			
		||||
| 
						 | 
				
			
			@ -373,17 +395,70 @@ adjustExportImport' isexport isimport r rs = do
 | 
			
		|||
				then retrieveKeyFileFromExport dbv k af dest p
 | 
			
		||||
				else giveup "no content identifier is recorded, unable to retrieve"
 | 
			
		||||
 | 
			
		||||
	-- versionedExport remotes have a key/value store, so can use
 | 
			
		||||
	-- the usual retrieveKeyFile, rather than an import/export
 | 
			
		||||
	-- variant. However, fall back to that if retrieveKeyFile fails.
 | 
			
		||||
	supportversionedretrieve k af dest p vc a
 | 
			
		||||
		| versionedExport (exportActions r) =
 | 
			
		||||
			retrieveKeyFile r k af dest p vc
 | 
			
		||||
				`catchNonAsync` const a
 | 
			
		||||
		| otherwise = a
 | 
			
		||||
	checkpresentwith k a = ifM a
 | 
			
		||||
		( return True
 | 
			
		||||
		, if annexobjects
 | 
			
		||||
			then checkpresentannexobject k
 | 
			
		||||
			else return False
 | 
			
		||||
		)
 | 
			
		||||
 | 
			
		||||
	checkPresentImport ciddbv k loc =
 | 
			
		||||
		checkPresentExportWithContentIdentifier
 | 
			
		||||
			(importActions r)
 | 
			
		||||
			k loc 
 | 
			
		||||
			=<< getkeycids ciddbv k
 | 
			
		||||
 | 
			
		||||
	-- For annexobjects=true, objects are stored in the remote
 | 
			
		||||
	-- in a location under .git/objects/
 | 
			
		||||
	annexobjectlocation k = mkExportLocation $
 | 
			
		||||
		".git" P.</> annexLocation gc k hashDirLower
 | 
			
		||||
 | 
			
		||||
	checkpresentannexobject k = 
 | 
			
		||||
		checkPresentExport (exportActions r) k (annexobjectlocation k)
 | 
			
		||||
 | 
			
		||||
	storeannexobject k o p = prepSendAnnex' k o >>= \case
 | 
			
		||||
		Nothing -> giveup "content is not available"
 | 
			
		||||
		Just (src, _, checkmodified) -> do
 | 
			
		||||
			let loc = annexobjectlocation k
 | 
			
		||||
			storeExport (exportActions r) src k loc p
 | 
			
		||||
			checkmodified >>= \case
 | 
			
		||||
				Nothing -> return ()
 | 
			
		||||
				Just err -> do
 | 
			
		||||
					removeExport (exportActions r) k loc
 | 
			
		||||
					giveup err
 | 
			
		||||
 | 
			
		||||
	removeannexobject k = 
 | 
			
		||||
		removeExport (exportActions r) k (annexobjectlocation k)
 | 
			
		||||
 | 
			
		||||
	retrieveannexobject k dest p =
 | 
			
		||||
		retrieveExport (exportActions r) k (annexobjectlocation k) dest p
 | 
			
		||||
 | 
			
		||||
	supportretrieveannexobject dbv k dest p a
 | 
			
		||||
		| annexobjects = tryNonAsync a >>= \case
 | 
			
		||||
			Right res -> return res
 | 
			
		||||
			Left err -> tryNonAsync (retrieveannexobject k dest p) >>= \case
 | 
			
		||||
				Right res -> return res
 | 
			
		||||
				-- Both failed, so which exception to
 | 
			
		||||
				-- throw? If there are known export
 | 
			
		||||
				-- locations, throw the exception from
 | 
			
		||||
				-- retrieving from the export locations.
 | 
			
		||||
				-- If there are no known export locations,
 | 
			
		||||
				-- throw the exception from retrieving from
 | 
			
		||||
				-- the annexobjects location.
 | 
			
		||||
				Left err' -> getanyexportlocs dbv k >>= \case
 | 
			
		||||
					[] -> ifM (isexportinconflict dbv)
 | 
			
		||||
						( throwM err
 | 
			
		||||
						, throwM err'
 | 
			
		||||
						)
 | 
			
		||||
					_ -> throwM err
 | 
			
		||||
		| otherwise = a
 | 
			
		||||
 | 
			
		||||
	-- versionedExport remotes have a key/value store which
 | 
			
		||||
	-- the usual retrieveKeyFile can be used with, rather than
 | 
			
		||||
	-- an import/export variant. However, fall back to that
 | 
			
		||||
	-- if retrieveKeyFile fails.
 | 
			
		||||
	supportversionedretrieve k af dest p vc a
 | 
			
		||||
		| versionedExport (exportActions r) =
 | 
			
		||||
			retrieveKeyFile r k af dest p vc
 | 
			
		||||
				`catchNonAsync` const a
 | 
			
		||||
		| otherwise = a
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,8 +14,7 @@ Normally files are stored on a git-annex special remote named by their
 | 
			
		|||
keys. That is great for reliable data storage, but your filenames are
 | 
			
		||||
obscured. Exporting replicates the tree to the special remote as-is.
 | 
			
		||||
 | 
			
		||||
Mixing key/value storage and exports in the same remote would be a mess and
 | 
			
		||||
so is not allowed. You have to configure a special remote with
 | 
			
		||||
To use this, you have to configure a special remote with
 | 
			
		||||
`exporttree=yes` when initially setting it up with
 | 
			
		||||
[[git-annex-initremote]](1).
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -92,8 +92,8 @@ See [[git-annex-preferred-content]](1).
 | 
			
		|||
 | 
			
		||||
  This option can be repeated multiple times with different paths.
 | 
			
		||||
 | 
			
		||||
  Note that this option is ignored when syncing with "exporttree=yes"
 | 
			
		||||
  remotes.
 | 
			
		||||
  Note that this option does not prevent exporting other files to an 
 | 
			
		||||
  "exporttree=yes" remote.
 | 
			
		||||
 | 
			
		||||
* `--all` `-A`
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,8 +37,8 @@ do so by using eg `approxlackingcopies=1`.
 | 
			
		|||
 | 
			
		||||
  This option can be repeated multiple times with different paths.
 | 
			
		||||
 | 
			
		||||
  Note that this option is ignored when syncing with "exporttree=yes"
 | 
			
		||||
  remotes.
 | 
			
		||||
  Note that this option does not prevent exporting other files to an 
 | 
			
		||||
  "exporttree=yes" remote.
 | 
			
		||||
 | 
			
		||||
* `--jobs=N` `-JN`
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -125,6 +125,11 @@ the S3 remote.
 | 
			
		|||
  When versioning is not enabled, this risks data loss, and so git-annex
 | 
			
		||||
  will not let you enable a remote with that configuration unless forced.
 | 
			
		||||
 | 
			
		||||
* `annexobjects` - When set to "yes" along with "exporttree=yes",
 | 
			
		||||
  this allows storing other objects in the remote along with the
 | 
			
		||||
  exported tree. They will be stored under .git/annex/objects/ in the
 | 
			
		||||
  remote.
 | 
			
		||||
 | 
			
		||||
* `publicurl` - Configure the URL that is used to download files
 | 
			
		||||
  from the bucket. Using this with a S3 bucket that has been configured
 | 
			
		||||
  to allow anyone to download its content allows git-annex to download
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,6 +32,11 @@ the adb remote.
 | 
			
		|||
  by [[git-annex-import]]. When set in combination with exporttree,
 | 
			
		||||
  this lets files be imported from it, and changes exported back to it.
 | 
			
		||||
 | 
			
		||||
* `annexobjects` - When set to "yes" along with "exporttree=yes",
 | 
			
		||||
  this allows storing other objects in the remote along with the
 | 
			
		||||
  exported tree. They will be stored under .git/annex/objects/ in the
 | 
			
		||||
  remote.
 | 
			
		||||
 | 
			
		||||
* `oldandroid` - Set to "yes" if your Android device is too old
 | 
			
		||||
  to support `find -printf`. Enabling this will make importing slower.
 | 
			
		||||
  If you see an error like "bad arg '-printf'", you can enable this
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,6 +41,11 @@ remote:
 | 
			
		|||
  by [[git-annex-import]]. It will not be usable as a general-purpose
 | 
			
		||||
  special remote.
 | 
			
		||||
 | 
			
		||||
* `annexobjects` - When set to "yes" along with "exporttree=yes",
 | 
			
		||||
  this allows storing other objects in the remote along with the
 | 
			
		||||
  exported tree. They will be stored under .git/annex/objects/ in the
 | 
			
		||||
  directory.
 | 
			
		||||
 | 
			
		||||
* `ignoreinodes` - Usually when importing, the inode numbers
 | 
			
		||||
  of files are used to detect when files have changed. Since some
 | 
			
		||||
  filesystems generate new inode numbers each time they are mounted,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,6 +32,9 @@ for a list of known working combinations.
 | 
			
		|||
  Setting this does not allow trees to be exported to the httpalso remote,
 | 
			
		||||
  because it's read-only. But it does let exported files be downloaded
 | 
			
		||||
  from it.
 | 
			
		||||
* `annexobjects` - If the other special remote has `annexobjects=yes`
 | 
			
		||||
  set (along with `exporttree=yes`), it also needs to be set when
 | 
			
		||||
  initializing the httpalso remote.
 | 
			
		||||
 | 
			
		||||
Configuration of encryption and chunking is inherited from the other
 | 
			
		||||
special remote, and does not need to be specified when initializing the
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,6 +26,11 @@ These parameters can be passed to `git annex initremote` to configure rsync:
 | 
			
		|||
  by [[git-annex-export]]. It will not be usable as a general-purpose
 | 
			
		||||
  special remote.
 | 
			
		||||
 | 
			
		||||
* `annexobjects` - When set to "yes" along with "exporttree=yes",
 | 
			
		||||
  this allows storing other objects in the remote along with the
 | 
			
		||||
  exported tree. They will be stored under .git/annex/objects/ in the
 | 
			
		||||
  remote.
 | 
			
		||||
 | 
			
		||||
* `shellescape` - Optional. This has no effect when using rsync 3.2.4 or
 | 
			
		||||
  newer. Set to "no" to avoid shell escaping
 | 
			
		||||
  normally done when using older versions of rsync over ssh. That escaping
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,6 +33,11 @@ the webdav remote.
 | 
			
		|||
  by [[git-annex-export]]. It will not be usable as a general-purpose
 | 
			
		||||
  special remote.
 | 
			
		||||
 | 
			
		||||
* `annexobjects` - When set to "yes" along with "exporttree=yes",
 | 
			
		||||
  this allows storing other objects in the remote along with the
 | 
			
		||||
  exported tree. They will be stored under .git/annex/objects/ in the
 | 
			
		||||
  remote.
 | 
			
		||||
 | 
			
		||||
* `chunk` - Enables [[chunking]] when storing large files.
 | 
			
		||||
 | 
			
		||||
* `chunksize` - Deprecated version of chunk parameter above.  
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,6 +52,13 @@ surprising for an existing user!
 | 
			
		|||
 | 
			
		||||
Perhaps this should not be "exportree=yes", but something else.
 | 
			
		||||
 | 
			
		||||
> Currently, if a remote is configured with "exporttree=foo", that
 | 
			
		||||
> is treated the same as "exporttree=no". So this will need to be
 | 
			
		||||
> a config added to exporttree=yes in order to interoperate
 | 
			
		||||
> with old git-annex.
 | 
			
		||||
> 
 | 
			
		||||
> Call it "exporttree=yes annexobjects=yes" --[[Joey]]
 | 
			
		||||
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
Consider two repositories A and B that both have access to the same
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue