Git Error: Unable to Unlink Old <FILE> -- Permission Denied

A branch management error that can seemingly come out of nowhere. Don't worry, there's an easy fix for this one. The key may be in understanding the real power of Sudo in Linux.

TL;DR -- check file permissions; on Linux?--maybe don't use Sudo with Git!

This error is almost definitely a permissions issue. In my case, outlined herein, the problem stemmed from a blatant abuse of sudo. Let's break it all down.

On certain occasions, it can be a strong temptation to use Sudo as a fix-for-all. In the normal process of development, Git can occasionally get hung up for reasons not outwardly evident; sometimes, rather than actually take the time to understand the complexities of Git, it's easier to just force your way through it. Sudo, at it's face, would seem like just another tool for coercing Git into compliance with your busy workflow. If you've been on the Linux command-line for any amount of time, you'll know that Sudo is a valuable tool for 'forcing' certain tasks. In the case of Git, however, it's anything but that. Here's why...

Sudo at a Glance

From the get go, you need to understand that Linux systems limit the power of users by default. There's your user profile, and then there's the ROOT profile. This may not be a semantically accurate description of ROOT, but you can think of ROOT as a "super user" on your computer: a user profile that has access to anything and everything. With that said, there will be times when you need to assume the role of this super user--i.e., your user profile simply doesn't have the permissions necessary to get something done. Here's a classic example: there's a file you'd like to edit, but you don't have write access on the file (you open the file in an editor, but it doesn't want to save). Changing file permissions aside, if you'd like to overcome this, the easiest way to get past this is to use Sudo. 

An important note: on any Linux system, there will be files that belong to you (usually located within your user folder just below /home), and there will be files that belong to ROOT (often above the ~/user folder).

Why not Sudo with Git?

We'll take a look at what happens, but let's start with how you might find yourself wanting to use Sudo with Git.

I don't recall the exact cause, but I do recall that one day I was trying to check out a local branch on my local machine: I think I was looking to get back onto Master (now known outside Acquia hosting as Main) from some branch I was fooling around with. When I ran git checkout master, Git gave me some business about not having the permissions necessary to unlink files. I thought to myself, "wierd!?" and proceeded to stare at my terminal just long enough to loosely connect these permission problems with past use of Sudo completely unrelated to web work. "Could it be that my user profile somehow has lost permission to use Git?"--I pondered.

Being in the hurry that I always am, I didn't take much time to read the actual output staring me in the face on my terminal. I said to myself, "let's try Sudo" and see if that works: sudo git checkout master. Sure enough, I find myself on master, and I get on with my day: "sharks don't look back because they have no necks; necks are for sheep!"

I felt somewhat accomplished for all of a few days, when suddenly the problem showed up again. And then it showed up again, and again, and again--to the point that I was suddenly using Sudo for just about everything I did with Git. Here's a look at a more recent incident--going to pull a branch of Drupal module updates from remote, I hit the same problem:

a permission error on the git command line
Git... why hast though forsaken me?

I'm sick and tired of this... let's figure this out.

A GitKraken permissions error
If you're using GitKraken for workflow management, you'll get a similar error to what you see on the command-line. Arguably, "could not open '/pathto/file' for writing: Permission denied" is a bit more descriptive. Good on GitKraken! I don't use this application as much as I should!

Unlink in this case means overwrite/delete. The permission denied comment is attached to each individual file. What if I was tremendously wrong? What if this has nothing to do with my user profile having permission to use Git? What if, like the output suggests, it has everything to do with file permissions? AHA!

As with just about every other problem I've ever had, there's a StackOverflow thread dealing with this. What's the consensus there?--Git can't overwrite the local files with whatever is coming in from remote because my user profile doesn't own the files in question. Why wouldn't I own the files in question? After all, the entire codebase resides under /home/terracoders/Sites. This is what happens when you use Sudo in git; per this little gem of an answer at AskUbuntu, you change the owner of whatever files you're working with to ROOT.

Let's go cd into the google_tag folder and see what's going on:

show the permissions on the contents of the google tag folder
... and... there you have it!

Engage British accent: "What have you done!?"

Yeah. I'll admit it. I was a dunce to use Sudo in the first place--it was a knee jerk reaction to a problem I didn't have time to think through. But, as with all of my mistakes, I generally take a step back and remind myself it's all part of the process. Sometimes you just have to screw it all up before you can grow as a developer. Once you remember what Sudo is actually used for, it makes perfect sense. I also gain a little solace in the fact that I'm not the only one out there to have made this mistake.

What we need here is to get the correct ownership on these files and folders. As a one off fix for this specific pull, I can cd into the parent directory for the google_tag folder and recursively change the ownership. Ironically, I'll have to use Sudo to do it. It will look something like this:

use c-h-own to recursively give a folder the correct owner
Problem solved!

After this quick ownership change, sure enough I was able to pull down that branch from remote. Go figure. If you've screwed up various files and directories the way I have, you may need to change permissions/ownership on your Drupal root (recursively--i.e., $ sudo chown -R user:group /path/to/drupal/root).

We're beginning to scratch the surface of a much larger issue: who exactly should site files belong to? Git obviously has problems when they belong to root, but the answer here isn't exactly cut and dry. It can depend on quite a lot of factors: i.e., where the docroot is located, whether you're running a traditional LAMP stack, whether you're running MAMP, and whether or not you're using middle-men like Drush to manage your site. You'll want to be sure to reference the documentation for your specific application.