Skip to content

Instantly share code, notes, and snippets.

@claraj
Last active November 7, 2024 18:20
Show Gist options
  • Save claraj/e5563befe6c2fb108ad0efb6de47f265 to your computer and use it in GitHub Desktop.
Save claraj/e5563befe6c2fb108ad0efb6de47f265 to your computer and use it in GitHub Desktop.
Fixing git submodule AKA git repo inside another git repo

Problem, and symptoms:

You experience one or more of these symptoms

  • you have code in a directory but it's not being pushed to GitHub. You just see an empty directory icon
  • you see this message when you add code to your git repository from the command prompt
hint: You've added another git repository inside your current repository.
hint: Clones of the outer repository will not contain the contents of
hint: the embedded repository and will not know how to obtain it.
hint: If you meant to add a submodule, use:
hint: 
hint:   git submodule add <url> nodule
hint: 
hint: If you added this path by mistake, you can remove it from the
hint: index with:
hint: 
hint:   git rm --cached nodule
hint: 
hint: See "git help submodule" for more information.

What's happening?

You have added a git repository inside another git repository

The outer git repository will ignore the inner git repository.

The inner git repository is known as a submodule.

Let's say you have these files and directories

project 
   |- file1.html
   |- file2.css
   |- resources
       |- info1.json
       |- info2.json

If you create a git repository in the project directory, and there's a git repository in the resources directory, all the files inside the resources directory will be ignored by the git repository in the project directory.

A git repo inside another git repo is called a submodule. In other words, a directory with a git repository in, is inside another directory, also with a git repository in. The submodule doesn't have to be in the immediate subdirectory, it can be one or two or more levels above.

Sometimes this is what you want to do, but if what you want to do is to collect files from more than one directory together in to one repository, you only want one git repository for the entire project. So a submodule is not what you want to happen.

When a git repo is created, it created a hidden directory called .git and that's how the git tool knows it's working with a git repository. All of the info about your past versions of code, the location of the GitHub remote etc.. are stored in files in this .git directory.

If you have a git repo in the project directory, and another one in the resources directory, your file system will actually look like this,

 project 
   |- .git
   |- file1.html
   |- file2.css
   |- resources
       |- .git
       |- info1.json
       |- info2.json

If you add and commit files from the project directory, you'll see an entry for the resources directory under files you've added and committed, but the info1.json and info2.json files will not be added.

If you want the project directory to have one git repo with everything in, follow these steps.

In the resources directory (the inner directory with a git repo in): delete the .git folder. You will need to enable hidden files to see this in explorer / finder.

Use a command prompt or git bash (windows) or terminal (mac, linux) and navigate to the project directory. You need to be in the directory above the one with the submodule - so in this example, the project directory (the outer directory, the one that should contain all the files). Then run the command

git rm --cached resources

but replace resources with your own directory name. The --cached part is really important, if you miss it out it will irreversably delete your resources directory!

Now you should be able to use the git add command to add all of the files in the resources directory to the main project's repository, and commit those files.

@sachingirime
Copy link

add

Thanks a lot

@KennethStreet
Copy link

This helped me too! Thanks!

@juancarlosp94
Copy link

Helped me a lot, thank you so much!

@username-max91
Copy link

Thank you so much, just what I was looking for!

@vamsirenangi
Copy link

wow this worked really well , iam facing this issue from several days

@AliceEMaffs
Copy link

fatal: pathspec 'foldername' did not match any files
please help

@Smontan
Copy link

Smontan commented Sep 10, 2023

No one says in the stack overflow that .git folder is hidden!. It took me 6hrs before I read this Solution.

@GHimenos
Copy link

GHimenos commented Oct 16, 2023

Emm... The easier ways:

  • don't init the git in a parent directory and:
    a.: just cd to directory with the repo
    b.: reopen the directory with the repo in your IDE to avoid changing it each time (you can previously move the repo directory to the appropriate place of your local and kill the parent one)

@alfreat
Copy link

alfreat commented Dec 7, 2023

What if i have commits inside the resources directory and i want to preserve those in the project directory, is it possible? Please elaborate.

@DiBiase123
Copy link

Thank you

@Steven7zzz
Copy link

you saved my life!

@Mahmoud-Fauome
Copy link

شكرا جدا لك

@Manu752
Copy link

Manu752 commented Apr 5, 2024

No one says in the stack overflow that .git folder is hidden!. It took me 6hrs before I read this Solution.

thanks a ton ..you're a lifesaver !

@ShanmugaCA
Copy link

Thanks!
Your explanation section "What's happening?" is very clear and that helped a lot, saved my time !

@Dark-Kernel
Copy link

I would rename ".git" to "git" instead removing it. This has the benefit, you can later revert the renaming (back to .git). After that, you can use git pull or git checkout other-branch again to update/modify the included resource. Rename it again to git and commit.

Cool dude!

@pa-0
Copy link

pa-0 commented Oct 23, 2024

To rename just .git submodule folders, in a repository with the following structure:

root/
├── sub1
│   └── .git
├── sub2
|   └── .git
├── sub3
|   └── .git
├── sub4
|   └── .git
├── sub5
|   └── .git 

you can pass the root folder's name to the following script:

#!/bin/bash
find . -maxdepth 3 -mindepth 3 -name ".git" -type d -execdir mv -- '{}' 'git' ';'

Note

If the .git folders are ± 1 to n levels above or below what's shown in my example, adjust maxdepth and mindepth #'s accordingly.

@imrany
Copy link

imrany commented Nov 7, 2024

Thanks a lot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment