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/annex/objects/
. Direct mode gets rid of the symlinks.
The advantage of direct mode is that you can access files directly, including modifying them. The disadvantage is that many regular git commands cannot be used in a direct mode repository, since they don't understand how to update its working tree.
deprecated
Direct mode is deprecated! Intead, git-annex v6 repositories can simply have files that are unlocked and thus can be directly accessed and modified. See upgrades for details about the transition to v6 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
So, if I edit a "content file" (change a music file's metadata, say), what's the workflow to record that fact and then synchronise it to other repositories?
I can't do a
git add
, so I don't understand what has to happen as a first step. (Thanks for your quick reply above, BTW.)What happens to the object database (
.git/annex/objects
) when going to direct mode? Are the objects deleted, moved to another location, kept?If the objects are kept, does it means that the file on the repository in direct mode is duplicated in the object database? If so, would it be relevant to use
cp --reflink=auto
to populate the working directory to enable copy on write on filesystems that supports it?.git/annex/objects
does not typically contain any file contents in direct mode. The file contents are stored directly in the working tree.Would it be safe to add largefiles to gitignore in direct mode?
Can git-annex still track large files ignored by git?
Thanks. :-)
asbraithwaite: No, as far as I know it can not.
I too have issues with mixing direct and indirect mode repositories.
I have a regular, existing repository with ebooks, shared between various clones on proper :) filesystems; now I would need a copy of some of them on an ereader which only offers a FAT filesystem, so it has to be direct mode.
I get a directory full of small files, the way git manages links on FAT.
This detects the fact that it is working on a crippled filesystem, enables direct mode and disables ssh connection caching; up to now everything seems to be fine, but then
seems to work, downloads the file somewhere, but when I try to open $SOME_BOOK it is still the fake link, and the file has been downloaded in its destination, as if the repo wasn't in direct mode.
I use version 4.20130723 on debian jessie
There should be no obstacles to using direct mode on one clone of a git repository, and indirect mode on another clone. The data stored in git for either mode is identical, and I do this myself for some repositories.
@valhalla, you probably need to run
git annex fsck
, and if that does not solve your problem, you need to file a bug report.@obergix asked:
The answer is simple: By running
git annex sync
, which handles all that.Thanks for these details @joeyh. But AFAIU, one needs to proceed to the git annex copy before doing the git annex sync, otherwise, symlinks (or files containing the symlink path on SMB) will be created, instead of the plain "direct" files that are expected.
I'm still not sure whether the git annex sync needs to be issued on either of the indirect or direct remotes first, or both, then in which sequence. I think a "walkthrough" script would help.
I have an issue with direct mode: I have tons of symlinks that points to the git-annex store, while in direct mode. After investigation, I found that these files don't seem to be part of the repository. I can check with:
The link is valid, and is probably pointing to a unused file in the annex store. How to add these files back?
If I was in indirect mode, I could simply use
git add tr.html
(and notgit annex add
). This would stage to the git staging area the symlink, and all would be well.I found that in direct mode, the same was true. The command is:
The file is added to the repository, and the link is converted to the target file. The question now is why? There is no hook on the add command. Could it be the annex assistant? If that didn't worked, my question would have been: how to checkout a file in direct mode?
cp
command follows symlinks by default (I thought it didn't).I kinda wish people would post questions to the forum, and not clutter up this page..
Anyway, there have been past bugs in the direct mode code that caused some files to not be checked out in direct mode, but stay as symlinks pointing at the content. That can be fixed by running
git annex fsck
. But, I am not aware of any problem that can leave a git-annex symlink that is not checked into git at all. Perhaps you copied the symlink from another location?This page mentioned a --depth option, but no, it was never implemented. I have updated this page.
If you need something simpler than the basic undo, you can use
git annex proxy
to run eg, agit revert
.(Deleted a forum thread that duplicated the previous comment.)