Ever wonder why Git doesn't quite get it when you change the capitalization of a folder/file name?
In case you don't want my life story, here's the solution.
Imagine the following scenario:
Me: Hey, check out this sweet side project I'm working on!
You (potentially not a programmer): What is it?
Me: It's a guitar tabs editor in your browser!
You: Neato! Can I see it?
Me: Sure! Just navigate to https://github.com/dawneraq/fret-zone, clone the repository, run
yarn develop, then it'll run on your machine at http://localhost:3000/. You're comfortable with the command line, right?
If I want to show a non-developer my sweet side project, I'm probably not going to get very far if I tell them to clone, build, and serve it themselves. For everyone's convenience, I knew early on that the app would have to be hosted somewhere.
Netlify to the rescue#
These past few months, Netlify has made itself known to me as an awesome hosting solution for frontend-focused web apps. You just point it at a Git repo you own, specify a build command (like
yarn build) and a directory containing built files (like
build/), then they host it at https://whatever-url-you-want.netlify.app/. Netlify also makes it easy to deploy to a custom domain! (They're not paying me to say that. I just really like their platform.)
Having just read a free chapter of swyx's Coding Career Handbook, I was excited to do just that. I was ready make this hobby project-in-progress into part of my professional identity by showcasing it on a silly pun domain.
Because I initialized FretZone with
create-react-app, Netlify already knew the proper build command, as well as the directory from which to deploy. Great! All I had to do was make sure the app could deploy successfully, then I could migrate from https://fret-zone.netlify.app/ to my shiny new domain https://fret.zone/. ✨
But it failed to build#
The app worked on my machine. My Netlify build log told a different story:
10:40:20 AM: $ yarn build 10:40:21 AM: yarn run v1.22.4 10:40:21 AM: $ react-scripts build 10:40:22 AM: Creating an optimized production build... 10:40:27 AM: Failed to compile. 10:40:27 AM: 10:40:27 AM: ./src/App.jsx 10:40:27 AM: Cannot find file './components/ToolBar/Zoom' in './src'. 10:40:27 AM: error Command failed with exit code 1. 10:40:27 AM: info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
"Cannot find file"? One of the folders in that file's path used to be called
Toolbar, but I'd recently pushed a commit that renamed it to
ToolBar with a capital 'B'.
I double-checked the relevant import in
App.jsx. Looked fine.
import Zoom from './components/ToolBar/Zoom';
I double-checked the path in my local filesystem. Looked fine.
I double-checked the error message. Looked fine.
10:40:27 AM: Cannot find file './components/ToolBar/Zoom' in './src'.
I triple- and quadruple-checked those three things again. Why was I being gaslighted like this?
Netlify Support Guides to the rescue#
Looking up 'netlify "cannot find file"' led me to this support guide.
...most people realize they are having a case issue when they try and build on Netlify, as the problem doesn’t occur locally. This almost always means that the file(s) have been committed to Git and pushed to a provider such as GitHub.
So it was a case sensitivity issue? No way!
I flew into a nerd rage. The
ToolBar folder definitely had the correct name. It's right there in the file explorer screenshot above. Hadn't that change been pushed in the commit I mentioned earlier?
Apparently not. What do you mean "1 changed file"? The changelog only shows changes to import statements in that one file. I changed the directory name! All of the files within the
ToolBar folder should have had their names changed too.
If that's not the case...what does the path look like in the GitHub repo?
What's going on here?#
While my commit did register that the paths in
App.jsx's component imports changed, it didn't register that the file paths themselves changed.
macOS, my local development environment, is case-insensitive. This is why
ls ~/Documents and
ls ~/documents output the same thing. Git is case-insensitive too—the Netlify support guide I found also had this to say:
Simply renaming the file and re-committing and pushing it does not generally work because Git’s default setting is to ignore case, and so those changes aren’t always registered. 😕
Changing the capitalization of a folder or file name that's under version control is a little trickier than simply renaming it.
I tend to rename my files by right-clicking in Visual Studio Code's file explorer. However, I've noticed that Git's understanding of a file renamed this way is as follows:
- The original file has been deleted.
- A new file with the original file's contents has been added under a different name.
Git doesn't recognize that a file has been renamed until both of those changes have been staged.
The tracked file or folder you want to recapitalize has to be explicitly renamed using a Git command.
git mv works the same as
mv, except it informs Git that a file or folder has been renamed by immediately staging the change.
The approach in the Stack Overflow answer linked in the Netlify support guide gave me an invalid argument error. This command used just once works for renaming individual files, but it does not work for folders.
➜ components git:(master) ✗ git mv -f Toolbar ToolBar
fatal: renaming 'src/components/Toolbar' failed: Invalid argument
(If you're changing the capitalization of a single file, the
-f flag isn't necessary.)
I ended up using this Stack Overflow answer's approach instead.
➜ components git:(master) git mv Toolbar tmp
➜ components git:(master) ✗ git mv tmp ToolBar