imz -- Ivan Zakharyaschev imz -- Ivan Zakharyaschev - 1 month ago 8
Git Question

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 git@github.com:/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'
$

Answer

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 git@github.com:/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 git@github.com:/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!

Comments