Overview
The error “fatal: not a git repository (or any of the parent directories): .git” means Git can’t find a repository root (a .git directory) starting from your current folder and walking up the directory tree.
Common causes:
- You’re in the wrong directory.
- The .git directory is missing, corrupt, or moved.
- Environment variables (GIT_DIR, GIT_WORK_TREE) are misconfigured.
- You’re inside a submodule or worktree without proper setup.
- Permissions or path issues (CI, containers, network mounts).
This guide shows quick fixes and deep-dive steps tailored for DevOps workflows and Git usage in CI/CD.
Quickstart (most cases)
- Confirm if you’re inside a repo:
git rev-parse --is-inside-work-tree # prints 'true' if in a repo
- If not in a repo, either change directory to your project root or initialize one:
cd /path/to/your/project
# If this project should be a repo but isn't initialized
git init
- If the repo used to exist but .git is missing or corrupted, reclone or restore from backup:
cd ..
rm -rf project && git clone <remote-url> project
- If scripts or CI jobs set Git env vars, clear them:
unset GIT_DIR GIT_WORK_TREE
Minimal working example
Reproduce the error and fix it quickly:
# 1) Create a fresh directory and run a Git command
mkdir -p /tmp/demo && cd /tmp/demo
git status
# -> fatal: not a git repository (or any of the parent directories): .git
# 2) Initialize a repository and try again
git init
# Initialized empty Git repository in /tmp/demo/.git/
git status
# On branch master (or main)
# No commits yet
# nothing to commit (create/copy files and use "git add" to track)
Step-by-step diagnosis and fixes
- Verify your location and the repo root
- Print current directory and list hidden files:
pwd
ls -la
- Is there a .git directory? If not, you’re not in a Git repo here.
- If unsure where the repo root is, try moving up directories or use:
git rev-parse --show-toplevel # succeeds only inside a repo
- Initialize or re-clone when appropriate
- New project: run git init in the project root.
- Existing project: clone it instead of copying files without .git:
git clone <remote-url> project && cd project
- Check for misconfigured Git environment variables
- These override repo discovery and can cause this error from valid paths:
echo ${GIT_DIR:-unset} ${GIT_WORK_TREE:-unset}
unset GIT_DIR GIT_WORK_TREE
- In CI, ensure job steps don’t export GIT_DIR or GIT_WORK_TREE incorrectly.
- Diagnose worktrees
- If using git worktree, a secondary working tree has a .git file (not a directory) pointing to the real metadata.
- Validate worktrees:
git worktree list # run from a known-good repository root
- If you moved or deleted the main repo, the worktree pointer can break. Recreate the worktree or re-clone.
- Handle submodules correctly
- Running Git inside a submodule path without initializing submodules can fail. Initialize and update:
git submodule update --init --recursive
- Ensure you’re inside the submodule folder when operating on it, or run commands from the superproject.
- Restore a missing or corrupted .git
- If .git was accidentally deleted, you generally must re-clone. If you have a backup of .git, restore it:
# Stop processes using the repo, then restore
rsync -a /backup/myproj/.git/ /path/to/myproj/.git/
- Minimal .git should include HEAD, config, and objects/ refs/ trees. If these are missing, re-clone.
- Fix permissions and ownership
- In containers, with sudo, or network shares, .git may be unreadable:
# Adjust to your user/group
sudo chown -R "$USER":"$USER" .git
chmod -R u+rwX .git
- Avoid mixing root and non-root operations against the same working copy.
- Validate the filesystem and path specifics
- On Windows/WSL or macOS, watch for case sensitivity and path translation issues.
- Ensure the path actually exists in the container (volume mounts) and that the .git directory is not excluded by build contexts.
- Confirm Git can see the repo
- From the intended working directory, these should succeed:
git rev-parse --git-dir
git status
- If they fail, you’re not in a valid repo or discovery is blocked.
CI/CD and scripting considerations
- Always cd into the repository before running Git commands:
cd "$GITHUB_WORKSPACE" # or $CI_PROJECT_DIR, etc.
git status
- For Docker builds, copy .git if you need version metadata, or mount it:
docker run -v "$PWD":"/src" -w /src alpine/git git rev-parse --short HEAD
- Avoid setting global GIT_DIR/GIT_WORK_TREE in CI environments. Prefer per-step working directories.
Pitfalls to avoid
- Running git init inside nested directories of an existing repository (creates confusing nested repos).
- Copying code without the .git directory, then expecting history to exist.
- Using sudo for some Git operations and not others (ownership drift).
- Deleting or moving the main repository while worktrees still reference it.
- Forgetting to initialize submodules in fresh clones.
- Leaving GIT_DIR or GIT_WORK_TREE exported in your shell profile.
Performance notes
- Git discovers repositories by walking up parent directories. Running Git from deep paths under $HOME or / can be slow.
- Speed up discovery by running commands from the project root when possible.
- For very deep directory structures, consider setting GIT_CEILING_DIRECTORIES to limit how far Git walks:
export GIT_CEILING_DIRECTORIES="$HOME"
- Avoid scanning huge workspaces in CI; cd directly to the repo directory before running Git.
Troubleshooting checklist
- Am I in the right directory? pwd; ls -la.
- Does .git exist here or in a parent directory? ls -la; git rev-parse --show-toplevel.
- Are GIT_DIR/GIT_WORK_TREE unset? echo and unset them.
- For clones with submodules: git submodule update --init --recursive.
- Using worktrees? Validate with git worktree list; recreate if broken.
- Permissions OK? chown/chmod as needed.
- Still broken? Re-clone the repository cleanly.
FAQ
Q: Can I recover if .git was deleted?
- A: Without a backup, re-clone from the remote. Uncommitted work in the working tree may be salvageable, but history lives in .git.
Q: Why does it work in one terminal but not another?
- A: One shell likely has GIT_DIR or GIT_WORK_TREE set, or a different working directory.
Q: How do I check if I’m in a repo programmatically?
- A: Use git rev-parse --is-inside-work-tree and check for exit code 0 or output "true".
Q: Does nested Git repos cause this error?
- A: Not directly, but nested repos can confuse tooling. Avoid git init inside another repo unless intentionally using submodules or worktrees.