Fix: fatal: not a git repository (or any of the parent directories): .git

The Error

You run a Git command — git status, git log, git add, git commit, or anything else — and get:

fatal: not a git repository (or any of the parent directories): .git

You may also see shorter variations:

fatal: not a git repository

Or when running a Git command from a script or tool:

fatal: not a git repository (or any of the parent directories): .git
fatal: could not read from remote repository.

Some tools and wrappers produce their own messages on top of this error:

Error: fatal: not a git repository (or any of the parent directories): .git
The process exited with code 128.

No matter the exact wording, the cause is the same: Git cannot find a .git directory in the current directory or any parent directory above it.

Why This Happens

Every Git repository has a hidden .git directory at its root. This directory contains the entire history of your project — all commits, branches, configuration, hooks, and object data. When you run any git command, Git looks for this .git folder in the current working directory. If it doesn’t find one, it walks up the directory tree checking each parent directory. If it reaches the filesystem root (/ on Linux/macOS, C:\ on Windows) without finding .git, it gives up and prints this error.

This means one of the following is true:

  • You’re in the wrong directory. Your terminal’s working directory isn’t inside a Git repository.
  • The repository was never initialized. You created a project folder but never ran git init or git clone.
  • The .git directory was deleted. Something removed the .git folder — an overly aggressive cleanup script, a manual deletion, or a file sync tool.
  • You’re inside a submodule or worktree with a broken link. The .git reference file points to a location that no longer exists.
  • Your CI/CD pipeline or script changed directories before running Git commands.

Fix 1: Navigate to the Correct Directory

The most common cause is simply being in the wrong folder. Check where you are:

pwd

Then list the contents to see if .git exists:

ls -la | grep .git

If there’s no .git directory, you’re not in a Git repository. Navigate to the right one:

cd /path/to/your/project
git status

If you’re unsure where your repository is, search for it:

# Linux / macOS
find ~ -name ".git" -type d 2>/dev/null

# Windows (Git Bash)
find /c/Users/YourName -name ".git" -type d 2>/dev/null

This searches your home directory for any .git folders and prints their paths. The parent of each .git directory is a repository root.

Fix 2: Initialize a New Repository with git init

If you created a project folder but never turned it into a Git repository, initialize it:

cd /path/to/your/project
git init

This creates the .git directory and sets up an empty repository. You can now stage and commit files:

git add .
git commit -m "Initial commit"

If you also need to connect it to a remote repository on GitHub or GitLab:

git remote add origin https://github.com/username/repo.git
git push -u origin main

If you run into authentication issues when pushing, see Fix: Permission denied (publickey) for SSH troubleshooting.

Fix 3: Clone the Repository Instead

If the repository already exists on a remote server and you don’t have a local copy yet, clone it rather than manually initializing:

git clone https://github.com/username/repo.git
cd repo

This creates a new directory with the full repository history already set up. Make sure you cd into the cloned directory before running any Git commands — the clone command creates a subdirectory, and your terminal stays in the parent directory after cloning.

A common mistake is running git clone and then immediately running git status without changing into the new directory:

git clone https://github.com/username/repo.git
# Still in the parent directory — this fails:
git status
# fatal: not a git repository (or any of the parent directories): .git

# Fix: cd into the cloned repo first
cd repo
git status

Fix 4: Recover a Deleted .git Directory

If you accidentally deleted the .git folder, the project files are still there but all Git history is gone locally. Your options depend on whether a remote copy exists.

If you have a remote (GitHub, GitLab, etc.):

The safest approach is to re-clone the repository into a temporary directory and copy the .git folder back:

# Clone the repo into a temp directory
git clone https://github.com/username/repo.git /tmp/repo-recovery

# Copy the .git directory into your project
cp -r /tmp/repo-recovery/.git /path/to/your/project/.git

# Verify
cd /path/to/your/project
git status

git status will now show any differences between your working files and the last commit on the remote. You can review and commit any local changes you want to keep.

If you have no remote:

Without a remote and without the .git directory, the history is gone. You’ll need to start fresh:

cd /path/to/your/project
git init
git add .
git commit -m "Re-initialize repository after .git deletion"

To prevent this in the future, always push your work to a remote, and be careful with commands like rm -rf in your project root. If you had a stash saved before the deletion, that data lived inside .git and is also lost.

Fix 5: Fix Submodule Issues

Git submodules don’t have a full .git directory. Instead, they contain a .git file that points to the parent repository’s .git/modules/ directory. If that reference is broken, you’ll see the “not a git repository” error when working inside the submodule.

Check the .git file inside the submodule:

cat path/to/submodule/.git

It should contain something like:

gitdir: ../../.git/modules/path/to/submodule

If that path doesn’t exist or is wrong, the submodule is broken. Fix it by re-initializing submodules from the parent repository:

# From the parent repository root
git submodule deinit -f path/to/submodule
git submodule update --init --recursive

If the submodule directory is completely missing:

git submodule update --init --recursive

This re-clones all submodules and sets up the correct .git references.

Fix 6: Handle Bare Repositories

A bare repository is a repository without a working tree — it contains the contents of the .git directory directly, without wrapping them in a .git subfolder. Bare repositories are used on servers and for git push targets. They are not meant for everyday development work.

If you accidentally cloned with --bare:

git clone --bare https://github.com/username/repo.git

You’ll get a directory that looks like repo.git/ and contains files like HEAD, config, objects/, refs/ — but no working tree and no .git subdirectory. Running git status or git log from outside this directory fails with the “not a git repository” error, and from inside it you’ll get errors about not having a working tree.

To fix this, clone the repository normally (without --bare):

git clone https://github.com/username/repo.git
cd repo

If you need to convert a bare repository to a regular one:

mkdir repo
mv repo.git repo/.git
cd repo
git config --local --bool core.bare false
git checkout main

Fix 7: Fix Git Hooks and Aliases Running Outside a Repo

Git hooks and custom aliases sometimes fail with this error because they execute in an unexpected working directory. A hook script might change directories before running Git commands, or a shell alias might reference a path that doesn’t exist.

Hooks:

Check your hook scripts in .git/hooks/. If a hook uses cd to change directories, make sure it changes back or runs Git commands against the correct path:

# In a hook script, always use the repo root
REPO_ROOT=$(git rev-parse --show-toplevel)
cd "$REPO_ROOT"

Aliases:

If you have a custom Git alias in ~/.gitconfig that runs a shell command, make sure it doesn’t assume a specific working directory:

[alias]
    # Bad: assumes you're in a repo
    deploy = !cd /some/other/path && git pull

    # Good: saves and restores the directory context
    deploy = !git -C /path/to/deploy-repo pull

The -C flag tells Git to run as if it were started in the specified directory. This is useful when your alias or script needs to operate on a different repository.

If you encounter permission issues when running hook scripts, see Fix: bash permission denied for troubleshooting executable permissions.

Fix 8: Fix IDE / Editor Terminal Path

Many developers use the integrated terminal in VS Code, IntelliJ, or other editors. The terminal’s working directory depends on how you opened the editor.

VS Code:

If you opened a single file instead of a folder, the integrated terminal might open in your home directory or a system path — not your project root. Fix this by opening the correct folder:

  1. File > Open Folder (not “Open File”)
  2. Select your Git project root
  3. Open a new terminal (Terminal > New Terminal)

The terminal’s starting directory will match the folder you opened.

You can also verify and change the directory manually:

pwd
cd /path/to/your/project
git status

IntelliJ / WebStorm / other JetBrains IDEs:

The terminal defaults to the project root defined when you opened the project. If you have a multi-module project, the terminal might open in a parent directory that isn’t a Git repo. Use cd to navigate to the correct module, or configure the terminal’s starting directory in Settings > Tools > Terminal > Start directory.

Sublime Text / other editors:

Editors without built-in project concepts may open the terminal in unpredictable directories. Always check pwd before running Git commands.

Fix 9: Fix CI/CD Pipeline Working Directory

CI/CD pipelines in GitHub Actions, GitLab CI, Jenkins, and other systems often run steps in a specific working directory. If a step changes directories or the checkout action didn’t run, Git commands fail.

GitHub Actions:

The actions/checkout step clones your repository into $GITHUB_WORKSPACE. If you skip the checkout step or change directories afterward, Git commands won’t work:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      # This step is required — without it, there's no repo
      - uses: actions/checkout@v4

      # Git commands work here because the working directory
      # is the repo root
      - run: git status

      # If you cd somewhere else, git commands may fail
      - run: |
          cd /tmp
          git status  # fatal: not a git repository

If a step needs to run in a different directory, use the working-directory key to control it explicitly:

      - name: Run tests
        working-directory: ./packages/my-app
        run: npm test

If your GitHub Actions workflow is failing with exit codes, see Fix: GitHub Actions process completed with exit code 1 for common solutions.

GitLab CI:

GitLab CI clones into $CI_PROJECT_DIR. Make sure your scripts don’t navigate out of this directory, or use cd $CI_PROJECT_DIR to return:

build:
  script:
    - cd $CI_PROJECT_DIR
    - git status

Jenkins:

Jenkins pipelines use checkout scm to clone the repository. The working directory is usually the Jenkins workspace. If you use dir() or sh 'cd ...' in your pipeline, make sure Git commands run within the checked-out repo:

pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                checkout scm
                sh 'git status'
            }
        }
    }
}

Fix 10: Resolve Windows Path Issues

Windows introduces several path-related problems that can cause this error.

Mapped network drives:

If your repository is on a mapped network drive (e.g., Z:\projects\repo), Git may not recognize it. Use the UNC path instead:

cd //server/share/projects/repo
git status

Long paths:

Windows has a 260-character path limit by default. If your repository is deeply nested, Git may fail to find .git. Enable long paths in Git:

git config --global core.longpaths true

And enable long paths in Windows (requires admin privileges and a restart):

reg add "HKLM\SYSTEM\CurrentControlSet\Control\FileSystem" /v LongPathsEnabled /t REG_DWORD /d 1 /f

OneDrive / Dropbox / Google Drive sync conflicts:

Cloud sync tools sometimes interfere with the .git directory. They can lock files, rename them with conflict suffixes, or skip syncing certain files. This corrupts the repository structure and can cause Git to not recognize the directory as a repository.

The safest approach is to not store Git repositories inside synced cloud folders. Instead, keep them in a regular local directory and use git push to back up your work to a remote. If you need to move a project out of a synced folder:

mv /c/Users/YourName/OneDrive/project /c/Users/YourName/projects/project
cd /c/Users/YourName/projects/project
git status

WSL vs Windows path mismatches:

If you initialized a repository in Windows but try to access it from WSL (or vice versa), Git may not find the .git directory because of path translation issues. Repositories in WSL should use the Linux filesystem (/home/user/project), and repositories in Windows should use the Windows filesystem (/mnt/c/Users/YourName/project from WSL, or C:\Users\YourName\project from cmd/PowerShell). Mixing the two causes performance issues and sometimes path resolution failures. If you encounter environment variable issues across WSL and Windows, see Fix: environment variable undefined for guidance.

Still Not Working?

Corrupted .git directory

Sometimes the .git directory exists but is corrupted — missing critical files like HEAD or config. Check if these files exist:

ls -la .git/HEAD .git/config .git/refs .git/objects

If HEAD or config is missing, Git won’t recognize the directory as a repository even though .git exists. If you have a remote, re-clone and recover using the method in Fix 4. If you don’t, you can try to repair it:

# Recreate a missing HEAD file
echo "ref: refs/heads/main" > .git/HEAD

# Run a filesystem check
git fsck --full

GIT_DIR or GIT_WORK_TREE environment variables

If the GIT_DIR or GIT_WORK_TREE environment variables are set, Git uses those paths instead of searching for .git in the current directory. This can cause confusing behavior when the variables point to the wrong location or a non-existent path.

Check if they’re set:

echo $GIT_DIR
echo $GIT_WORK_TREE

If either one is set and you don’t need it, unset them:

unset GIT_DIR
unset GIT_WORK_TREE
git status

If these are set in your shell profile (~/.bashrc, ~/.zshrc), remove or fix the lines that set them.

Git not installed or not in PATH

On some minimal systems or containers, Git may not be installed. Verify:

git --version

If this returns “command not found,” install Git for your platform. On CI/CD containers, make sure the image includes Git or add an installation step.

Filesystem is case-sensitive but the path isn’t matching

On case-sensitive filesystems (common on Linux), /path/to/Project and /path/to/project are different directories. Make sure you’re using the exact casing of your repository path.

# This might fail on case-sensitive systems if the actual directory is "MyProject"
cd /home/user/myproject

Safe directory restrictions (Git 2.35.2+)

Git 2.35.2 introduced a security fix that prevents Git from operating in repositories owned by a different user. While the error message is usually different (unsafe repository), some configurations can cause Git to report “not a git repository” instead.

If you’re working in a directory owned by another user (common in Docker containers where the repo is mounted as a volume), add it to the safe directories list:

git config --global --add safe.directory /path/to/repo

In Docker, this is a frequent issue because the container user and the host user have different UIDs. Add a wildcard to trust all directories (only do this if you understand the security implications):

git config --global --add safe.directory '*'

Related: Fix: Permission denied (publickey) · Fix: git stash pop conflicts · Fix: GitHub Actions exit code 1

Related Articles