Git Error: Unable to create index.lock

Here's an error I recently came accross in Git when trying to push a commit. If Git is giving you something about being unable to create the index.lock file, it's likely you have a git process running in the background that needs to be resolved before git can move forward.

I was doing some routine updates to Drupal modules today when I got a rather peculiar error: git was unable to create a file called 'index.lock'. I don't know what a lock file is, or why Git even needs to create one, so it caught me by surprise. Reviewing my own terminal, though, and after consulting a thread over at Stack Overflow, It's all clear to me how I ended up where I did. In the end, I fell into the ever enduring trap of not listening to my terminal. Let's start at the beginning, though. Here's how I managed to find myself with this error:

How to make a commit:

I make commits without using Git's default text editor for my commit message--that is, I usually make my messages inline. I've long done this because command line text editors often require memorizing a set of unique commands that differ from OS defaults (such as ctl-s to save). Memorizing all of the git-specific commands alone is more than enough stress on the brain--why bother with anything more? So this is how I usually do my commits:

$ git commit -a -m 'this is my commit message' 

Now, it just so happens that every now and then, I fumble on my keyboard and mistype my entry. Today, I accidentally hit return before I got to the inline message:

$ git commit -a

Many of you will know that if you don't give your commit message inline, Git will open your default command line editor and ask for your commit message either way. In my case, I set Git to default to Nano (which I find more intuitive than Vi, Vim, or even Emacs). Without the inline commit message, I suddenly found myself staring at a Nano edit screen. Now, I've had enough experience with Nano to know how to save a file and exit the program. Under normal circumstances, saving a commit message and exiting the editor will simply bring you back to the command prompt, at which point you can proceed with a push. As is occasionally the case though, I was so focused on getting to the push that I didn't take notice of the output once I had exited Nano:

$ git commit -a
Use "fg" to return to nano.

[1]+  Stopped                git commit -a
$

This should have been the first red flag. The commit obviously didn't finish, and I was being prompted to return to Nano. Blissfully ignorant, I went ahead and made my push. The push went as expected (you don't have to finish your commit to push--Git just pushes everything that's already committed), so I moved on to checkout another branch for a merge. That's when I got the following error:

$ git checkout some-branch
fatal: Unable to create 'project_path/.git/index.lock': File exists.

If no other git process is currently running, this probably means a
git process crashed in this repository earlier. Make sure no other git
process is running and remove the file manually to continue.

Whaaaaaaaaaaat?

This should have been the second red flag--although, the wording in the error could have been better. It should probably read a little more like this: "A git process is probably running in the background and hasn't been terminated. If not, this may mean a git process crashed in this repository earlier..." The bit about ensuring that no other git process is running is the real point, though. Again, if you don't actually read the output on your terminal, you can get a bit turned around. At this point, I probably could have put 1 and 1 together and should have realized that there was a problem with my commit message--namely, that Nano was still running in the background, and that I hadn't actually finished my commit (a git status would have confirmed this as well). Failing to engage with my terminal, though, I went straight to Stack Overflow (via DuckDuckGo). The thread I found had no "accepted" answer, but there were several suggestions to simply remove the index.lock file. A few, however, had suggested heeding the words of the error and confirming whether any git processes were running. Here's what I got:

$ ps -ef | grep git
dhmpsan+ 13825 13708  0 18:03 pts/1    00:00:00 git commit -a
dhmpsan+ 13846 13825  0 18:03 pts/1    00:00:00 editor /project_path/.git/COMMIT_EDITMSG
dhmpsan+ 15188 13708  0 18:09 pts/1    00:00:00 grep git

And now it all starts to come together. My commit and my commit message are both still running. One solution would be to simply kill the processes; a better solution might be to finish them out, though. I must have exited Nano without actually terminating the application (more on that in a bit); had I actually finished my commit message, the commit process also would have resolved and everything would be hunky dory. Probably best to go finish that commit message. If you pay close attention to the processes listed above, you can see that the commit message is being stored by Git in a file called COMMIT_EDITMSG. Let's open that with Nano and see if we can't finish it out. After navigating to your .git folder, open the file with your editor:

$ nano COMMIT_EDITMSG

You should get something like this when you open Nano:

FILE COMMIT_EDITMSG is being edited (by servername with nano 2.5.3, PID 17212); continue?
Y Yes
N No      ^C Cancel

YES!!--edit it! Once you edit this, save and exit the text editor appropriately, the process should terminate and your index.lock file issue should be resolved. Interestingly enough, though, this didn't finish out the commit I had started earlier. It terminated the processes, but I still needed to commit once more. This time, I opted to add my commit message inline.

But... beyond not reading the output of my terminal, what was the cause of all this? How did I get out of Nano while it was still running?

Butterfingers: Ctl-X vs Ctl-Z in Nano

The X and Z keys are right next to each other on the keyboard. If you're not careful, you can hit Z when you intend to hit X. For Nano, that's a big difference. Ctl-X will exit you from the editor; Ctl-Z will put the current process in the background. Ctl-Z can give you the impression that you've left the application when in actuality you haven't. If you're the kind of person who actually listens to your terminal, you'll probably catch on to this. If you're whizing through your workflow, as I often do, you might find yourself in a pickle, though.