# Submodules

Submodules are a useful feature of git, and allow us to nest projects within our own project. A good example of a project that would take advantage of this is a dotfiles repository - mine can be found [on GitLab](https://gitlab.com/shaunrd0/dot) and has several submodules.

I've recently been working on [kot](https://gitlab.com/shaunrd0/kot), a linux dotfiles CLI tool, and I have been testing it with my dotfiles repository within a docker container. I thought this was a good chance to write down some useful commands for dealing with git submodules. 

If you want a repository to test these commands, feel free to clone kot and play around with the submodules within.
```bash
git clone https://gitlab.com/shaunrd0/kot
cd kot
```

To show a status of all submodules - 
```bash
git submodule status --recursive

-7877117d5bd413ecf35c86efb4514742d8136843 dot (heads/master)
-826d5691ac7d36589591314621047b1b9d89ed34 dot/.vim/bundle/Colorizer
-3ea887d2f4d43dd55d81213517344226f6399ed6 dot/.vim/bundle/ale
-293a1062274a06be61797612034bd8d87851406e dot/.vim/bundle/clang_complete
-d80e8e2c1fa08607fa34c0ca5f1b66d8a906c5ef dot/.vim/bundle/supertab
-afb8db4f81580771c39967e89bc5772e72b9018e dot/.vim/bundle/unicode.vim
-cb1bc19064d3762e4e08103afb37a246b797d902 dot/.vim/bundle/vim-airline
-d148d42d9caf331ff08b6cae683d5b210003cde7 dot/.vim/bundle/vim-airline-themes
-b2a0450e23c63b75bbeabf4f0c28f9b4b2480689 dot/.vim/bundle/vim-signify
```

So I have `dot` as a submodule, and `dot` also has several submodules we inherit with the `--recursive` option. The same command without recursion is shown below

```bash
git submodule status

-7877117d5bd413ecf35c86efb4514742d8136843 dot (heads/master)
```

Notice in all of the output below, there is a minus sign `-` before each submodule. This means they have not been initialized. To summarize the meaning of this output, I'll quote from `man git-submodule`

>This will print the SHA-1 of the currently
           checked out commit for each submodule, along with the submodule path and the
           output of git describe for the SHA-1. Each SHA-1 will possibly be prefixed with
           - if the submodule is not initialized, + if the currently checked out submodule
           commit does not match the SHA-1 found in the index of the containing repository
           and U if the submodule has merge conflicts.


To update and initialize all submodules recursively, we can use the following command

```bash
git submodule update --init --recursive        

Submodule 'dotfiles/dot' (https://gitlab.com/shaunrd0/dot) registered for path 'dotfiles/dot'
Cloning into '/home/kapper/Code/kotd/dotfiles/dot'...
warning: redirecting to https://gitlab.com/shaunrd0/dot.git/
Submodule path 'dotfiles/dot': checked out '7877117d5bd413ecf35c86efb4514742d8136843'
Submodule '.vim/bundle/Colorizer' (https://github.com/chrisbra/Colorizer) registered for path 'dotfiles/dot/.vim/bundle/Colorizer'
Submodule '.vim/bundle/ale' (https://github.com/dense-analysis/ale) registered for path 'dotfiles/dot/.vim/bundle/ale'
Submodule '.vim/bundle/clang_complete' (https://github.com/xavierd/clang_complete) registered for path 'dotfiles/dot/.vim/bundle/clang_complete'
Submodule '.vim/bundle/supertab' (https://github.com/ervandew/supertab) registered for path 'dotfiles/dot/.vim/bundle/supertab'
Submodule '.vim/bundle/unicode.vim' (https://github.com/chrisbra/unicode.vim) registered for path 'dotfiles/dot/.vim/bundle/unicode.vim'
Submodule '.vim/bundle/vim-airline' (https://github.com/vim-airline/vim-airline) registered for path 'dotfiles/dot/.vim/bundle/vim-airline'
Submodule '.vim/bundle/vim-airline-themes' (https://github.com/vim-airline/vim-airline-themes) registered for path 'dotfiles/dot/.vim/bundle/vim-airline-themes'
Submodule '.vim/bundle/vim-signify' (https://github.com/mhinz/vim-signify) registered for path 'dotfiles/dot/.vim/bundle/vim-signify'
Cloning into '/home/kapper/Code/kotd/dotfiles/dot/.vim/bundle/Colorizer'...
Cloning into '/home/kapper/Code/kotd/dotfiles/dot/.vim/bundle/ale'...
Cloning into '/home/kapper/Code/kotd/dotfiles/dot/.vim/bundle/clang_complete'...
Cloning into '/home/kapper/Code/kotd/dotfiles/dot/.vim/bundle/supertab'...
Cloning into '/home/kapper/Code/kotd/dotfiles/dot/.vim/bundle/unicode.vim'...
Cloning into '/home/kapper/Code/kotd/dotfiles/dot/.vim/bundle/vim-airline'...
Cloning into '/home/kapper/Code/kotd/dotfiles/dot/.vim/bundle/vim-airline-themes'...
Cloning into '/home/kapper/Code/kotd/dotfiles/dot/.vim/bundle/vim-signify'...
Submodule path 'dotfiles/dot/.vim/bundle/Colorizer': checked out '826d5691ac7d36589591314621047b1b9d89ed34'
Submodule path 'dotfiles/dot/.vim/bundle/ale': checked out '3ea887d2f4d43dd55d81213517344226f6399ed6'
Submodule path 'dotfiles/dot/.vim/bundle/clang_complete': checked out '293a1062274a06be61797612034bd8d87851406e'
Submodule path 'dotfiles/dot/.vim/bundle/supertab': checked out 'd80e8e2c1fa08607fa34c0ca5f1b66d8a906c5ef'
Submodule path 'dotfiles/dot/.vim/bundle/unicode.vim': checked out 'afb8db4f81580771c39967e89bc5772e72b9018e'
Submodule path 'dotfiles/dot/.vim/bundle/vim-airline': checked out 'cb1bc19064d3762e4e08103afb37a246b797d902'
Submodule path 'dotfiles/dot/.vim/bundle/vim-airline-themes': checked out 'd148d42d9caf331ff08b6cae683d5b210003cde7'
Submodule path 'dotfiles/dot/.vim/bundle/vim-signify': checked out 'b2a0450e23c63b75bbeabf4f0c28f9b4b2480689'
```

Now if we later return to the repository and run `git submodule status --recursive` and get the following output

```bash
git submodule status --recursive 

+7877117d5bd413ecf35c86efb4514742d8136843 dot (heads/master)
 826d5691ac7d36589591314621047b1b9d89ed34 dot/.vim/bundle/Colorizer (heads/master)
 3ea887d2f4d43dd55d81213517344226f6399ed6 dot/.vim/bundle/ale (v3.1.0-9-g3ea887d2)
 293a1062274a06be61797612034bd8d87851406e dot/.vim/bundle/clang_complete (v1.8-374-g293a106)
 d80e8e2c1fa08607fa34c0ca5f1b66d8a906c5ef dot/.vim/bundle/supertab (2.1-40-gd80e8e2)
 afb8db4f81580771c39967e89bc5772e72b9018e dot/.vim/bundle/unicode.vim (v20-139-gafb8db4)
 cb1bc19064d3762e4e08103afb37a246b797d902 dot/.vim/bundle/vim-airline (v0.11-354-gcb1bc19)
 d148d42d9caf331ff08b6cae683d5b210003cde7 dot/.vim/bundle/vim-airline-themes (remotes/origin/jellybeans-refactor-266-gd148d42)
 b2a0450e23c63b75bbeabf4f0c28f9b4b2480689 dot/.vim/bundle/vim-signify (v1.0-291-gb2a0450)
```

This means the `dot` project submodule has a new commit that we haven't pulled into our local project yet. To fix this, just run the command below again.

```bash
git submodule update --init --recursive
```


**Fixing or replacing submodules** can be done with the following steps. 

For context, see the status of all submodules

```bash
git submodule status 

 826d5691ac7d36589591314621047b1b9d89ed34 .vim/bundle/Colorizer (heads/master)
 3ea887d2f4d43dd55d81213517344226f6399ed6 .vim/bundle/ale (v3.1.0-9-g3ea887d2)
 293a1062274a06be61797612034bd8d87851406e .vim/bundle/clang_complete (v1.8-374-g293a106)
 d80e8e2c1fa08607fa34c0ca5f1b66d8a906c5ef .vim/bundle/supertab (2.1-40-gd80e8e2)
 afb8db4f81580771c39967e89bc5772e72b9018e .vim/bundle/unicode.vim (v20-139-gafb8db4)
 cb1bc19064d3762e4e08103afb37a246b797d902 .vim/bundle/vim-airline (v0.11-354-gcb1bc19)
 d148d42d9caf331ff08b6cae683d5b210003cde7 .vim/bundle/vim-airline-themes (remotes/origin/jellybeans-refactor-266-gd148d42)
 b2a0450e23c63b75bbeabf4f0c28f9b4b2480689 .vim/bundle/vim-signify (v1.0-291-gb2a0450)
 ```

So we try to add a submodule, one that we had removed from `.gitmodules` and deleted the directory. But we get the error below.

```bash
git submodule add https://github.com/alexanderjeurissen/ranger_devicons .config/ranger/plugins/ranger_devicons

A git directory for '.config/ranger/plugins/ranger_devicons' is found locally with remote(s):
  origin        https://github.com/alexanderjeurissen/ranger_devicons
If you want to reuse this local git directory instead of cloning again from
  https://github.com/alexanderjeurissen/ranger_devicons
use the '--force' option. If the local git directory is not the correct repo
or you are unsure what this means choose another name with the '--name' option.
```

To correct the awkward start our git modules are in, we simply remove all traces of the submodule. To do this, run the following commands

```bash
git rm -r --cached .config/ranger/plugins/ranger_devicons/
rm -r .config/ranger/plugins/ranger_devicons/
rm -rf .git/modules/.config/ranger/plugins/ranger_devicons/
vim .gitmodules
vim .git/config
```

The first file opened by the `vim` command is `.gitmodules` within the root of your repository. REMOVE the following lines, and save the file.
```toml
# .gitmodules file in the root of your repository
[submodule ".config/ranger/plugins/ranger_devicons"]
  path = .config/ranger/plugins/ranger_devicons
  url = https://github.com/alexanderjeurissen/ranger_devicons
```

The second file opened by the `vim` command is `.git/config`. REMOVE the following lines, and save the file.

```toml
# .git/config from the root of your repository
[submodule ".config/ranger/plugins/ranger_devicons"]
  url = https://github.com/alexanderjeurissen/ranger_devicons
  active = true
```

Now you can add the submodule back again

```bash
git submodule add https://github.com/alexanderjeurissen/ranger_devicons .config/ranger/plugins/ranger_devicons

Cloning into '/home/kapper/dot/.config/ranger/plugins/ranger_devicons'...
remote: Enumerating objects: 329, done.
remote: Counting objects: 100% (91/91), done.
remote: Compressing objects: 100% (84/84), done.
remote: Total 329 (delta 37), reused 10 (delta 7), pack-reused 238
Receiving objects: 100% (329/329), 183.95 KiB | 2.11 MiB/s, done.
Resolving deltas: 100% (146/146), done.
```

```bash
git submodule status 

 feb2d7a90fe8aabd7ee3965d4bd67ebedceca817 .config/ranger/plugins/ranger_devicons (heads/main)
 826d5691ac7d36589591314621047b1b9d89ed34 .vim/bundle/Colorizer (heads/master)
 3ea887d2f4d43dd55d81213517344226f6399ed6 .vim/bundle/ale (v3.1.0-9-g3ea887d2)
 293a1062274a06be61797612034bd8d87851406e .vim/bundle/clang_complete (v1.8-374-g293a106)
 d80e8e2c1fa08607fa34c0ca5f1b66d8a906c5ef .vim/bundle/supertab (2.1-40-gd80e8e2)
 afb8db4f81580771c39967e89bc5772e72b9018e .vim/bundle/unicode.vim (v20-139-gafb8db4)
 cb1bc19064d3762e4e08103afb37a246b797d902 .vim/bundle/vim-airline (v0.11-354-gcb1bc19)
 d148d42d9caf331ff08b6cae683d5b210003cde7 .vim/bundle/vim-airline-themes (remotes/origin/jellybeans-refactor-266-gd148d42)
 b2a0450e23c63b75bbeabf4f0c28f9b4b2480689 .vim/bundle/vim-signify (v1.0-291-gb2a0450)
```