KhueApps
Home/DevOps/Fix Git error: fatal: unsafe repository (ownership mismatch)

Fix Git error: fatal: unsafe repository (ownership mismatch)

Last updated: October 07, 2025

What this error means

Git 2.35+ added a safety check (in response to CVE-2022-24765) that blocks operations in repositories whose ownership does not match the current user. You’ll see:

  • fatal: unsafe repository ('…' is owned by someone else)
  • fatal: unsafe repository (ownership mismatch)

This prevents accidental code execution from untrusted repos on shared machines. You must either align ownership or explicitly mark the repo as safe.

Quickstart (most common fixes)

  • If you trust the repo and want to “bless” a path for your user:
# Add the current directory as safe for your user
git config --global --add safe.directory "$(pwd)"
  • Fix real ownership on Linux/macOS:
sudo chown -R "$USER":"$(id -gn)" /path/to/repo
  • Fix real ownership on Windows (PowerShell, run as Administrator if needed):
# Replace C:\path\to\repo with your path
icacls "C:\path\to\repo" /setowner "$env:USERNAME" /T
  • Avoid the risky wildcard unless you control the machine:
# Trust all repositories for this user (NOT recommended on shared hosts)
git config --global --add safe.directory '*'

Minimal working example (reproduce and fix)

# Linux/macOS demo: create repo as root, then use as a normal user
sudo bash -c '
  rm -rf /tmp/unsafe-demo && mkdir -p /tmp/unsafe-demo && cd /tmp/unsafe-demo && \
  git init && echo hello > a.txt && git add . && git commit -m "init" >/dev/null
'

# Now as your normal user
cd /tmp/unsafe-demo
# This will likely print: fatal: unsafe repository (ownership mismatch)
 git status

# Fix 1: change ownership (preferred when you own the machine)
sudo chown -R "$USER":"$(id -gn)" /tmp/unsafe-demo

# or Fix 2: bless the directory for your user
# git config --global --add safe.directory /tmp/unsafe-demo

git status  # works now

Step-by-step resolution

  1. Confirm your Git version
git --version

If 2.35+ you may hit this check. Upgrading is fine; just configure ownership or safe.directory.

  1. Inspect repository ownership
  • Linux/macOS:
stat -c '%U:%G %n' .
# or
ls -ld . .git
  • Windows (PowerShell):
(Get-Acl .).Owner
  1. Decide on a fix
  • Preferred: make the actual filesystem owner match the user who runs Git.
  • Alternative: declare the repo path safe for your user via safe.directory.
  1. Apply the fix
  • Linux/macOS: chown the repo or add safe.directory.
  • Windows: adjust owner using icacls/takeown, or add safe.directory.
  1. Verify
git config --global --get-all safe.directory
git status
  1. If the path is symlinked, use the real canonical path in safe.directory. Example:
git config --global --add safe.directory "$(realpath .)"

Commands by platform

  • Linux/macOS (preferred real fix):
sudo chown -R "$USER":"$(id -gn)" /path/to/repo
  • Windows (PowerShell):
# Ensure you own the directory
icacls "C:\path\to\repo" /setowner "$env:USERNAME" /T
# or, if needed
# takeown /F "C:\path\to\repo" /R /D Y
  • Mark path as safe (user-level):
git config --global --add safe.directory /absolute/path/to/repo
  • Mark all repos safe for your user (use only on fully trusted machines):
git config --global --add safe.directory '*'
  • System-wide (requires admin; affects all users):
sudo git config --system --add safe.directory /absolute/path
  • Remove/clean entries:
git config --global --get-all safe.directory
git config --global --unset-all safe.directory
  • Find where a setting came from:
git config --list --show-origin | grep safe.directory

Common scenarios and fixes

  • Used sudo with Git inside your home

    • Symptom: files or .git owned by root.
    • Fix: chown the repo back to your user, avoid sudo with Git in project trees.
  • WSL or dual-boot accessing Windows files from Linux

    • Symptom: repo under /mnt/c has ownership mapped oddly.
    • Fix: keep Linux Git repos inside your Linux home (e.g., ~/projects). Otherwise add safe.directory for the canonical /mnt/... path, or clone under WSL’s filesystem.
  • Docker bind mounts

    • Symptom: container user UID/GID differs from host; Git in container flags mismatch.
    • Fix options:
      • Run the container with host UID/GID: docker run -u $(id -u):$(id -g) ...
      • chown the mount inside the container at startup.
      • Add safe.directory for the mount path used in the container (e.g., /workspace).
  • CI runners (e.g., ephemeral build users)

    • Add during job init:
git config --global --add safe.directory "$PWD"
  • Network shares / SMB / NFS
    • Ownership may map to different users.
    • Prefer local clones for build steps; otherwise add a precise safe.directory entry per share path.

Pitfalls to avoid

  • Blindly using safe.directory '*': convenient but dangerous on shared systems; it trusts all repos.
  • Configuring safe.directory inside a repository config: ignored by design; use global or system scope.
  • Relying on symlinked paths: Git matches canonical paths; configure the resolved absolute path.
  • Mixing tools: running some commands as Administrator/root and others as a normal user leads to churn in ownership.

Performance notes

  • The safe.directory check is a fast metadata lookup; it rarely affects performance on local disks.
  • On remote filesystems (NFS/SMB), metadata calls can be slower and ownership mapping inconsistent. Cloning to a local disk often speeds up builds and avoids false mismatches.
  • In CI and Docker, repeated recursive chown -R can be expensive. Prefer aligning UIDs (docker run -u) or mounting volumes with correct ownership to avoid chown in every job.

FAQ

  • Why did this start happening now?

    • Newer Git versions enforce repo ownership for safety.
  • Is it safe to use safe.directory '*'?

    • Only on machines you fully control. It disables the protection for your user.
  • Can I disable the check entirely?

    • Not directly; the supported approach is safe.directory. Using '*' effectively disables it for your user but is discouraged.
  • Can I set safe.directory in .git/config?

    • No. Git ignores it there because the repo itself is untrusted. Use global or system config.
  • How do I list what’s trusted?

    • git config --global --get-all safe.directory
  • Does this apply to bare repos?

    • Yes. Ownership is checked for any Git repository directory.

Series: Git

DevOps