74 lines
2.2 KiB
Markdown
74 lines
2.2 KiB
Markdown
---
|
|
title: "sudo git clone Makes Files Root-Owned — User git Pull Fails"
|
|
aliases:
|
|
- sudo-git-clone-root-files
|
|
- git-permission-denied-fetch-head
|
|
tags:
|
|
- git
|
|
- linux
|
|
- server
|
|
- permissions
|
|
sources:
|
|
- "daily/2026-04-30.md"
|
|
created: 2026-04-30
|
|
updated: 2026-04-30
|
|
---
|
|
|
|
# sudo git clone Makes Files Root-Owned — User git Pull Fails
|
|
|
|
Running `sudo git clone` on a server creates every file and directory — including the entire `.git/` folder — owned by `root`. Any subsequent `git pull` or `git fetch` run as a regular user fails with `Permission denied` on `.git/FETCH_HEAD` (or similar index files), even though the user can read the working tree.
|
|
|
|
## Key Points
|
|
|
|
- `sudo git clone` → all files owned by `root:root`
|
|
- `git pull` as a non-root user hits a write permission error on `.git/FETCH_HEAD`
|
|
- The error message looks like a network or credential issue but is purely a filesystem ownership problem
|
|
- Fix: `sudo chown -R $USER:$USER /opt/project`
|
|
- Prevention: never use `sudo` for `git clone` unless the repo must be root-owned
|
|
|
|
## Details
|
|
|
|
### The Error
|
|
|
|
```
|
|
error: cannot open .git/FETCH_HEAD: Permission denied
|
|
```
|
|
|
|
or
|
|
|
|
```
|
|
fatal: Unable to create '/opt/project/.git/index.lock': Permission denied
|
|
```
|
|
|
|
### Fix
|
|
|
|
```bash
|
|
sudo chown -R $USER:$USER /opt/project
|
|
# Verify
|
|
ls -la /opt/project/.git/
|
|
```
|
|
|
|
### Prevention
|
|
|
|
If deploying to `/opt/` or `/srv/` (root-owned dirs), create the directory first, then clone as the service user:
|
|
|
|
```bash
|
|
sudo mkdir -p /opt/project
|
|
sudo chown deploy:deploy /opt/project
|
|
git clone git@github.com:org/project.git /opt/project
|
|
```
|
|
|
|
Or use `sudo -u deploy git clone ...` to clone as the deploy user directly.
|
|
|
|
### Why This Happens
|
|
|
|
`sudo` switches the effective UID to root. `git clone` creates all files with the current effective UID as owner. There is no `--chown` flag on `git clone`, unlike `docker cp`.
|
|
|
|
## Related Concepts
|
|
|
|
- [[wiki/concepts/monorepo-deploy-script-pitfall]] — another class of silent git failure during deploys
|
|
- [[wiki/concepts/python-service-deployment-dotenv]] — deploy checklist for Python services
|
|
|
|
## Sources
|
|
|
|
- [[daily/2026-04-30.md]] — Session 12:11, re-deploy after project folder deletion; sudo git clone footgun discovered
|