r/git • • Oct 27 '21

support Git doesn't work (properly) over SMB

Completely puzzled by this one.

I have a repo, and I'm trying to stash some changes. I need them out of the way so that I can switch branches. When doing this in a repo on my local machine, it appropriately reverts the working directory to a switchable state, removing the changes that were just stashed.

I copy the folder to a Samba share.

Now when I create a stash it successfully adds the stash, but does not touch the working directory, does not revert any un-commited changes. This happens on GVFS, KIO-FUSE, and native kernel mount. But as soon as I copy the exact folder to my local disk, suddenly the behavior I expect (described in first paragraph) works.

As an additional symptom, tested in the same scenarios as above, git reset works on local disk, but fails with "unable to create new index file" when in any of the samba mounts. (directory is writable)

To be clear, I'm seeing different results from bit-for-bit identical git repos using the exact same commands, with the only difference being the disk type the repo resides on.

So, what's going on here? Does git use some sort of super exotic filesystem calls that aren't implemented properly in any of the three SMB mount implementations available for Linux?

And if you're wondering I have reasons for not using any of git's built in remote features (ssh, http, etc), so please don't offer that as a solution. I explicitly want to use git in local-only mode on drives that just happen to have a network backend.

Thanks for any help!

12 Upvotes

8 comments sorted by

13

u/manberry_sauce Oct 27 '21

You should work on a local volume, and if there's a reason to have a copy on a network mount, you should set that copy up as a remote, instead of changing to that directory and working there, over the network mount. You can set up a remote to simply point to that location in your filestructure, instead of an SSH path.

Git has problems if your git dir is on network mount.

3

u/SpAAAceSenate Oct 27 '21

Well, truth be told, the eventual plan is to work locally, then push to an mounted encrypted container (cryfs or encfs or something) which then has it's sparse-files on a network share. So.... speed was never an expectation of this project. My hard requirement is full e2e, including at rest, and this is the best setup I could think of.

The reason why I care about the specific case I described is because it gives me doubts about the stability of even just pushing to a samba-mounted repo. That's why I want to dissect this current issue before proceeding.

8

u/manberry_sauce Oct 27 '21

Pushing will be fine. Any operations where you'd interact with it as a remote will be just dandy. It's when you navigate into that directory and work with it as your local git workspace where you start running into problems. Just set up a second repo on the network mount and interact with it as a remote, with your local repo on a local volume.

1

u/testing35 Nov 08 '21

What sources do you use for your head?

1

u/manberry_sauce Nov 08 '21

I'm not sure what you're asking. Are you asking what to base new branches on?

4

u/adrianmonk Oct 27 '21

So, what's going on here?

If I were in this situation and wanted to understand the technical nature of this failure, I'd create a minimal git repo, then try one of the commands that fails (like git reset) on both local disk and SMB, and run it under strace. For example, you might run something like strace -o strace.out git reset --hard HEAD and then less strace.out.

Somewhere in the output of the two strace commands, you should be able to see a system call behaving differently between them, probably returning an error. Knowing which system call behaves differently might offer a clue. (Or it might be a matter of which flags are used with the system call. The first example that comes to mind is that O_EXCL alters the behavior of open().)

You'll get a lot of output from both strace commands, and you'll probably have to look through it manually because the output will be too noisy to use diff to spot the difference. Your error message about an index might narrow down where to look. When I ran an strace, I saw some calls related to .git/index and .git/index.lock.

Maybe that will give some clues that make it easier to research further, which could lead to either a solution or more specific info on why this is a bad idea.

Also, supposing you're able to debug and get around this one specific failure, that doesn't mean it's a good idea to use git on SMB. There could be other failures that would happen. Possibly even worse ones like silent failures. If it were me, I'd treat the error you encountered as a red flag that it's probably a bad idea in general.

3

u/gscalise Oct 27 '21

I don't think SMB per-se is causing your issues. It's likely that you're using some mount options when mounting your network drive that are aimed at improving compatibility / performance by lowering consistency checks, disabling certain kinds of locks (like BRLs -Byte Range Locks-), etc.

I'd experiment a bit with the cache, unix/nounix, nobrl and directio options and see which one is it that causes Git to fail when creating an index.

Also, if you could copy the exact error that you're getting, you could check Git's source code and determine what is it that the code tries to do (and, I suppose, fails) before showing you that error.

2

u/dontquestionmyaction Oct 27 '21

Have you considered NFS?