I just migrated binaries from native git file tracking to git annex. Then I went on to clone the repo on a different device. Because older commits still contain the binaries I did a shallow clone. After that I wanted to fetch a few binaries from annex and ran git annex init; git annex sync
.
To my surprise instead of somehow working out the annex metadata with the remote it just force pushed an empty git-annex branch to the remote. Luckily I was just testing things out and had a backup available but for people who rely on a service like gitlab to access their annex repository when traveling this can end up being a very nasty surprise. I don't exactly know how this could best be fixed but force pushing without asking isn't a good solution in my opinion. Maybe git-annex-init could check if a remote already has annex metadata and pull that. git-annex-sync could fail and give you the option to add a force flag or work out how to merge things (which shouldn't be too hard when the local metadata is completely empty)
Well, I tried to reproduce this, following your instructions to the extent there were clear.
I made a repository, added some files to git, and committed. Then
git rm --cached
the files, andgit-annex add
to add them to git-annex, and committed. So master had 2 commits, an older commit where the files were in git, and a newer commit where the files are in git-annex. The git-annex branch had a couple of commits as well.Then I cloned:
In the clone, that made master be a single commit. There was no origin/git-annex branch in the clone, like there normally would be in a non-shallow clone.
Then I ran
git-annex init; git annex sync
:At this point, the git-annex branch in the remote repository is not destroyed. It contains a merge between the branch that was there before the clone and the git-annex branch that was synced from the clone. Looks just fine.
In the clone, there is still no origin/git-annex branch, and the git-annex branch has only the changes that git-annex committed to it in the clone.
So, the clone still doesn't know that it can get the annexed files from origin. But nothing is "destroyed".
This does not seem like the best possible behavior, it would be better if, after git-annex sync, it fetched origin/git-annex (either the latest commit or all of them) and merged it into the local git-annex branch.
What's going on is, the shallow clone gets remote.origin.fetch set to "+refs/heads/master:refs/remotes/origin/master". So, attempting to fetch any other branch from origin will always skip creating a tracking branch.
All you have to do, then is
That preserves master as a shallow clone, while letting the git-annex branch be fetched. Or, alternatively,
git fetch --unshallow
.Maybe git-annex sync could detect this situation and force fetch the git-annex branch. (eg, git fetch origin git-annex, which does actually fetch the refs, followed by manually setting origin/git-annex to
FETCH_HEAD
) That would leave workflows usinggit push
andgit pull
still with the problem. And it might be that someone who wants a shallow clone also wants the git-annex branch to be cloned shallowly and would object if its full history was fetched by that. I have not found a way yet to fetch the git-annex branch shallowly.