How to Fix Git 'Permission Denied' error


git config --listThe output should look something like the following screenshot
sudo chown -R $USER:$USER .gitHere
$USERis your username of ubuntu/ windows.
git commit -m "your message" Boom 💥— you’re done.
While working inside WSL (Windows Subsystem for Linux), I ran into this annoying error while trying to commit my Frappe app code:
fatal: could not open '.git/COMMIT_EDITMSG': Permission deniedAt first, it looked like a random Git glitch.
But it turns out it was me — I had previously run a Git command with sudo, and WSL dutifully created a few .git files owned by root.
That one small mistake locked me out from writing new commit messages.
In WSL, file ownership behaves like a regular Linux system.
When you use sudo inside your project folder, all files Git touches (like .git/config, index, COMMIT_EDITMSG) become owned by root.
Later, when you try to run normal Git commands as your normal user, WSL politely says:
“Permission denied.”
It’s not Git’s fault — it’s Linux being strict about file ownership.
ls -l .gitYou’ll see the output something like:
-rw-r--r-- 1 root root 52 Nov 12 02:28 COMMIT_EDITMSG
-rw-r--r-- 1 root root 101 Nov 12 22:56 FETCH_HEAD
...means:
There’s a file named COMMIT_EDITMSG that is owned by root, only root can edit it (others can only read it), and it was last modified on Nov 12 at 2:28 AM.
Here’s what each part means 👇
| Section | Example | Meaning |
|---|---|---|
| File permission | -rw-r--r-- | This shows who can read or write the file. • r = read, w = write, x = execute. • The first rw- means the owner can read/write. • The next r-- means the group can only read. • The last r-- means others can only read. |
| Number of links | 1 | How many links (copies or references) point to this file. You can ignore this for now. |
| Owner name | root | The user who owns the file. Here, root = the system’s admin user. |
| Group name | root | The group that owns the file — also root here. |
| File size | 52 | File size in bytes. (So 52 bytes = a tiny text file.) |
| Last modified date | Nov 12 02:28 | The date and time when this file was last changed. |
| File name | COMMIT_EDITMSG | The actual name of the file. |
Run this inside your repo:
Here
$USERis your username of ubuntu/ windows.
sudo chown -R $USER:$USER .gitWhich means:
“Give ownership of all .git files back to me.”
If you want to fix everything in your bench or project folder:
sudo chown -R $USER:$USER ~/frappe-benchls -ld .gitYou should see:
drwxrwxr-x ... sab sab ...means:
“This is a directory owned by user sab. The owner and their group can read, write, and read it. Other users can only read and open it, but not modify it.”
| Symbol | Meaning |
|---|---|
| d | directory (folder) |
| - | normal file |
| l | symbolic link |
| r | read |
| w | write |
| x | execute (or enter, for folders) |
git commit -m "fix: corrected social link fields and updated b_event script"âś… It should now work flawlessly.
sudo gitThis is the real lesson.
Never use sudo with Git — not even once — unless you absolutely need to modify system-level repositories.
In a dev setup (especially WSL), you should always:
sudo unless it’s for system-level tasks If you often work in multiple apps inside frappe-bench:
cd ~/frappe-bench/apps
for app in */; do sudo chown -R $USER:$USER "$app/.git"; doneThat’ll recursively fix ownership for all apps in one go.
| Problem | Cause | Fix |
|---|---|---|
fatal: could not open '.git/COMMIT_EDITMSG': Permission denied | You ran sudo git and .git files became owned by root | sudo chown -R $USER:$USER .git |
| Can’t push or pull without password | SSH key not configured | Use ssh-keygen and add to GitHub |
| Ownership issues across bench | Mixed sudo operations | Fix all with a for-loop or chown bench |
WSL is amazing — but it plays by Linux rules.
Once you stop mixing sudo with normal Git operations, life gets much smoother.
So next time you see “Permission Denied,” remember:
It’s not Git being stubborn — it’s just protecting your house keys from the wrong user. 🔑

Learn how to check and set your Git user.name and user.email for all projects (global) or a single repo (local). Fix your GitHub commit identity.

 Learn why the Frappe framework's built-in reporting is a game-changer. See how to customize, group, and save reports instantly

Learn how to use Frappe's Assignment Rule DocType to automate document assignments. Explore Round Robin, Load Balancing, and custom Python rules.