This error occurs when Git cannot locate or access the git directory for a submodule. The submodule's internal .git reference points to a path that doesn't exist or has become corrupted after moving, cloning, or branch switching.
The "fatal: Not a git repository" error in a submodule context indicates that Git cannot find or access the git metadata directory for one of your submodules. Unlike a regular "not a git repository" error (where you simply aren't in a git repo), this error specifically involves broken references between a submodule's working directory and its actual git data. In modern Git (1.7.8+), submodules don't contain a full `.git` directory. Instead, each submodule has a `.git` **file** that contains a `gitdir:` pointer to the parent repository's `.git/modules/<submodule-name>` directory. This design keeps all git data centralized in the parent repo while allowing submodules to function independently. When this pointer becomes invalid—due to moving the repository, incorrect cloning, switching branches with different submodule configurations, or filesystem corruption—Git cannot resolve the submodule's git directory and throws this error. The error message typically includes a path like `.git/modules/submodule_name` that Git is trying to access but cannot find.
First, confirm you're actually inside a git repository and not in a ZIP download or unrelated directory:
# Check if .git exists in current or parent directories
git rev-parse --git-dirIf this command fails, you're not in a git repository. If you downloaded a ZIP archive of the project:
# You need to clone the repository properly instead
rm -rf project-folder
git clone --recursive https://github.com/user/repo.git project-folderThe --recursive flag ensures submodules are also cloned.
If submodules haven't been initialized yet (common after a fresh clone without --recursive):
# Initialize and update all submodules recursively
git submodule update --init --recursiveIf a specific submodule is causing issues:
# Check the status of all submodules
git submodule status
# Initialize a specific submodule
git submodule init path/to/submodule
git submodule update path/to/submoduleThis fetches the submodule content and sets up the proper git directory structure.
If the submodule exists but is in a broken state, deinitializing and reinitializing often fixes the issue:
# Deinitialize the submodule (removes working tree but keeps .git/modules entry)
git submodule deinit -f path/to/submodule
# Reinitialize the submodule
git submodule init path/to/submodule
# Update to fetch content
git submodule update path/to/submoduleIf the error persists, you may need to also remove the cached modules directory:
# Remove the submodule's git directory from parent repo
rm -rf .git/modules/path/to/submodule
# Then reinitialize
git submodule init path/to/submodule
git submodule update path/to/submoduleIf you moved or renamed your repository directory, the absolute paths in submodule configuration may be broken. Find and fix these paths:
# Find all files with old path references
find .git -type f -name "config" -exec grep -l "old/path" {} \;
find . -name ".git" -type f -exec grep -l "old/path" {} \;The submodule's .git file contains a gitdir path. Check its contents:
# View the .git file in the submodule directory
cat path/to/submodule/.git
# Output: gitdir: ../../.git/modules/submoduleIf the path is incorrect (e.g., has the old directory name), fix it:
# Update the gitdir path (adjust the relative path as needed)
echo "gitdir: ../../.git/modules/submodule" > path/to/submodule/.gitAlso check the corresponding config in the parent's modules directory:
# Check the worktree path
cat .git/modules/submodule/config | grep worktreeUpdate it if necessary to point to the correct working directory.
If other solutions fail, completely removing and re-adding the submodule ensures a clean state:
# Step 1: Remove submodule entry from .gitmodules
git config -f .gitmodules --remove-section "submodule.path/to/submodule"
# Step 2: Remove submodule entry from .git/config
git config --remove-section "submodule.path/to/submodule"
# Step 3: Remove the submodule's git modules directory
rm -rf .git/modules/path/to/submodule
# Step 4: Remove the submodule working directory
rm -rf path/to/submodule
# Step 5: Remove from Git's cache
git rm --cached path/to/submodule
# Step 6: Commit the removal
git commit -m "Remove broken submodule"
# Step 7: Re-add the submodule
git submodule add https://github.com/user/submodule-repo.git path/to/submodule
# Step 8: Commit the re-added submodule
git commit -m "Re-add submodule"If you're getting this error when switching branches, the submodule.recurse config option may be causing Git to update submodules before they're properly initialized:
# Check if submodule.recurse is enabled
git config --get submodule.recurse
# Disable it globally
git config --global submodule.recurse false
# Or disable it for just this repository
git config submodule.recurse falseAfter disabling, switch branches first, then manually update submodules:
git checkout target-branch
git submodule update --init --recursiveYou can re-enable submodule.recurse once all submodules are in a consistent state.
If a submodule has a full .git directory instead of a .git file with a gitdir pointer, it can cause issues. The absorbgitdirs command fixes this:
# Move submodule git directories to parent's .git/modules
git submodule absorbgitdirsThis command:
1. Moves each submodule's .git directory to .git/modules/<submodule>
2. Replaces the submodule's .git directory with a .git file containing the gitdir pointer
This is especially useful if you've manually run git init inside a submodule or converted an existing directory to a submodule.
If the repository is severely corrupted and other fixes don't work, cloning fresh is the most reliable solution:
# Backup any local changes
cd /path/to/parent-repo
git stash
# Clone fresh with all submodules
cd ..
git clone --recursive https://github.com/user/repo.git repo-fresh
# Copy over any untracked files you need
# Then remove the old repository
rm -rf parent-repo
mv repo-fresh parent-repoIf you have local commits that haven't been pushed:
# In the old repo, export patches
cd old-repo
git format-patch origin/main --stdout > ../my-patches.patch
# In the fresh clone, apply them
cd ../repo-fresh
git am < ../my-patches.patchHow Git submodule directories work:
Modern Git (1.7.8+) stores submodule git data in the parent repository at .git/modules/<submodule-path>/. The submodule's working directory contains a .git file (not directory) with content like:
gitdir: ../../.git/modules/my-submoduleThis bidirectional linking requires two paths to match:
1. The gitdir: in the submodule's .git file → points to parent's .git/modules/
2. The core.worktree in .git/modules/<submodule>/config → points back to submodule's working directory
Both paths are typically relative, which is why moving the parent repository usually doesn't break things. However, older Git versions used absolute paths, which break when moving repositories.
Upgrading from older Git versions:
If you're migrating a repository from Git < 1.7.10 that used absolute paths:
# Check Git version
git --version
# If submodules have absolute paths, upgrade Git and re-clone
# Or manually fix the paths in .git files and configSubmodules in CI/CD pipelines:
Many CI/CD runners use shallow clones or don't initialize submodules by default:
# GitHub Actions
- uses: actions/checkout@v4
with:
submodules: recursive # Clone submodules too
# GitLab CI
variables:
GIT_SUBMODULE_STRATEGY: recursiveDebugging submodule state:
# Show detailed submodule status
git submodule status --recursive
# Show submodule summary (commits)
git submodule summary
# List all registered submodules
git config --file .gitmodules --get-regexp path
# Check what's in the submodule's .git file
cat path/to/submodule/.git
# Check parent's submodule config
cat .git/modules/submodule/configCommon gotcha: nested submodules:
If your submodules contain their own submodules (nested submodules), you need --recursive for most operations:
git clone --recursive <url>
git submodule update --init --recursive
git submodule foreach --recursive git pull origin mainkex_exchange_identification: Connection closed by remote host
Connection closed by remote host when connecting to Git server
fatal: unable to access: Proxy auto-configuration failed
How to fix 'Proxy auto-configuration failed' in Git
fatal: unable to access: Authentication failed (proxy requires basic auth)
How to fix 'Authentication failed (proxy requires basic auth)' in Git
fatal: unable to access: no_proxy configuration not working
How to fix 'no_proxy configuration not working' in Git
fatal: unable to read tree object in treeless clone
How to fix 'unable to read tree object in treeless clone' in Git