Please describe the problem in your own words.
Currently the command git annex info fails when run inside a submodule that is checked out in a linked Git worktree. The error it provides is:
changeWorkingDirectory: does not exist
Ordinary Git commands recognize the worktree correctly, and the same annex command succeeds when GIT_DIR and GIT_WORK_TREE are explicitly set to absolute paths.
I think it should work without those overrides.
What steps will reproduce the problem?
This bash script should reproduce the problem on most systems:
#!/bin/sh
set -eu
workdir=$(mktemp -d)
cd "$workdir"
workdir=$(pwd -P)
# Create a repository to use as a submodule.
git init source
git -C source commit --allow-empty -m "Initial commit"
# Add it to a parent repository.
git init main
git -C main -c protocol.file.allow=always submodule add "$workdir/source" sub
git -C main commit -m "Add submodule"
# Check out the submodule in a linked worktree.
git -C main worktree add -b linked ../linked
git -C linked -c protocol.file.allow=always submodule update --init
cd linked/sub
git annex init repro
# Ordinary Git recognizes the worktree.
git rev-parse --show-toplevel
git status
# This fails with "changeWorkingDirectory: does not exist".
# Continue so we can also demonstrate the workaround.
git annex info || true
# Explicit absolute paths make the same command succeed.
GIT_DIR=$(git rev-parse --absolute-git-dir) \
GIT_WORK_TREE=$(pwd -P) \
git annex info
What version of git-annex are you using? On what operating system?
I have tried it across a range of versions.
Please provide any additional information below.
Have you had any luck using git-annex before?
Yes, lots. It's been working well for me in keeping track of scientific analyses.
This has nothing to do with
git-annex info, any git-annex command after the first initialization behaves this way.It seems that git-annex is seeing the git config of "core.worktree=../../../../../../linked/sub" and getting a little bit confused.
It constructs a Repo with a location of eg
That worktree is wrong. And since it's not being run in that worktree, it tries to chdir to it.
core.worktree is supposed to be relative to the gitdir. And since
.git -> ../../main/.git/worktrees/linked/modules/sub/, that's "../../main/.git/worktrees/linked/modules/sub/../../../../../../linked/sub" aka "../../linked/sub".The wrong worktree comes from Git.Config.updateLocation. It is using the gitdir seen above, rather than following the symlink to the git directory it points to. So it uses "/home/joey/tmp/tmp.rQ1fokJzh0/linked/sub/.git/../../../../../../linked/sub" which reduces to "/home/linked/sub".
So either Git.Config.updateLocation needs to change to follow the gitdir symlink, or the symlink needs to be followed at an earlier point.
It's worth noting that the first time git-annex runs, it ends up with the correct location eg
So the trouble comes from the various fixups that git-annex init has to do to convert .git files to symlinks.
I will need to refresh my memory about linked worktrees and gitdir symlinks to get any further.
As far as I can see, core.worktree is the only config setting that is relative to the path of the gitdir.
Changing the gitdir to be where the symlink points to does not seem like a good idea, it would affect git-annex code that creates symlinks pointing into the gitdir.
Also,
git rev-parse --git-diris just ".git" in this situation, so even git internally does not follow the symlink manually, except presumably when resolving core.worktree.So, I've fixed this only in the core.worktree handling code in updateLocation.