2.2 KiB
2.2 KiB
| title | aliases | tags | sources | created | updated | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| sudo git clone Makes Files Root-Owned — User git Pull Fails |
|
|
|
2026-04-30 | 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 byroot:rootgit pullas 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
sudoforgit cloneunless 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
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:
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