Doing a quick search of reported issues around git repos, basically the trouble is that a git repo folder does not expect to be sync'ed at a file level, because repos are expected to be in different states on different devices, and the state of a repo is represented in the filesystem via the .git directory.
As an example problem-case, say your first device checks out branch A and your second device checks out branch B. Some files conflict, which is likely reasonably handled as any filesync application needs to handle conflicting updates. But any files that are changed in one and not in the other end up getting sync'ed over into the other, including inside your GIT directory, which will very likely lead to an illegal GIT directory state.
As a toy example, pretend that the .git internals require that at any given time, `.git/activebranch/` must contain exactly one file whose filename is the name of the active branch, and git maintains this invariant. By syncing changed files, any filesync utility would break this invariant by resulting in `.git/activebranch/` containing two files, due to each side seeing a new file that the other side needs to acquire. Depending on how such a problem might manifest in real life as a result of performing a file-based sync on two instances of a git directory, this could lead to your .git directory entering a state in which git doesn't know how to interpret it.
--
This isn't a syncthing problem as such, it's a problem of trying to use a file syncing application on the internal state of an application on two different machines with two different states, and expecting the result to be a valid state.
> it's a problem of trying to use a file syncing application on the internal state of an application on two different machines with two different states, and expecting the result to be a valid state.
I think that we can narrow the problem down to the fact that git's internal state is represented in a way that is transparent to syncthing (a folder of files), that it will attempt to sync, but only partially succeed. If git's internal state was a single database file, you wouldn't get corruption, just a syncthing conflict file.
As an example problem-case, say your first device checks out branch A and your second device checks out branch B. Some files conflict, which is likely reasonably handled as any filesync application needs to handle conflicting updates. But any files that are changed in one and not in the other end up getting sync'ed over into the other, including inside your GIT directory, which will very likely lead to an illegal GIT directory state.
As a toy example, pretend that the .git internals require that at any given time, `.git/activebranch/` must contain exactly one file whose filename is the name of the active branch, and git maintains this invariant. By syncing changed files, any filesync utility would break this invariant by resulting in `.git/activebranch/` containing two files, due to each side seeing a new file that the other side needs to acquire. Depending on how such a problem might manifest in real life as a result of performing a file-based sync on two instances of a git directory, this could lead to your .git directory entering a state in which git doesn't know how to interpret it.
--
This isn't a syncthing problem as such, it's a problem of trying to use a file syncing application on the internal state of an application on two different machines with two different states, and expecting the result to be a valid state.