Understanding git submodule
We recently upgrade & add some little features to our extension carousel based on “Infinite Carousel” by CatchMyFame.com. We were working in our extension repository, focusing just in javascript implementation within a test app. When we integrated to our radiant project and run it locally, it worked just fine. But after deploy I got:
** Could not load extension from file: infinite_carousel_extension.
**#<NameError: uninitialized constant InfiniteCarouselExtension>
Looking into releases/12355/ vendor/extensions/infinite_carousel folder reveals no files whatsoever. Then I realized something obvious about how radiant works. It looks in their extension folders for the _extension.rb file, which in our case no longer exists. The directory was created, but none of the content was pulled in.
In my short experience, understanding Git, you have to understand its implementation something for which I am still struggling with myself.
Submodule
Git submodule essentially allows you to attach an external repository inside another repository at a specific path.
Having submodules in a repository is fantastic. It creates some sort of independence but if I look in my repository, all I have is an empty directory rather than the actual contents, which can be frustrating, right?
First things first: Adding Submodule to your git repository
$ git submodule add <external_repository> <submodule_path_repository>
Since we added a radiant extension, the git submodule add <external_path> <submodule_path> was done when we run script/extension install infinite_carousel
In order to fill in the submodule’s path with the files from the external repository, you must first initialize the submodules and then update them.
$ git submodule init
$ git submodule update
Working in a Submodule
Git submodules are locked to a specific revision and don’t automatically track the external project’s HEAD.
The checked out submodules is a full Git repository in and of itself and it should be treated as such. So, if you want to make changes locally in your submodule, you must repeat the usual steps .
$ git add <submodule files changed>
$ git commit -m <your comments>
Git submodules are implemented using two parts: the .gitmodules file and special type of tree object. Together, they define a specific revision of a specific repository which is checked out into a specific location in your project.
[submodule "vendor/extensions/infinite_carousel"]
path = vendor/extensions/infinite_carousel
url = git://github.com/blazingcloud/radiant-carousel-extension.git
The file contains:
Path ==> location in your repository where the submodule should live.
Url ==> is the url of the repository to clone from. Our example is a github url but I assume that it should equally be a path to another repository. Although, I haven’t tried it.
If you want your main project to use the new HEAD of the submodule, you simply need to add and commit the submodule’s directory as you would with any other file.
Removing Submodules
So, we ended up removing the submodule from our main repository. It was not the right approach for our case.
Note: script/extension install <extension_name> in your Radiant Project generates sub-module repository <references to original repository>. So if you want your extension to be part of you main repository, submodule is not a good option.
We couldn’t find a git submodule <command> that removes everything in one command. We had to do a couple things to remove the submodule.
- Remove the submodule’s entry in the .gitmodules file. Use your favorite editor and remove the tree object [submodule] url path
- Remove the submodule’s entry in the .git/config, which it is only present if you’ve run “git submodule init” on the repository. If you haven’t, you can skip this step.
- Remove the path created for the submodule “git rm –cached <plugin path>“
One Comment
Thanks for this. It did help out a tonne as I couldn’t find it in the wiki of radiant. By the time I needed to figure out how to setup a project, with submodules, on a staging server… the giti submodule init and update commands were the key.