Search code examples
gitgit-submodulesgit-addgit-init

How to add an existing nested repo (already checked out in a subdir) to a parent Git repo as a submodule?


What happens if I'm creating the initial commit from my working (parent) directory, but there are subdirs with independently checked-out git repos?

I simply did git add . but that brought me to a strange situation when the subdirs with nested Git repos are not registered as submodules of the parent repo.

So: how to proceed after an initial "git add ." in a parent working dir where there have been subdirs with independetly checked-out nested git repos (in order to get correct submodules)?

An example:

[imz@z super-existing-sub]$ ls 
c  sub
[imz@z super-existing-sub]$ ls -a sub/
.  ..  a  .git
[imz@z super-existing-sub]$ 

So, there is already a pre-existing super-existing-sub/sub git repo inside super-existing-sub.

After I run in super-existing-sub:

$ git init
$ git add .

what can be done to correctly register the pre-existing Git repo as a submodule?

Now, Git somehow has tracked it:

$ git status 
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

    new file:   c
    new file:   sub

$ 

but git submodule has some problems:

$ git submodule status 
No submodule mapping found in .gitmodules for path 'sub'
$ 

How to convert it to a correct submodule?


I tried to proceed the way that was suggested in the answer (composed by Victor and me), namely git submodule add URL subdir, but that breaks unfortunately:

$ git submodule status
No submodule mapping found in .gitmodules for path 'wp-content/themes/liquorice'
$ git submodule add [email protected]:/nudgeme/Liquorice.git ./wp-content/themes/liquorice
'wp-content/themes/liquorice' already exists in the index
/sshx:kosmoplus:/home/kosmoplus/kosmoplus.ru.old $ git submodule status
No submodule mapping found in .gitmodules for path 'wp-content/themes/liquorice'
$ 

Solution

  • See TL;DR at the end.

    Let's read the man-page for git submodule <URL> <path> carefully, and notice the following remark:

    If <path> does exist and is already a valid Git repository, then this is added to the changeset without cloning. This second form is provided to ease creating a new submodule from scratch, and presumes the user will later push the submodule to the given URL.

    Let's try to use this in a situation like ours (after you added the parent directory recursively to the new parent repo whereas there was already an existing nested Git repo).

    The idea is, first, to lookup the origin URL in ./path/to/submodule/.git/config in order to get a nice real external URL for the meta-information about the submodule, and second, invoke git submodule <URL> <path> (which hopefully does what we want, according to the man-page).

    Let's try:

    $ git submodule status
    No submodule mapping found in .gitmodules for path 'wp-content/themes/liquorice'
    $ git submodule add [email protected]:/nudgeme/Liquorice.git ./wp-content/themes/liquorice
    'wp-content/themes/liquorice' already exists in the index
    /sshx:kosmoplus:/home/kosmoplus/kosmoplus.ru.old $ git submodule status
    No submodule mapping found in .gitmodules for path 'wp-content/themes/liquorice'
    $ 
    

    Unfortunately, it breaks.

    Well, let's think how we can solve the issue that something "already exists in the index" and is not the the thing we want...

    ...we can simply remove it from the index! This works successfully:

    $ git submodule status
    No submodule mapping found in .gitmodules for path 'wp-content/themes/liquorice'
    $ git rm --cached ./wp-content/themes/liquorice
    rm 'wp-content/themes/liquorice'
    $ git submodule add [email protected]:/nudgeme/Liquorice.git ./wp-content/themes/liquorice
    Adding existing repo at 'wp-content/themes/liquorice' to the index
    $ git submodule status
     9733c0ab3e4207352e3f51d612f2a1c9c4a0b63a wp-content/themes/liquorice (liquorice2.1-1-g9733c0a)
    $ 
    

    TL;DR

    • lookup the origin URL in subdir;
    • git rm --cached subdir
    • git submodule add URL subdir

    This could even be made a simple script to automate the task of adding an existing nested repo into the parent as a submodule, but I don't see the point in multiplying things. At this level, simply learn the basic Git commands, and use and combine them!