Running almost any Git command in the wrong place produces this:
fatal: not a git repository (or any of the parent directories): .git
The message is precise if you read it carefully. Git looked for a .git directory in your current directory, did not find one, walked up to the parent, checked again, and kept going all the way to the filesystem root — (or any of the parent directories) — without ever finding one. So it stopped.
The single most common cause is being in the wrong directory. Check that first:
pwd
ls -la
If you see a .git entry in the ls -la output, you are inside a repository and something else is wrong — skip to the later sections. If you do not, you are simply somewhere Git does not manage.
Why This Happens
Git identifies a repository by the presence of a .git directory at the repository root. Every command that touches history — status, add, commit, log, push, branch, rev-parse — needs to find it. The search runs upward only: from you toward /. It never looks down into subdirectories.
That upward-only rule explains most confused reports. If your project root is ~/code/myapp and you are sitting in ~/code, Git checks ~/code, then ~, then /home, then / — and never looks inside myapp.
The realistic causes:
- Wrong directory — you are above the project root, or in a different project entirely.
- Never a repository — the folder was downloaded as a ZIP rather than cloned, so there is no
.gitat all. .gitwas deleted — an over-eager clean-up, or a copy operation that skipped hidden files.- Stale
.gitfile — in submodules and worktrees,.gitis a file pointing elsewhere, and the target moved. - Stripped in a container or CI job —
.dockerignoreexcluded it, or only source files were copied in.
Fix 1: Go to the Right Directory
# Where am I?
pwd
# Is there a .git here?
ls -la | grep '\.git'
# Move into the project
cd ~/code/myapp
git status
If you are not sure where the repository lives, search for it:
# macOS / Linux
find ~ -maxdepth 4 -name .git -type d 2>/dev/null
That lists the root of every repository within four levels of your home directory. The parent of each result is a repository root.
Fix 2: Clone the Project If You Never Had It
If the folder came from a downloaded ZIP or a file copy, it has source code but no history. There is nothing to repair — clone it properly:
git clone https://github.com/user/repo.git
cd repo
git status
Fix 3: Initialise a New Repository — Deliberately
If you genuinely want to start tracking a new project at this location:
git init
git add .
git commit -m "Initial commit"
Check
pwdbefore runninggit init. Running it in your home directory or/creates a repository whose working tree is everything below that point. Git then reports thousands of untracked files, and every command in every subfolder starts behaving strangely. It is one of the harder self-inflicted messes to notice.
If you have already done that, undo it by removing only Git's metadata:
pwd # confirm you are in the wrong repo, not a real one
rm -rf .git
Your files are untouched — .git holds history and configuration, nothing else.
Fix 4: Repair a Submodule or Worktree
Inside a submodule or a linked worktree, .git is a small text file rather than a directory:
cat .git
# gitdir: /Users/you/code/parent/.git/modules/mysubmodule
If that path no longer exists — the parent repository moved, or was deleted and re-cloned — Git cannot resolve the real repository and reports it as not a repository at all. Re-initialise from the parent:
cd /path/to/parent-repo
git submodule update --init --recursive
For a broken worktree, list and prune the stale registration, then add it again:
git worktree list
git worktree prune
git worktree add ../feature-branch feature-branch
Fix 5: Containers and CI
Inside a container, check whether the metadata made it in at all:
docker exec -it <container> ls -la /app
If .git is missing, look for .git in your .dockerignore — excluding it is a common and usually sensible image-size optimisation. It only becomes a problem when something in the build genuinely needs Git, such as a version string derived from git describe. In that case either stop excluding it, or pass the value in as a build argument instead:
ARG GIT_SHA
ENV APP_VERSION=$GIT_SHA
In CI, a shallow clone still produces a valid .git, so this error there usually means the job changed directory before running Git, or the checkout step was skipped for that job.
A Different Error Worth Knowing
If the message is not the one at the top of this page but instead:
fatal: detected dubious ownership in repository at '/path/to/repo'
that is a separate safety check, not a missing repository. It fires when the repo is owned by a different user than the one running Git — common with mounted volumes and CI runners. Fix it by declaring the path safe rather than by chowning files:
git config --global --add safe.directory /path/to/repo
Verify
Confirm you are inside a repository and find its root:
git rev-parse --show-toplevel
Inside a repository this prints the absolute path to the root. Outside one it prints the same fatal: not a git repository message, which makes it a reliable one-line test — useful in shell scripts:
if git rev-parse --show-toplevel >/dev/null 2>&1; then
echo "In a repo"
else
echo "Not a repo"
fi
Prevention
- Clone, do not download ZIPs, for anything you intend to commit to.
- Show hidden files in your file manager so
.gitis visible and less likely to be lost in a copy. - Use
cp -arather thancp -rwhen duplicating a project directory, so hidden files come along. - Put the repository name in your shell prompt. Most prompt frameworks show the current branch, which disappears the moment you leave the repository — an instant visual signal that you are outside it.