I am working with a bare repository to transfer two keys from a custom backend to and from a special remote. This seems to be working fine.
In order to be able to make use of export remotes (exporttree=yes), I need to be able to specific a tree to be exported. For technical reasons, I want to keep using a bare repository, and use a hash-object
, update-index
, and write-tree
manually in order to create a tree. The Python code snippet that does this looks like this:
for key, prefix, fname in (
# the prefixes are constant hashdir-lower
(RepoAnnexGitRemote.refs_key, 'a11/1c8', '.datalad/dotgit/refs'),
(RepoAnnexGitRemote.repo_export_key, '6b2/c13',
'.datalad/dotgit/repo-export.zip')):
# create a blob for the annex link
out = repo._git_runner.run(
['git', 'hash-object', '-w', '--stdin'],
stdin=bytes(
f'../../.git/annex/objects/{prefix}/{key}/{key}', 'utf-8'),
protocol=StdOutCapture)
linkhash = out['stdout'].strip()
# place link into a tree
out = repo._git_runner.run(
['git', 'update-index', '--add', '--cacheinfo', '120000',
linkhash, fname],
protocol=StdOutCapture)
# write the complete tree, and return ID
out = repo._git_runner.run(
['git', 'write-tree'],
protocol=StdOutCapture)
exporttree = out['stdout'].strip()
It essentially creates the two blobs for the annex links, puts them together in a tree, and writes it to the repo.
However, after this code ran, git-annex is not longer operating properly in the bare repo:
% git annex drop --all
fatal: relative path syntax can't be used outside working tree
fatal: relative path syntax can't be used outside working tree
fatal: relative path syntax can't be used outside working tree
fatal: relative path syntax can't be used outside working tree
fatal: relative path syntax can't be used outside working tree
fatal: relative path syntax can't be used outside working tree
fatal: relative path syntax can't be used outside working tree
fatal: relative path syntax can't be used outside working tree
fatal: relative path syntax can't be used outside working tree
fatal: relative path syntax can't be used outside working tree
fatal: relative path syntax can't be used outside working tree
git-annex: fd:21: Data.ByteString.hGetLine: end of file
(fatal error messages are from cat-file batch calls inside)
When I comment this code out, everything goes back to normal. It seems to makes no difference whether I follow the problematic code up with a commit-tree
and update-ref
to actually have the mainline branch point to a commit with that tree. It also seems to make no difference, when I explicitly setpresentkey <key> <here> 0
.
AFAICS this creates the same records as if I would have done this in a regular worktree using high-level git-annex tooling. Other git-annex commands like fsck
seem to be working fine. If a create a branch with that tree, also findref
seems to be working properly.
Is this a bug, or am I doing something wrong? Thanks in advance for your time!
git update-index
creates an index file. A repo with an index file is no longer a bare repo to a certain extent, at least it is very unusual for a repo to be both bare and contain an index file, since after all an index file is a record of the files in the working tree. This seems to be the root of the confusion.I was able to reproduce this by simply copying
.git/index
from a non-bare repo into the bare repo and then runninggit-annex drop --all
.Removing the index file was not sufficient to fix it. It turned out I also needed to delete
annex/keydb*
. Then things returned to normal.So, it seems that the keys database is getting populated in a bare repo when there's an index file, and once the keys database is populated, it runs code paths that will not work in a bare repo, because that database contains paths (taken from the index) that it treats as being present in a nonexistant working tree. I've fixed it to both avoid populating the keys database, and ignore a populated keys database in this situation.
But.. My suggestion is, if you need to do this kind of thing in a bare repo, set
GIT_INDEX_FILE
to some other file. That's how git-annex makes similar tree objects.