git has a new feature:

CONFLICT (file location): x/foo/bar.ext added in refs/remotes/whatever/master inside a directory that was renamed in HEAD, suggesting it should perhaps be moved to y/bar.ext.

When this happens during a git-annex sync, the result is:


With the .variant file checked in, but the other one not checked in.

Which is problimatic both because the file does not get checked in, and because if this is a merge conflict at all (I disagree with git that it should be, didn't used to be), it's a conflict between x/foo/bar.ext and y/bar.ext and so git-annex sync should presumably make those two into .variant files, not 2 files in the same directory. Although, it might be better for git-annex not to make variant files at all in this situation, since both files have the same content.

The worse problem, perhaps, is that git-annex sync succeeds and if the user was not expecting this behavior, it can seem like their file has been lost, because it was moved to a directory they did not move it to! git merge is relying on this being a merge conflict for the user to see the error message and know where it renamed their file to, but this is counter to sync's desire to avoid merge conflicts for users who are not able to deal with that complication.

This new git feature does have a config. Set merge.directoryRenames=false to disable it. Or, merge.directoryRenames=true will avoid it being treated as a merge conflict. (The config was added in 2.22, while git started doing this in 2.18. Annoyingly, Debian stable shipped git 2.20 so produces conflicts with no way to turn it off.) One option would be for sync to set one of the two if it's not set (probably =false), and if it is set to =conflict (or the git version lacks the config), to deal with the conflict.

Based on git commit 8c8e5bd6eb331d055aa7fa6345f6dcdadd658979, it uses a higher than usual stage level in the index for the conflict produced by case, so it might be possible for git-annex to use that to detect it and handle it specially.


Fixed the file not being checked in. In fact, it needed to be cleaned up.

That avoids part of the problem. To avoid the surprising rename, git-annex sync should set merge.directoryRenames=false when merge.directoryRenames is not configured, unless automatic merge conflict resolution is disabled. --Joey

done --Joey