{"id":225,"date":"2018-12-26T07:39:00","date_gmt":"2018-12-26T07:39:00","guid":{"rendered":""},"modified":"2019-07-03T13:05:01","modified_gmt":"2019-07-03T13:05:01","slug":"git-submodule","status":"publish","type":"post","link":"https:\/\/opstree.com\/blog\/2018\/12\/26\/git-submodule\/","title":{"rendered":"Git-Submodule"},"content":{"rendered":"<div dir=\"ltr\" style=\"text-align:left;\">\n<div dir=\"ltr\" style=\"text-align:left;\">\n<div class=\"separator\" style=\"clear:both;text-align:center;\"><a class=\"hoverZoomLink\" href=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2018\/12\/434e0-module.jpg\" style=\"margin-left:1em;margin-right:1em;\"><img loading=\"lazy\" decoding=\"async\" border=\"0\" class=\"hoverZoomLink\" height=\"360\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2018\/12\/434e0-module.jpg?w=300\" width=\"640\"><\/a><\/div>\n<p>Rocket Science has always fascinated me, but one thing which totally blows my mind is the concept of modules aka. modular rockets. The literal definition of modules <span class=\"gmail-gr_ gmail-gr_34 gmail-gr-alert gmail-gr_gramm gmail-gr_inline_cards gmail-gr_run_anim gmail-Grammar gmail-multiReplace\" id=\"gmail-34\">states<\/span> &#8220;<i>A <b>modular rocket<\/b> is a type of multistage rocket which features components that can be interchanged for specific mission requirements.<\/i>&#8221; In simple <span class=\"gmail-gr_ gmail-gr_35 gmail-gr-alert gmail-gr_gramm gmail-gr_inline_cards gmail-gr_run_anim gmail-Punctuation gmail-only-ins gmail-replaceWithoutSep\" id=\"gmail-35\">terms<\/span>, you can say that the <b>Super Rocket <\/b>depends upon <span class=\"gmail-gr_ gmail-gr_33 gmail-gr-alert gmail-gr_gramm gmail-gr_inline_cards gmail-gr_run_anim gmail-Grammar gmail-only-del gmail-replaceWithoutSep\" id=\"gmail-33\">those<\/span> <b>Submodules<\/b> to get the things done.<br \/>\nSimilarly is the case in <span class=\"gmail-gr_ gmail-gr_30 gmail-gr-alert gmail-gr_gramm gmail-gr_inline_cards gmail-gr_run_anim gmail-Grammar gmail-only-ins gmail-replaceWithoutSep\" id=\"gmail-30\">the Software<\/span> world, where super projects have multiple dependencies on other objects. And if we talk about managing projects <b>Git<\/b> can&#8217;t be ignored, Moreover Git has a concept of <b>Submodules<\/b> which is slightly inspired <span class=\"gmail-gr_ gmail-gr_31 gmail-gr-alert gmail-gr_gramm gmail-gr_inline_cards gmail-gr_run_anim gmail-Grammar gmail-multiReplace\" id=\"gmail-31\">by<\/span> the amazing rocket science of modules.<\/p>\n<h3 style=\"text-align:left;\">Hour of Need<\/h3>\n<p>Being a <span class=\"gmail-gr_ gmail-gr_22 gmail-gr-alert gmail-gr_spell gmail-gr_inline_cards gmail-gr_run_anim gmail-ContextualSpelling gmail-ins-del gmail-multiReplace\" id=\"gmail-22\">DevOps<\/span> Specialist we need to do provisioning of the <span class=\"gmail-gr_ gmail-gr_23 gmail-gr-alert gmail-gr_spell gmail-gr_inline_cards gmail-gr_run_anim gmail-ContextualSpelling gmail-ins-del gmail-multiReplace\" id=\"gmail-23\">Infrastructure<\/span> of our clients which is sometimes common for most of the clients. We decided to Automate it, which a <span class=\"gmail-gr_ gmail-gr_24 gmail-gr-alert gmail-gr_spell gmail-gr_inline_cards gmail-gr_run_anim gmail-ContextualSpelling gmail-ins-del gmail-multiReplace\" id=\"gmail-24\">DevOps<\/span> is habitual of. Hence, Opstree Solutions initiated <span class=\"gmail-gr_ gmail-gr_27 gmail-gr-alert gmail-gr_gramm gmail-gr_inline_cards gmail-gr_run_anim gmail-Grammar gmail-multiReplace\" id=\"gmail-27\">an Internal<\/span> project named <b>OSM<span class=\"gmail-gr_ gmail-gr_26 gmail-gr-alert gmail-gr_gramm gmail-gr_inline_cards gmail-gr_run_anim gmail-Style gmail-replaceWithoutSep\" id=\"gmail-26\">.<\/span><\/b><span class=\"gmail-gr_ gmail-gr_26 gmail-gr-alert gmail-gr_gramm gmail-gr_inline_cards gmail-gr_disable_anim_appear gmail-Style gmail-replaceWithoutSep\" id=\"gmail-26\">&nbsp;In<\/span> which we create Ansible Roles of different opensource <span class=\"gmail-gr_ gmail-gr_21 gmail-gr-alert gmail-gr_spell gmail-gr_inline_cards gmail-gr_run_anim gmail-ContextualSpelling gmail-ins-del gmail-multiReplace\" id=\"gmail-21\">software<\/span> with the contribution of each member of our <span class=\"gmail-gr_ gmail-gr_32 gmail-gr-alert gmail-gr_spell gmail-gr_inline_cards gmail-gr_run_anim gmail-ContextualSpelling gmail-multiReplace\" id=\"gmail-32\">organization<\/span>. So that those roles can be used in <span class=\"gmail-gr_ gmail-gr_23 gmail-gr-alert gmail-gr_gramm gmail-gr_inline_cards gmail-gr_run_anim gmail-Grammar gmail-only-ins gmail-replaceWithoutSep\" id=\"gmail-23\">the provisioning<\/span> of the client&#8217;s infrastructure.<br \/>\nThis makes the client projects dependent on our OSM<b>. <\/b>Which creates a problem statement to manage all dependencies which might get <span class=\"gmail-gr_ gmail-gr_29 gmail-gr-alert gmail-gr_gramm gmail-gr_inline_cards gmail-gr_run_anim gmail-Grammar gmail-only-ins gmail-doubleReplace gmail-replaceWithoutSep\" id=\"gmail-29\">updated<\/span> over the period. And to do that there is a lot of copy paste, deleting the repository and cloning them again to get the updated version, which is itself a <span class=\"gmail-gr_ gmail-gr_27 gmail-gr-alert gmail-gr_spell gmail-gr_inline_cards gmail-gr_run_anim gmail-ContextualSpelling gmail-ins-del\" id=\"gmail-27\">hair-pulling<\/span> task and obviously not <span class=\"gmail-gr_ gmail-gr_36 gmail-gr-alert gmail-gr_gramm gmail-gr_inline_cards gmail-gr_run_anim gmail-Grammar gmail-multiReplace\" id=\"gmail-36\">the best<\/span> practice.<br \/>\nHere comes the git-submodule as a <b>modular rocket<\/b> to take our <b>Super Rocket <\/b>to <span class=\"gmail-gr_ gmail-gr_26 gmail-gr-alert gmail-gr_spell gmail-gr_inline_cards gmail-gr_run_anim gmail-ContextualSpelling gmail-multiReplace\" id=\"gmail-26\">its<\/span> <span class=\"gmail-gr_ gmail-gr_25 gmail-gr-alert gmail-gr_gramm gmail-gr_inline_cards gmail-gr_run_anim gmail-Grammar gmail-only-ins gmail-doubleReplace gmail-replaceWithoutSep\" id=\"gmail-25\">destination<\/span>.<\/p>\n<h4 style=\"text-align:left;\">Let&#8217;s Liftoff with Git-Submodules<\/h4>\n<div style=\"text-align:left;\">&#8220;<i>A submodule is a repository embedded inside another repository. The submodule has its own history; the repository it is embedded in is called a <span class=\"gmail-gr_ gmail-gr_35 gmail-gr-alert gmail-gr_spell gmail-gr_inline_cards gmail-gr_run_anim gmail-ContextualSpelling gmail-ins-del gmail-multiReplace\" id=\"gmail-35\">superproject<\/span>.<\/i>&#8220;<\/div>\n<p>In simple <span class=\"gmail-gr_ gmail-gr_45 gmail-gr-alert gmail-gr_gramm gmail-gr_inline_cards gmail-gr_run_anim gmail-Punctuation gmail-only-ins gmail-replaceWithoutSep\" id=\"gmail-45\">terms<\/span>, a <b>submodule<\/b> is a git repository inside a Superproject&#8217;s git repository, which has <span class=\"gmail-gr_ gmail-gr_47 gmail-gr-alert gmail-gr_spell gmail-gr_inline_cards gmail-gr_run_anim gmail-ContextualSpelling gmail-multiReplace\" id=\"gmail-47\">its<\/span> own <b>.git<\/b> folder which contains all the information that is necessary for your project in version control and all the information about commits, remote repository address etc. It is like an attached repository inside <span class=\"gmail-gr_ gmail-gr_43 gmail-gr-alert gmail-gr_gramm gmail-gr_inline_cards gmail-gr_run_anim gmail-Grammar gmail-only-del gmail-replaceWithoutSep\" id=\"gmail-43\">your<\/span> main repository, which can be used to reuse a code inside it as a &#8220;<b>module<\/b>&#8220;.<br \/>\nLet&#8217;s get a practical use case of submodules.<br \/>\nWe have a client let&#8217;s call it &#8220;Armstrong&#8221; who needs few of our ansible roles of OSM for their provisioning of Infrastructure. Let&#8217;s have a look at their git repository below.<\/p>\n<pre><span class=\"pl-k\" style=\"box-sizing:border-box;color:#d73a49;\">$    cd provisioner\n$    ls -a\n     .  ..  ansible  .git  inventory  jenkins  playbooks  README.md  roles\n$    cd roles\n$    ls -a\n     apache  java   nginx  redis  tomcat<\/span><\/pre>\n<div style=\"text-align:left;\">We can see in this Armstrong&#8217;s <i>provisioner<\/i> repository(a git repository) depends upon five roles which are available in OSM&#8217;s repository to help Armstrong to provision their infrastructure. So we&#8217;ll add submodules <i>osm_java<\/i> and others.<\/p>\n<pre><span class=\"pl-k\" style=\"box-sizing:border-box;color:#d73a49;\">$    cd java\n$    git submodule add -b armstrong git@gitlab.com:oosm\/osm_java.git osm_java\n     Cloning into '.\/provisioner\/roles\/java\/osm_java'...\n     remote: Enumerating objects: 23, done.\n     remote: Counting objects: 100% (23\/23), done.\n     remote: Compressing objects: 100% (17\/17), done.\n     remote: Total 23 (delta 3), reused 0 (delta 0)\n     Receiving objects: 100% (23\/23), done.\n     Resolving deltas: 100% (3\/3), done.<\/span><\/pre>\n<p>With the above <span class=\"gmail-gr_ gmail-gr_541 gmail-gr-alert gmail-gr_gramm gmail-gr_inline_cards gmail-gr_run_anim gmail-Punctuation gmail-only-ins gmail-replaceWithoutSep\" id=\"gmail-541\">command<\/span>, we are adding a submodule named osm_java whose <span class=\"gmail-gr_ gmail-gr_580 gmail-gr-alert gmail-gr_spell gmail-gr_inline_cards gmail-gr_run_anim gmail-ContextualSpelling gmail-ins-del gmail-multiReplace\" id=\"gmail-580\">URL<\/span> is <i>git@gitlab.com:oosm\/osm_java.git<\/i> and branch is <span class=\"gmail-gr_ gmail-gr_610 gmail-gr-alert gmail-gr_spell gmail-gr_inline_cards gmail-gr_disable_anim_appear gmail-ContextualSpelling gmail-ins-del gmail-multiReplace\" id=\"gmail-610\">armstrong<\/span>. The name of the branch is coined <span class=\"gmail-gr_ gmail-gr_645 gmail-gr-alert gmail-gr_spell gmail-gr_inline_cards gmail-gr_run_anim gmail-ContextualSpelling gmail-ins-del gmail-multiReplace\" id=\"gmail-645\">armstrong<\/span> because to keep the configuration of each of our client&#8217;s requirement isolated, we created individual branches of OSM&#8217;s repositories on the basis of client name.<br \/>\nNow if take a look at our <span class=\"gmail-gr_ gmail-gr_865 gmail-gr-alert gmail-gr_spell gmail-gr_inline_cards gmail-gr_run_anim gmail-ContextualSpelling gmail-ins-del gmail-multiReplace\" id=\"gmail-865\">superproject<\/span> provisioner we can see a file named .gitmodules which has the information regarding the submodules.<\/p>\n<pre><span class=\"pl-k\" style=\"box-sizing:border-box;color:#d73a49;\">$    cd provisioner\n$    ls -a\n     .  ..  ansible  .git  .gitmodules  inventory  jenkins  playbooks  README.md  roles\n$    cat .gitmodules\n     [submodule \"roles\/java\/osm_java\"]\n     path = roles\/java\/osm_java\n     url = git@gitlab.com:oosm\/osm_java.git\n     branch = armstrong<\/span><\/pre>\n<p>Here you can clearly see that a submodule <i>osm_java<\/i> has been attached to the superproject <i>provisioner<\/i>.<\/p>\n<h4 style=\"text-align:left;\">What if there was no submodule?<\/h4>\n<p>If that was a case, then we need to clone the repository from osm and paste it to the provisioner then add &amp; commit it to the provisioner phew&#8230;.. that would also have worked.<br \/>\nBut what if there is some update has been made in the osm_java which have to be used in <i>provisioner<\/i>, we can not easily sync with the OSM. We would need to delete <i>osm_java<\/i>, again clone, copy, and paste in the provisioner which sounds clumsy and not a best way to automate the process.<br \/>\nBeing a osm_java as a submodule we can easily update that this dependency without messing up the things.<\/p>\n<pre><span class=\"pl-k\" style=\"box-sizing:border-box;color:#d73a49;\">$    git submodule status\n     -d3bf24ff3335d8095e1f6a82b0a0a78a5baa5fda roles\/java\/osm_java\n$    git submodule update --remote\n     remote: Enumerating objects: 3, done.\n     remote: Counting objects: 100% (3\/3), done.\n     remote: Total 2 (delta 0), reused 2 (delta 0), pack-reused 0\n     Unpacking objects: 100% (2\/2), done.\n     From <\/span><span class=\"pl-k\" style=\"box-sizing:border-box;color:#d73a49;\"><span class=\"pl-k\" style=\"box-sizing:border-box;color:#d73a49;\">git@gitlab.com:oosm\/osm_java.git<\/span>     0564d78..04ca88b  armstrong     -&gt; origin\/armstrong\n     Submodule path 'roles\/java\/osm_java': checked out '04ca88b1561237854f3eb361260c07824c453086'<\/span><\/pre>\n<p>By using the above update command we have <span class=\"gmail-gr_ gmail-gr_1591 gmail-gr-alert gmail-gr_spell gmail-gr_inline_cards gmail-gr_run_anim gmail-ContextualSpelling gmail-ins-del gmail-multiReplace\" id=\"gmail-1591\">successfully<\/span> updated the submodule which actually pulled the changes from OSM&#8217;s origin <i>armstrong<\/i> branch.<\/p>\n<h4 style=\"text-align:left;\">What have we learned?&nbsp;<\/h4>\n<div style=\"text-align:left;\">In this <span class=\"gmail-gr_ gmail-gr_74 gmail-gr-alert gmail-gr_gramm gmail-gr_inline_cards gmail-gr_run_anim gmail-Punctuation gmail-only-ins gmail-replaceWithoutSep\" id=\"gmail-74\"><span class=\"gmail-gr_ gmail-gr_66 gmail-gr-alert gmail-gr_spell gmail-gr_inline_cards gmail-gr_run_anim gmail-ContextualSpelling gmail-ins-del\" id=\"gmail-66\">blog post<\/span><\/span>, we learned to make use of git-submodules to keep our dependent repositories updated with our <span class=\"gmail-gr_ gmail-gr_67 gmail-gr-alert gmail-gr_spell gmail-gr_inline_cards gmail-gr_run_anim gmail-ContextualSpelling gmail-ins-del gmail-multiReplace\" id=\"gmail-67\">super project<\/span>, and not getting our hands dirty with gullible copy and paste.<\/div>\n<div style=\"text-align:left;\">Kick-off those practices which might ruin the fun, sit back and enjoy the automation.<\/div>\n<p><b>Referred links: <\/b><br \/>\nImage: <a href=\"https:\/\/www.google.com\/search?q=module+rocket&amp;client=ubuntu&amp;hs=83Z&amp;channel=fs&amp;source=lnms&amp;tbm=isch&amp;sa=X&amp;ved=0ahUKEwjkge3x6qbfAhVTSX0KHSpsD8UQ_AUIDygC&amp;biw=1325&amp;bih=639#imgrc=bZvZ97NwfHZ6aM:\" target=\"_blank\" rel=\"noopener\">google.com<\/a><br \/>\nDocumentation: <a href=\"https:\/\/git-scm.com\/docs\/gitsubmodules\" target=\"_blank\" rel=\"noopener\">https:\/\/git-scm.com\/docs\/gitsubmodules<\/a><\/p>\n<\/div>\n<\/div>\n<p><img id=\"hzDownscaled\" style=\"position:absolute;top:-10000px;\"><\/p>\n<div id=\"hzImg\" style=\"background-color:white;border-radius:3px;border:1px solid rgb(255,255,255);box-shadow:rgba(0,0,0,0.33) 3px 3px 9px 5px;cursor:pointer;display:none;left:0;line-height:0;margin:0;opacity:1;overflow:hidden;padding:2px;pointer-events:none;position:absolute;top:53px;z-index:2147483647;\"><\/div>\n<div id=\"hzImg\" style=\"background-color:white;border-radius:3px;border:1px solid rgb(255,255,255);box-shadow:rgba(0,0,0,0.33) 3px 3px 9px 5px;cursor:pointer;display:none;left:0;line-height:0;margin:0;opacity:1;overflow:hidden;padding:2px;pointer-events:none;position:absolute;top:53px;z-index:2147483647;\"><\/div>\n<p><img id=\"hzDownscaled\" style=\"position:absolute;top:-10000px;\"><br \/>\n<img id=\"hzDownscaled\" style=\"position:absolute;top:-10000px;\"><\/p>\n<div id=\"hzImg\" style=\"background-color:white;border-radius:3px;border:1px solid rgb(255,255,255);box-shadow:rgba(0,0,0,0.33) 3px 3px 9px 5px;cursor:pointer;display:none;left:0;line-height:0;margin:0;opacity:1;overflow:hidden;padding:2px;pointer-events:none;position:absolute;top:37px;z-index:2147483647;\"><\/div>\n<p><img id=\"hzDownscaled\" style=\"position:absolute;top:-10000px;\"><\/p>\n<div id=\"hzImg\" style=\"background-color:white;border-radius:3px;border:1px solid rgb(255,255,255);box-shadow:rgba(0,0,0,0.33) 3px 3px 9px 5px;display:none;left:364px;line-height:0;margin:0;opacity:1;overflow:hidden;padding:2px;position:absolute;top:200px;z-index:2147483647;\"><\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Rocket Science has always fascinated me, but one thing which totally blows my mind is the concept of modules aka. modular rockets. The literal definition of modules states &#8220;A modular rocket is a type of multistage rocket which features components that can be interchanged for specific mission requirements.&#8221; In simple terms, you can say that &hellip; <a href=\"https:\/\/opstree.com\/blog\/2018\/12\/26\/git-submodule\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Git-Submodule&#8221;<\/span><\/a><\/p>\n","protected":false},"author":159458168,"featured_media":29900,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[1],"tags":[768739308,768739295,15148152],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2025\/11\/DevSecOps-1.jpg","jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pfDBOm-3D","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/225"}],"collection":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/users\/159458168"}],"replies":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/comments?post=225"}],"version-history":[{"count":3,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/225\/revisions"}],"predecessor-version":[{"id":1506,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/225\/revisions\/1506"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/media\/29900"}],"wp:attachment":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/media?parent=225"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/categories?post=225"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/tags?post=225"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}