Automatically convert direct mode repositories to v7 with adjusted unlocked branches

* Automatically convert direct mode repositories to v7 with adjusted
  unlocked branches and set annex.thin.
* init: When run on a crippled filesystem with --version=5,
  will error out, since version 7 is needed for adjusted unlocked branch.
* direct: This command always errors out as direct mode is no longer
  supported.
* indirect: This command has become a deprecated noop.
* proxy: This command is deprecated because it was only needed in direct
  mode. (But it continues to work.)

Also removed mentions of direct mode throughough the documentation.

I have not removed all the direct mode code yet.
This commit is contained in:
Joey Hess 2019-08-26 14:52:55 -04:00
parent f6fb4b8cdb
commit 20741b1eb4
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
27 changed files with 98 additions and 484 deletions

View file

@ -22,7 +22,6 @@ import qualified Annex
import qualified Git import qualified Git
import qualified Git.Config import qualified Git.Config
import qualified Git.Objects import qualified Git.Objects
import qualified Git.LsFiles
import qualified Annex.Branch import qualified Annex.Branch
import Logs.UUID import Logs.UUID
import Logs.Trust.Basic import Logs.Trust.Basic
@ -32,7 +31,6 @@ import Types.RepoVersion
import Annex.Version import Annex.Version
import Annex.Difference import Annex.Difference
import Annex.UUID import Annex.UUID
import Annex.Link
import Annex.WorkTree import Annex.WorkTree
import Config import Config
import Config.Files import Config.Files
@ -101,7 +99,7 @@ initialize' :: Maybe RepoVersion -> Annex ()
initialize' mversion = checkCanInitialize $ do initialize' mversion = checkCanInitialize $ do
checkLockSupport checkLockSupport
checkFifoSupport checkFifoSupport
checkCrippledFileSystem checkCrippledFileSystem mversion
unlessM isBareRepo $ do unlessM isBareRepo $ do
hookWrite preCommitHook hookWrite preCommitHook
hookWrite postReceiveHook hookWrite postReceiveHook
@ -124,7 +122,7 @@ initialize' mversion = checkCanInitialize $ do
AdjustedBranch.InAdjustedClone -> return () AdjustedBranch.InAdjustedClone -> return ()
AdjustedBranch.NotInAdjustedClone -> AdjustedBranch.NotInAdjustedClone ->
ifM (crippledFileSystem <&&> (not <$> isBareRepo)) ifM (crippledFileSystem <&&> (not <$> isBareRepo))
( adjustToCrippledFilesystem ( AdjustedBranch.adjustToCrippledFileSystem
-- Handle case where this repo was cloned from a -- Handle case where this repo was cloned from a
-- direct mode repo -- direct mode repo
, unlessM isBareRepo , unlessM isBareRepo
@ -148,7 +146,11 @@ uninitialize = do
- Checks repository version and handles upgrades too. - Checks repository version and handles upgrades too.
-} -}
ensureInitialized :: Annex () ensureInitialized :: Annex ()
ensureInitialized = getVersion >>= maybe needsinit checkUpgrade ensureInitialized = do
getVersion >>= maybe needsinit checkUpgrade
whenM isDirect $
unlessM (upgrade True versionForAdjustedBranch) $
giveup "Upgrading this direct mode repository failed, and direct mode is no longer supported."
where where
needsinit = ifM Annex.Branch.hasSibling needsinit = ifM Annex.Branch.hasSibling
( initialize Nothing Nothing ( initialize Nothing Nothing
@ -200,9 +202,15 @@ probeCrippledFileSystem' tmp = do
) )
#endif #endif
checkCrippledFileSystem :: Annex () checkCrippledFileSystem :: Maybe RepoVersion -> Annex ()
checkCrippledFileSystem = whenM probeCrippledFileSystem $ do checkCrippledFileSystem mversion = whenM probeCrippledFileSystem $ do
warning "Detected a crippled filesystem." warning "Detected a crippled filesystem."
unlessM isBareRepo $ case mversion of
Just ver | ver < versionForCrippledFilesystem ->
giveup $ "Cannot use repo version " ++ show (fromRepoVersion ver) ++ " in a crippled filesystem."
_ -> noop
setCrippledFileSystem True setCrippledFileSystem True
{- Normally git disables core.symlinks itself when the {- Normally git disables core.symlinks itself when the
@ -282,22 +290,3 @@ propigateSecureHashesOnly :: Annex ()
propigateSecureHashesOnly = propigateSecureHashesOnly =
maybe noop (setConfig (ConfigKey "annex.securehashesonly")) maybe noop (setConfig (ConfigKey "annex.securehashesonly"))
=<< getGlobalConfig "annex.securehashesonly" =<< getGlobalConfig "annex.securehashesonly"
adjustToCrippledFilesystem :: Annex ()
adjustToCrippledFilesystem = ifM versionSupportsAdjustedBranch
( ifM (liftIO $ AdjustedBranch.isGitVersionSupported)
( AdjustedBranch.adjustToCrippledFileSystem
, enableDirectMode
)
, enableDirectMode
)
enableDirectMode :: Annex ()
enableDirectMode = unlessM isDirect $ do
warning "Enabling direct mode."
top <- fromRepo Git.repoPath
(l, clean) <- inRepo $ Git.LsFiles.inRepo [top]
forM_ l $ \f ->
maybe noop (`toDirect` f) =<< isAnnexLink f
void $ liftIO clean
setDirect True

View file

@ -1,10 +1,19 @@
git-annex (7.20190820) UNRELEASED; urgency=medium git-annex (7.20190820) UNRELEASED; urgency=medium
* Automatically convert direct mode repositories to v7 with adjusted
unlocked branches and set annex.thin.
* assistant: When creating a new repository, no longer use direct
mode, instead use v7 adjusted branches with annex.thin.
* init: When run on a crippled filesystem with --version=5,
will error out, since version 7 is needed for adjusted unlocked branch.
* direct: This command always errors out as direct mode is no longer
supported.
* indirect: This command has become a deprecated noop.
* proxy: This command is deprecated because it was only needed in direct
mode. (But it continues to work.)
* info: When file matching options are specified when getting * info: When file matching options are specified when getting
info of something other than a directory, they won't have any effect, info of something other than a directory, they won't have any effect,
so error out to avoid confusion. so error out to avoid confusion.
* assistant: When creating a new repository, no longer use direct
mode, instead use v7 adjusted branches with annex.thin.
* When upgrading a direct mode repo to v7 with adjusted unlocked branches, * When upgrading a direct mode repo to v7 with adjusted unlocked branches,
fix a bug that prevented annex.thin from taking effect for the files fix a bug that prevented annex.thin from taking effect for the files
in working tree. in working tree.

View file

@ -8,60 +8,14 @@
module Command.Direct where module Command.Direct where
import Command import Command
import qualified Git
import qualified Git.LsFiles
import qualified Git.Branch
import Config
import Annex.Direct
import Annex.Version
cmd :: Command cmd :: Command
cmd = notBareRepo $ noDaemonRunning $ cmd = notBareRepo $ noDaemonRunning $
command "direct" SectionSetup "switch repository to direct mode" command "direct" SectionSetup "switch repository to direct mode (deprecated)"
paramNothing (withParams seek) paramNothing (withParams seek)
seek :: CmdParams -> CommandSeek seek :: CmdParams -> CommandSeek
seek = withNothing (commandAction start) seek = withNothing (commandAction start)
start :: CommandStart start :: CommandStart
start = ifM versionSupportsDirectMode start = giveup "Direct mode is not supported by this repository version. Use git-annex unlock instead."
( ifM isDirect
( stop
, starting "direct" (ActionItemOther Nothing)
perform
)
, giveup "Direct mode is not supported by this repository version. Use git-annex unlock instead."
)
perform :: CommandPerform
perform = do
showOutput
_ <- inRepo $ Git.Branch.commitCommand Git.Branch.ManualCommit
[ Param "-a"
, Param "-m"
, Param "commit before switching to direct mode"
]
top <- fromRepo Git.repoPath
(l, clean) <- inRepo $ Git.LsFiles.inRepo [top]
forM_ l go
void $ liftIO clean
next cleanup
where
go = whenAnnexed $ \f k -> do
toDirectGen k f >>= \case
Nothing -> noop
Just a -> tryNonAsync a >>= \case
Left e -> warnlocked f e
Right _ -> return ()
return Nothing
warnlocked :: FilePath -> SomeException -> Annex ()
warnlocked f e = do
warning $ f ++ ": " ++ show e
warning "leaving this file as-is; correct this problem and run git annex fsck on it"
cleanup :: CommandCleanup
cleanup = do
setDirect True
return True

View file

@ -8,89 +8,14 @@
module Command.Indirect where module Command.Indirect where
import Command import Command
import qualified Git
import qualified Git.Branch
import qualified Git.LsFiles
import Git.FileMode
import Config
import qualified Annex
import Annex.Direct
import Annex.Content
import Annex.Content.Direct
import Annex.CatFile
import Annex.Init
import Annex.Ingest
cmd :: Command cmd :: Command
cmd = notBareRepo $ noDaemonRunning $ cmd = notBareRepo $ noDaemonRunning $
command "indirect" SectionSetup "switch repository to indirect mode" command "indirect" SectionSetup "switch repository to indirect mode (deprecated)"
paramNothing (withParams seek) paramNothing (withParams seek)
seek :: CmdParams -> CommandSeek seek :: CmdParams -> CommandSeek
seek = withNothing (commandAction start) seek = withNothing (commandAction start)
start :: CommandStart start :: CommandStart
start = ifM isDirect start = stop
( do
unlessM (coreSymlinks <$> Annex.getGitConfig) $
giveup "Git is configured to not use symlinks, so you must use direct mode."
whenM probeCrippledFileSystem $
giveup "This repository seems to be on a crippled filesystem, you must use direct mode."
starting "indirect" (ActionItemOther Nothing)
perform
, stop
)
perform :: CommandPerform
perform = do
whenM stageDirect $ do
showOutput
void $ inRepo $ Git.Branch.commitCommand Git.Branch.ManualCommit
[ Param "-m"
, Param "commit before switching to indirect mode"
]
-- Note that we set indirect mode early, so that we can use
-- moveAnnex in indirect mode.
setDirect False
top <- fromRepo Git.repoPath
(l, clean) <- inRepo $ Git.LsFiles.stagedOthersDetails [top]
forM_ l go
void $ liftIO clean
next $ return True
where
{- Walk tree from top and move all present direct mode files into
- the annex, replacing with symlinks. Also delete direct mode
- caches and mappings. -}
go (f, Just sha, Just mode) | isSymLink mode = do
r <- liftIO $ catchMaybeIO $ getSymbolicLinkStatus f
case r of
Just s
| isSymbolicLink s -> void $ flip whenAnnexed f $
\_ k -> do
removeInodeCache k
removeAssociatedFiles k
return Nothing
| otherwise ->
maybe noop (fromdirect f)
=<< catKey sha
_ -> noop
go _ = noop
fromdirect f k = do
removeInodeCache k
removeAssociatedFiles k
whenM (liftIO $ not . isSymbolicLink <$> getSymbolicLinkStatus f) $ do
v <- tryNonAsync (moveAnnex k f)
case v of
Right True -> do
l <- calcRepo $ gitAnnexLink f k
liftIO $ createSymbolicLink l f
Right False -> warnlocked "Failed to move file to annex"
Left e -> catchNonAsync (restoreFile f k e) $
warnlocked . show
warnlocked msg = do
warning msg
warning "leaving this file as-is; correct this problem and run git annex add on it"

View file

@ -8,23 +8,11 @@
module Command.Proxy where module Command.Proxy where
import Command import Command
import Config
import Utility.Tmp.Dir
import Utility.Env
import Annex.Direct
import Annex.Tmp
import qualified Git
import qualified Git.Sha
import qualified Git.Ref
import qualified Git.Branch
import qualified Git.LsFiles
import Git.FilePath
import Utility.CopyFile
cmd :: Command cmd :: Command
cmd = notBareRepo $ cmd = notBareRepo $
command "proxy" SectionPlumbing command "proxy" SectionPlumbing
"safely bypass direct mode guard" "safely bypass direct mode guard (deprecated)"
("-- git command") (withParams seek) ("-- git command") (withParams seek)
seek :: CmdParams -> CommandSeek seek :: CmdParams -> CommandSeek
@ -32,48 +20,4 @@ seek = withWords (commandAction . start)
start :: [String] -> CommandStart start :: [String] -> CommandStart
start [] = giveup "Did not specify command to run." start [] = giveup "Did not specify command to run."
start (c:ps) = liftIO . exitWith =<< ifM isDirect start (c:ps) = liftIO $ exitWith =<< safeSystem c (map Param ps)
( withOtherTmp $ \tmp -> withTmpDirIn tmp "proxy" go
, liftIO $ safeSystem c (map Param ps)
)
where
go tmp = do
oldref <- fromMaybe Git.Sha.emptyTree
<$> (inRepo . maybe Git.Ref.headSha Git.Ref.sha
=<< inRepo Git.Branch.currentUnsafe)
exitcode <- proxy tmp
cleanupproxy tmp oldref
return exitcode
proxy tmp = do
usetmp <- liftIO $ Just . addEntry "GIT_WORK_TREE" tmp <$> getEnvironment
-- Set up the tmp work tree, to contain both a checkout of all
-- staged files as well as hard links (or copies) of any
-- unstaged files.
unlessM (isNothing <$> inRepo Git.Branch.current) $
unlessM (liftIO $ boolSystemEnv "git" [Param "checkout", Param "--", Param "."] usetmp) $
error "Failed to set up proxy work tree."
top <- fromRepo Git.repoPath
(fs, cleanup) <- inRepo $ Git.LsFiles.notInRepo True [top]
forM_ fs $ \f -> do
tf <- inRepo $ toTopFilePath f
let tmpf = tmp </> getTopFilePath tf
liftIO $ do
createDirectoryIfMissing True (takeDirectory tmpf)
createLinkOrCopy f tmpf
liftIO $ void cleanup
liftIO $ safeSystemEnv c (map Param ps) usetmp
-- To merge the changes made by the proxied command into
-- the work tree is similar to cleaning up after a
-- direct mode merge. But, here we force updates of any
-- non-annxed files that were changed by the proxied
-- command.
cleanupproxy tmp oldref = do
updateWorkTree tmp oldref True
liftIO $ removeDirectoryRecursive tmp

View file

@ -1,129 +1,14 @@
Normally, git-annex repositories consist of symlinks that are checked into Normally, git-annex repositories consist of symlinks that are checked into
git, and in turn point at the content of large files that is stored in git, and in turn point at the content of large files that is stored in
`.git/annex/objects/`. Direct mode gets rid of the symlinks. `.git/annex/objects/`. Direct mode was a hack to avoid the symlinks.
The advantage of direct mode is that you can access files directly, The advantage of direct mode was that you can access files directly,
including modifying them. The disadvantage is that many regular git including modifying them. The disadvantage was that many regular git
commands cannot be used in a direct mode repository, since they don't commands could not used in a direct mode repository, since they don't
understand how to update its working tree. understand how to update its working tree.
[[!toc]] Direct mode has been removed from git-annex as of version 7.20190826.
The first time a new git-annex is run in a direct mode repository,
## deprecated it automatically converts it to a v7 repository with
[[unlocked|tips/unlocked files]]. See [[upgrades]] for details
Direct mode is deprecated! Instead, git-annex v7 repositories can simply about the transition to v7 repositories.
have files that are [[unlocked|tips/unlocked files]] and thus can be directly accessed and
modified. See [[upgrades]] for details about the transition to v7
repositories.
## enabling (and disabling) direct mode
Normally, git-annex repositories start off in indirect mode. With some
exceptions:
* Repositories created by the [[assistant]] use direct mode by default.
* Repositories on FAT and other less than stellar filesystems
that don't support things like symlinks will be automatically put
into direct mode.
* Windows always uses direct mode.
Any repository can be converted to use direct mode at any time, and if you
decide not to use it, you can convert back to indirect mode just as easily.
Also, you can have one clone of a repository using direct mode, and another
using indirect mode.
To start using direct mode:
git annex direct
To stop using direct mode:
git annex indirect
## safety of using direct mode
With direct mode, you're operating without large swathes of git-annex's
carefully constructed safety net, which ensures that past versions of
files are preserved and can be accessed.
With direct mode, any file can be edited directly, or deleted at any time,
and there's no guarantee that the old version is backed up somewhere else.
So if you care about preserving the history of files, you're strongly
encouraged to tell git-annex that your direct mode repository cannot be
trusted to retain the content of a file. To do so:
git annex untrust .
On the other hand, if you only care about the current versions of files,
and are using git-annex with direct mode to keep files synchronised between
computers, and manage your files, this should not be a concern for you.
## use a direct mode repository
You can use most git-annex commands as usual in a direct mode repository.
Direct mode also works well with the git-annex assistant.
The most important command to use in a direct mode repository is `git annex
sync`. This will commit any files you have run `git annex add` on, as well
as files that were added earlier and have been modified. It will push
the changes to other repositories for `git annex sync` there to pick up,
and will pull and merge any changes made on other repositories into the
local repository.
## what doesn't work in direct mode
A very few git-annex commands don't work in direct mode, and will refuse
to do anything. For example, `git annex unlock` doesn't make sense in
direct mode.
As for git commands, direct mode prevents using any git command that would
modify or access the work tree. So you cannot `git commit` or `git pull`
(use `git annex sync` for both instead), or run `git status` (use `git
annex status` instead). These git commands will complain "fatal: This
operation must be run in a work tree".
The reason for this is that git doesn't understand how git-annex uses the
work tree in direct mode. Where git expects the symlinks that get checked
into git to be checked out in the work tree, direct mode instead replaces
them with the actual content of files, as managed by git-annex.
There are still lots of git commands you can use in direct mode. For
example, you can run `git log` on files, run `git push`, `git fetch`,
`git config`, `git remote add` etc.
## proxing git commands in direct mode
For those times when you really need to run a command like `git revert
HEAD` in a direct mode repository, git-annex has the ability to proxy
the command to work in direct mode.
For example:
git annex proxy -- git revert HEAD
git annex proxy -- git checkout HEAD^^
git annex proxy -- git mv mydir newname
This works by setting up a temporary work tree, letting the git
command run on that work tree, and then updating the real work
tree to reflect any changes staged or committed by the git command,
with appropriate handling of the direct mode files.
## undoing changes in direct mode
There is also the `undo` command to do the equivalent of the above revert
in a simpler way. Say you made a change in direct mode, the assistant
dutifully committed it and you realise your mistake, you can try:
git annex undo file
## forcing git to use the work tree in direct mode
This is for experts only. You can lose data doing this, or check enormous
files directly into your git repository, and it's your fault if you do!
Ok, with the warnings out of the way, all you need to do to make any
git command access the work tree in direct mode is pass it
`-c core.bare=false`

View file

@ -22,7 +22,7 @@ non-large file directly to the git repository, instead of to the annex.
Large files are added to the annex in locked form, which prevents further Large files are added to the annex in locked form, which prevents further
modification of their content unless unlocked by [[git-annex-unlock]](1). modification of their content unless unlocked by [[git-annex-unlock]](1).
(This is not the case however when a repository is in a filesystem not (This is not the case however when a repository is in a filesystem not
supporting symlinks, or is in direct mode.) supporting symlinks.)
To add a file to the annex in unlocked form, `git add` can be used instead To add a file to the annex in unlocked form, `git add` can be used instead
(that only works in repository v7 or higher). (that only works in repository v7 or higher).

View file

@ -12,10 +12,6 @@ This plumbing-level command looks up filename used to store the content
of a key. The filename is output to stdout. If the key's content is not of a key. The filename is output to stdout. If the key's content is not
present in the local repository, nothing is output, and it exits nonzero. present in the local repository, nothing is output, and it exits nonzero.
Note that in direct mode, the file will typically be in the git work
tree, and while its content should correspond to the key, the file
could become modified at any time after git-annex checks it.
# OPTIONS # OPTIONS
* `--batch` * `--batch`

View file

@ -1,6 +1,6 @@
# NAME # NAME
git-annex direct - switch repository to direct mode git-annex direct - switch repository to direct mode (deprecated)
# SYNOPSIS # SYNOPSIS
@ -8,20 +8,9 @@ git annex direct
# DESCRIPTION # DESCRIPTION
Switches a repository to use direct mode, where rather than symlinks to This used to switch a repository to use direct mode.
files, the files are directly present in the repository. But direct mode is no longer used; git-annex automatically converts
direct mode repositories to v7 adjusted unlocked branches.
As part of the switch to direct mode, any changed files will be committed.
Note that git commands that operate on the work tree will refuse to
run in direct mode repositories. Use `git annex proxy` to safely run such
commands.
Note that the direct mode/indirect mode distinction is removed in v7
git-annex repositories. In such a repository, you can
use [[git-annex-unlock]](1) to make a file's content be directly present.
You can also use [[git-annex-adjust]](1) to enter a branch where all
annexed files are unlocked, which is similar to the old direct mode.
# SEE ALSO # SEE ALSO
@ -29,8 +18,6 @@ annexed files are unlocked, which is similar to the old direct mode.
[[git-annex-indirect]](1) [[git-annex-indirect]](1)
[[git-annex-unlock]](1)
[[git-annex-adjust]](1) [[git-annex-adjust]](1)
# AUTHOR # AUTHOR

View file

@ -45,8 +45,7 @@ that can be determined purely by looking at the key.
# EXAMPLES # EXAMPLES
The location a key's value is stored (in indirect mode) The location where the content of a key is stored can be looked up by running:
can be looked up by running:
git annex examinekey $KEY --format='.git/annex/objects/${hashdirmixed}${key}/${key}' git annex examinekey $KEY --format='.git/annex/objects/${hashdirmixed}${key}/${key}'

View file

@ -1,6 +1,6 @@
# NAME # NAME
git-annex indirect - switch repository to indirect mode git-annex indirect - switch repository to indirect mode (deprecated)
# SYNOPSIS # SYNOPSIS
@ -8,11 +8,11 @@ git annex indirect
# DESCRIPTION # DESCRIPTION
Switches a repository back from direct mode to the default, indirect This command was used to switch a repository back from direct mode
mode. indirect mode.
Note that the direct mode/indirect mode distinction is removed in v7 Now git-annex automatically converts direct mode repositories to v7
git-annex repositories. with adjusted unlocked branches, so this command does nothing.
# SEE ALSO # SEE ALSO

View file

@ -13,7 +13,7 @@ automatically creates a post-receive hook using this.
When a repository is configured with receive.denyCurrentBranch=updateInstead, When a repository is configured with receive.denyCurrentBranch=updateInstead,
pushes to the repository update its work tree. However, that does not work pushes to the repository update its work tree. However, that does not work
for repositories that use direct mode or have an adjusted branch checked for repositories that use have an adjusted branch checked
out. The hook updates the work tree when run in such a repository, out. The hook updates the work tree when run in such a repository,
the same as running `git-annex merge` would. the same as running `git-annex merge` would.
@ -21,8 +21,6 @@ the same as running `git-annex merge` would.
[[git-annex]](1) [[git-annex]](1)
[[git-annex-direct]](1)
[[git-annex-adjust]](1) [[git-annex-adjust]](1)
[[git-annex-merge]](1) [[git-annex-merge]](1)

View file

@ -1,6 +1,6 @@
# NAME # NAME
git-annex proxy - safely bypass direct mode guard git-annex proxy - safely bypass direct mode guard (deprecated)
# SYNOPSIS # SYNOPSIS
@ -8,36 +8,9 @@ git annex proxy `-- git cmd [options]`
# DESCRIPTION # DESCRIPTION
Only useful in a direct mode repository, this runs the specified git This command was for use in a direct mode repository, and such
command with a temporary work tree, and updates the working tree to repositories are automatically updated to use an adjusted unlocked branch.
reflect any changes staged or committed by the git command. So, there's no reason to use this command any longer.
For example, to revert the most recent change that was committed
to the repository:
git annex proxy -- git revert HEAD
To check out a past version of the repository:
git annex proxy -- git checkout HEAD^^
To rename a directory:
git annex proxy -- git mv mydir newname
To commit the changes to a specific file, first use git annex add to
stage the changes in the index, and then proxy a commit:
git annex add myfile
git annex proxy -- git commit myfile -m foo
The temporary work tree that the git command is run in is set up by
checking out all files that are in the index, and copying (or hard linking)
any unstaged files from the real work tree. Since the git command is run
using this temporary work tree, it won't see eg, local modifications to
files. So, it probably is not useful to proxy a command like "git add".
However, you can use the proxy with any git command you like, as long as
you think about how it will interact with the temporary work tree.
# SEE ALSO # SEE ALSO

View file

@ -14,8 +14,6 @@ in the working tree.
Show files that are not checked into git (?), deleted (D), Show files that are not checked into git (?), deleted (D),
modified (M), added but not committed (A), and type changed/unlocked (T). modified (M), added but not committed (A), and type changed/unlocked (T).
Particularly useful in direct mode.
# OPTIONS # OPTIONS
* `--ignore-submodules=when` * `--ignore-submodules=when`

View file

@ -100,7 +100,7 @@ subdirectories).
* `status [path ...]` * `status [path ...]`
Similar to `git status --short`, displays the status of the files in the Similar to `git status --short`, displays the status of the files in the
working tree. Particularly useful in direct mode. working tree.
See [[git-annex-status]](1) for details. See [[git-annex-status]](1) for details.
@ -313,19 +313,6 @@ subdirectories).
See [[git-annex-vicfg]](1) for details. See [[git-annex-vicfg]](1) for details.
* `direct`
Switches a repository to use direct mode, where rather than symlinks to
files, the files are directly present in the repository.
See [[git-annex-direct]](1) for details.
* `indirect`
Switches a repository back from direct mode to the default, indirect mode.
See [[git-annex-indirect]](1) for details.
* `adjust` * `adjust`
Switches a repository to use an adjusted branch, which can automatically Switches a repository to use an adjusted branch, which can automatically
@ -333,6 +320,18 @@ subdirectories).
See [[git-annex-adjust]](1) for details. See [[git-annex-adjust]](1) for details.
* `direct`
Switches a repository to use direct mode. (deprecated)
See [[git-annex-direct]](1) for details.
* `indirect`
Switches a repository to use indirect mode. (deprecated)
See [[git-annex-indirect]](1) for details.
# REPOSITORY MAINTENANCE COMMANDS # REPOSITORY MAINTENANCE COMMANDS
* `fsck [path ...]` * `fsck [path ...]`
@ -665,20 +664,6 @@ subdirectories).
See [[git-annex-rekey]](1) for details. See [[git-annex-rekey]](1) for details.
* `findref [ref]`
Lists files in a git ref. (deprecated)
See [[git-annex-findref]](1) for details.
* `proxy -- git cmd [options]`
Only useful in a direct mode repository, this runs the specified git
command with a temporary work tree, and updates the working tree to
reflect any changes staged or committed by the git command.
See [[git-annex-proxy]](1) for details.
* `resolvemerge` * `resolvemerge`
Resolves a conflicted merge, by adding both conflicting versions of the Resolves a conflicted merge, by adding both conflicting versions of the
@ -708,6 +693,18 @@ subdirectories).
See [[git-annex-remotedaemon]](1) for details. See [[git-annex-remotedaemon]](1) for details.
* `findref [ref]`
Lists files in a git ref. (deprecated)
See [[git-annex-findref]](1) for details.
* `proxy -- git cmd [options]`
Bypass direct mode guard. (deprecated)
See [[git-annex-proxy]](1) for details.
# TESTING COMMANDS # TESTING COMMANDS
* `test` * `test`
@ -1052,7 +1049,7 @@ Here are all the supported configuration settings.
Makes the watch and assistant commands delay for the specified number of Makes the watch and assistant commands delay for the specified number of
seconds before adding a newly created file to the annex. Normally this seconds before adding a newly created file to the annex. Normally this
is not needed, because they already wait for all writers of the file is not needed, because they already wait for all writers of the file
to close it. On Mac OSX, when not using direct mode this defaults to to close it. On Mac OSX, this defaults to
1 second, to work around a bad interaction with software there. 1 second, to work around a bad interaction with software there.
* `annex.expireunused` * `annex.expireunused`
@ -1134,12 +1131,6 @@ Here are all the supported configuration settings.
Automatically maintained, and used to automate upgrades between versions. Automatically maintained, and used to automate upgrades between versions.
* `annex.direct`
Set to true when the repository is in direct mode. Should not be set
manually; use the "git annex direct" and "git annex indirect" commands
instead.
* `annex.crippledfilesystem` * `annex.crippledfilesystem`
Set to true if the repository is on a crippled filesystem, such as FAT, Set to true if the repository is on a crippled filesystem, such as FAT,

View file

@ -15,8 +15,7 @@ names of the files and some other metadata remain there.
The contents of the files are kept by git-annex in a distributed key/value The contents of the files are kept by git-annex in a distributed key/value
store consisting of every clone of a given git repository. That's a fancy store consisting of every clone of a given git repository. That's a fancy
way to say that git-annex stores the actual file content somewhere under way to say that git-annex stores the actual file content somewhere under
`.git/annex/`. (See [[internals]] for details and note that in `.git/annex/`. (See [[internals]] for details.)
[[direct_mode]] the file contents are left in the work tree.)
That was the values; what about the keys? Well, a key is calculated for a That was the values; what about the keys? Well, a key is calculated for a
given file when it's first added into git-annex. Normally this uses a hash given file when it's first added into git-annex. Normally this uses a hash

View file

@ -20,15 +20,6 @@ This two-level structure is used because it allows the write bit to be removed
from the subdirectories as well as from the files. That prevents accidentally from the subdirectories as well as from the files. That prevents accidentally
deleting or changing the file contents. See [[lockdown]] for details. deleting or changing the file contents. See [[lockdown]] for details.
In [[direct_mode]], file contents are not stored in here, and instead
are stored directly in the file. However, the same symlinks are still
committed to git, internally.
Also in [[direct_mode]], some additional data is stored in these directories.
`.cache` files contain cached file stats used in detecting when a file has
changed, and `.map` files contain a list of file(s) in the work directory
that contain the key.
### `.git/annex/tmp/` ### `.git/annex/tmp/`
This directory contains partially transferred objects. This directory contains partially transferred objects.

View file

@ -5,4 +5,3 @@
* [[special_remotes]] * [[special_remotes]]
* [[workflows|workflow]] * [[workflows|workflow]]
* [[sync]] * [[sync]]
* [[direct_mode]]

View file

@ -6,8 +6,8 @@ submodule, that points to the real git repository under `.git/modules/`.
This presents problems for git-annex. So, when used in a submodule, This presents problems for git-annex. So, when used in a submodule,
git-annex will automatically replace the `.git` file with a symlink git-annex will automatically replace the `.git` file with a symlink
pointing at the git repository. (When the filesystem doesn't support pointing at the git repository. (When the filesystem doesn't support
symlinks, direct mode is used, and submodules are supported in that symlinks, an adjusted unlocked branch is used, and submodules are
setup too.) supported in that setup too.)
With that taken care of, git-annex should work ok in submodules. Although With that taken care of, git-annex should work ok in submodules. Although
this is a new and somewhat experimental feature. this is a new and somewhat experimental feature.

View file

@ -106,15 +106,3 @@ It might be interesting to find someway to unlock and lock the library
only when running calibre, a simple script to launch calibre will do only when running calibre, a simple script to launch calibre will do
that. Note that each time you will lock and unlock, you will have a that. Note that each time you will lock and unlock, you will have a
new commit in git. new commit in git.
Another solution
===================
You could also use direct mode in place of the auto unlock feature
git annex direct
Then remove the `post-commit` git hook (or do not add it). Its a
simpler solution, but remember that interaction between git annex direct
repositories and plain git are complex and sometimes downright dangerous. See [[direct mode]] for details.
In particular, do *not* called `git add *` in the above steps, as that will commit all books into git.

View file

@ -6,9 +6,7 @@ With git-annex this changes some: Very large files can be managed with git-annex
In this method, you just remove annexed files whenever you want, and commit the changes. This is probably the most natural way to go. In this method, you just remove annexed files whenever you want, and commit the changes. This is probably the most natural way to go.
In an indirect mode repo, you can do this the same way you would in a regular git repository. For example, `git rm foo; git commit -m "removed foo"`. This leaves the contents of the files still in the annex, not really deleted yet. You can do this the same way you would in a regular git repository. For example, `git rm foo; git commit -m "removed foo"`. This leaves the contents of the files still in the annex, not really deleted yet.
If you have a direct mode repo, you can't run `git rm` in it. Instead, you can just delete files using `rm` or your file manager, and then run `git annex sync` to commit the deletion. That will delete the file's content from your disk. Even if it's the only copy of the file!
Either way, deleting files can leave some garbage lying around in either the local repository, or other repositories that contained a copy of the content of the file you deleted. Eventually you'll want to free up some disk space used by one of these repositories, and then it's time to take out the garbage. Either way, deleting files can leave some garbage lying around in either the local repository, or other repositories that contained a copy of the content of the file you deleted. Eventually you'll want to free up some disk space used by one of these repositories, and then it's time to take out the garbage.

View file

@ -81,8 +81,7 @@ Download and install the [git-annex-turtle](https://github.com/andrewringler/git
## OS X (Finder) Context Menus ## OS X (Finder) Context Menus
For OS X, it is possible to get context menus in Finder. Due to how OS X For OS X, it is possible to get context menus in Finder. Due to how OS X
deals with symlinks, one needs to operate on folders if using indirect deals with symlinks, one needs to operate on folders.
mode. Direct mode operation has not been tested.
1. Open Automator and create a new Service. 1. Open Automator and create a new Service.
2. Using the Drop down menus in the top create the sentence "Service receives selected folders in Finder.app" to have it work on folders. For direct mode operation it is probably reasonable to select "files or folders". 2. Using the Drop down menus in the top create the sentence "Service receives selected folders in Finder.app" to have it work on folders. For direct mode operation it is probably reasonable to select "files or folders".

View file

@ -6,9 +6,7 @@ done
## step 2: default for new repositories that used to use direct mode ## step 2: default for new repositories that used to use direct mode
Done when using the command line to init in a crippled filesystem. done
Done when using the assistant.
## step 3: auto-upgrade from direct mode ## step 3: auto-upgrade from direct mode
@ -26,6 +24,8 @@ Limited mostly to windows, also some FAT media. This seems difficult
to avoid though, see discussion in to avoid though, see discussion in
<http://git-annex.branchable.com/todo/annex.thin_without_hardlinks/> <http://git-annex.branchable.com/todo/annex.thin_without_hardlinks/>
done
## step 4: default for all new repositories ## step 4: default for all new repositories
Could probably happen fairly soon after switch of direct mode. Could probably happen fairly soon after switch of direct mode.

View file

@ -48,10 +48,6 @@ The upgrade events, so far:
## v6 -> v7 (git-annex version 7.x) ## v6 -> v7 (git-annex version 7.x)
The upgrade from v5 to v7 is handled manually for now.
Run `git-annex upgrade` to perform the upgrade.
v6 repositories are automatically upgraded to v7. v6 repositories are automatically upgraded to v7.
The only difference between v6 and v7 is that some additional git hooks The only difference between v6 and v7 is that some additional git hooks
@ -93,7 +89,10 @@ same tradeoff.
See [[tips/unlocked_files/]] for more details about locked files and thin See [[tips/unlocked_files/]] for more details about locked files and thin
mode. mode.
Run git-annex upgrade to perform this upgrade. Normally you will need to run git-annex upgrade to perform this upgrade.
But, when a new enough git-annex is used in a direct mode repository,
it will be automatically upgraded and configured to use unlocked files
instead of direct mode.
## v4 -> v5 (git-annex version 5.x) ## v4 -> v5 (git-annex version 5.x)

View file

@ -8,5 +8,4 @@
When you add a file to the annex and commit it, only a symlink to When you add a file to the annex and commit it, only a symlink to
the content is committed to git. The content itself is stored in the content is committed to git. The content itself is stored in
git-annex's backend, `.git/annex/` (or in [[direct_mode]] the file `.git/annex/objects/`
is left as-is).

View file

@ -1,5 +1,4 @@
Normally, the content of files in the annex is prevented from being modified. Normally, the content of files in the annex is prevented from being modified.
(Unless your repository is using [[direct_mode]].)
That's a good thing, because it might be the only copy, you wouldn't That's a good thing, because it might be the only copy, you wouldn't
want to lose it in a fumblefingered mistake. want to lose it in a fumblefingered mistake.
@ -19,9 +18,8 @@ it is a regular file.
(If you decide you don't need to modify the file after all, or want to discard (If you decide you don't need to modify the file after all, or want to discard
modifications, just use `git annex lock`.) modifications, just use `git annex lock`.)
When you `git commit` it will notice that you are committing an unlocked When you commit an unlocked file, all that gets committed to git is a
file, add its new content to the annex, and a pointer to that content is pointer to the content. The content of the file is stored by git-annex.
what gets committed to git.
$ echo "now smaller, but even cooler" > my_cool_big_file $ echo "now smaller, but even cooler" > my_cool_big_file
$ git commit my_cool_big_file -m "changed an annexed file" $ git commit my_cool_big_file -m "changed an annexed file"

View file

@ -11,7 +11,3 @@ Notice that, since annexed files are represented by symlinks,
the symlink will break when the file is moved into a subdirectory. the symlink will break when the file is moved into a subdirectory.
But, git-annex will fix this up for you when you commit -- But, git-annex will fix this up for you when you commit --
it has a pre-commit hook that watches for and corrects broken symlinks. it has a pre-commit hook that watches for and corrects broken symlinks.
(Note that if a repository is in direct mode, you can't run normal git
commands in it. Instead, just move the files using non-git commands, and
`git annex add` and `git annex sync`.)