git-lfs is a weird one
I quite like using git for managing le content, but I also quite
like not having a repository get megabytes bigger every time I add a
screenshot, so I thought today would be a good day to try out
git-lfs, which basically stores large files out of band and just
versions the metadata and a reference to them.
First of all, I wanted a directory to just chuck things in - let's
call it ./blobs. This requires a .gitattributes file in the
repository root that looks like this:
blobs/** filter=lfs diff=lfs merge=lfs -text
As I often do with git, since it doesn't have any interest in
committing an empty directory, I added a README.md file to the
directory. No amount of fucking around would make git-lfs not try
to add the README.md as an LFS file (and it's not just
me).
[attr]not-lfs !filter !diff !merge text
blobs/** filter=lfs diff=lfs merge=lfs -text
blobs/README.md not-lfs
not
blobs/** filter=lfs diff=lfs merge=lfs -text
blobs/README.md -filter -diff -merge -text
Eventually I gave up and just added blobs/README.md first, then
added the .gitattributes file after, and that seems to work.
While it didn't seem to stop screwing around with the file to begin
with, adding this to .gitattributes does seem to mostly work, and
removing it manages to trigger
this
issue in magit:
blobs/README.md -filter -diff -merge -text
So, I'm not really sure. Perhaps I'm just misunderstanding how it's meant to work.
Anyway, I had my README.md as a text file and added a couple of
binary files. Now for the easiest part, time to push the repository! Let's do that:
Pushing to ssh://my.forgejo.example/user/repo.git
Uploading LFS objects: 50% (1/2), 173 KB | 3.3 KB/s, done.
LFS: Client error &{%!!(string=https) %!!(string=) %!!(*url.Userinfo=<nil>) %!!(string=my.forgejo.example) %!!(string=/user/repo.git/info/lfs/objects/3287493847ab1231231235452431221/412341234) %!!(string=) %!!(bool=false) %!!(bool=false) %!!(string=) %!!(string=) %!!(string=)}s(MISSING) from HTTP 413
Well, that's unexpected. Especially unexpected is getting an HTTP
error from a ssh push. I had been fucking around a lot with LFS
by this point so spent a while looking at paths and permissions on the
server to see if I'd collided something, but then I searched a lot for
"HTTP 413 git-lfs" and got annoyed at all the results just being
people misconfiguring the max body size limit for their frontend HTTP
proxy rather than explaining my special SSH problem. Eventually it
occurred to me that having an HTTP error might actually indicated an
HTTP problem, so I read one of the nginx articles and it was about
files above 5MB causing problems, and noticed that precisely one out
of two files copied OK, then I had a look at ./blobs directory:
❯ ls -l blobs/
-rw-r--r-- 1 rob staff 130 May 3 14:19 some-small-file
-rw-r--r-- 1 rob staff 114 May 3 14:00 README.md
-rw-r--r-- 1 rob staff 5103114 May 3 14:19 some-file-above-5MB
anyway, I added client_max_body_size 3000m; to the proxy config in
nginx and then it worked, voila.
Eventually I found the rather surprising fact that git-lfs
historically only
used ssh for
authentication, doing the actual data transfer via HTTP. There's a
proposal to not do
that
and an out-of-tree
implementation.
gitea actually has a config
option to do it
all over ssh, which is disabled by default due to a now-fixed bug
in git-lfs (and
another one).
forgejo hasn't ported that code
yet since it has
bad test coverage, which is a bit unfortunate.
Anyway! Now it mostly works.