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 most regular git commands cannot safely be used, and only a subset of git-annex commands can be used.

Normally, git-annex repositories start off in indirect mode. With some exceptions:

  • Repositories created by the assistant use direct mode by default.
  • Repositories on FAT and other less than stellar filesystems that don't support things like symlinks will be automatically put into direct mode.

enabling (and disabling) direct mode

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; direct mode interoperates.

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 (until you dropunused them). 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. A very few commands don't work in direct mode, and will refuse to do anything.

Direct mode also works well with the git-annex assistant.

You can use git commit --staged, or plain git commit. But not git commit -a, or git commit <file> .. that'd commit whole large files into git!

what doesn't work in direct mode

git annex status shows incomplete information. A few other commands, like git annex unlock don't make sense in direct mode and will refuse to run.

As for git commands, you can probably use some git working tree manipulation commands, like git checkout and git revert in useful ways... But beware, these commands can replace files that are present in your repository with broken symlinks. If that file was the only copy you had of something, it'll be lost.

This is one more reason it's wise to make git-annex untrust your direct mode repositories. Still, you can lose data using these sort of git commands, so use extreme caution.

So, just which git commands are safe? It seems like I'm going to have to use direct mode, so it'd be nice to know just what I'm allowed to do, and what the workflow should be.
Comment by Michael Mon Feb 18 19:24:11 2013

All git commands that do not change files in the work tee (and do not stage files from the work tree), are safe. I don't have a complete list; it includes git log, git show, git diff, git commit (but not -a or with a file as a parameter), git branch, git fetch, git push, git grep, git status, git tag, git mv (this one is somewhat surprising, but I've tested it and it's ok)

git commands that change files in the work tree will replace your data with dangling symlinks. This includes things like git revert, git checkout, git merge, git pull, git reset

git commands that stage files from the work tree will commit your data to git directly. This includes git add, git commit -a, and git commit file

Comment by joeyh.name Mon Feb 18 22:55:13 2013

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.)

Comment by Michael Mon Feb 18 23:03:14 2013
git annex add $file
git commit -m changed
git annex sync
git annex copy $file --to otherrepo
Comment by joeyh.name Mon Feb 18 23:05:35 2013
Comments on this page are closed.