I came across a pretty strange git problem earlier today that got me scratching my head. I found a way to work around it, but figured I’d write it up here in case it’s useful to someone else.
I started using Git LFS recently for an iOS app. I’ve always disliked that git eventually barfs on binary files, especially as repositories grow. Since I’d vaguely heard of this new fangled thing a while ago, I figured I’d give it a try. I set things up and everything was working fine, until I started noticing this strange problem.
Whenever I’d check out a branch which had added a new set of pngs to an asset catalog, some of the pngs would show up as modified, according to
git status, even though the files were identical to what they were supposed to be. After a bunch of screwing around, it occurred to me to go check whether these files were even in LFS. Turns out
git lfs ls-files helps with this, and so does opening the file up in Github’s UI. To my surprise I found that these problematic files were not actually being tracked by LFS at all.
I set about trying to figure out why, and I’m now almost certain it’s Xcode that’s screwing up here. Take a look at this repository, which illustrates the problem. It turns out that when you drag pngs into an Xcode Asset Catalog, Xcode stages those files for you. However 1, if you commit those staged files, they aren’t tracked by LFS (can be confirmed by running
git lfs status). If you commit and push your changes at this point, it will result in those files being omitted from LFS. However, when you check out that branch elsewhere (via the command line, say), the command line git thinks those files have changed, because it expects to them to be in LFS, and they’re actually not. The files are identical from a file system perspective, because it doesn’t care about whether it got there via a text reference, or whether the actual binary was checked out the old way.
I did find a way to work around this for now: un-stage, and re-stage the files Xcode staged with either command line git, or SourceTree. Once that’s done, you can verify with
git lfs status, and then commit and push.
I’m not entirely sure why, but I suspect it has something to do with Xcode using it’s own version of git. ↩