{"id":1716,"date":"2023-10-31T14:45:05","date_gmt":"2023-10-31T14:45:05","guid":{"rendered":"https:\/\/www.aviator.co\/blog\/?p=1716"},"modified":"2025-09-25T13:17:17","modified_gmt":"2025-09-25T13:17:17","slug":"how-to-work-with-git-submodules","status":"publish","type":"post","link":"https:\/\/www.aviator.co\/blog\/how-to-work-with-git-submodules\/","title":{"rendered":"How to work with git submodules"},"content":{"rendered":"\n<figure class=\"wp-block-image size-full\"><img fetchpriority=\"high\" decoding=\"async\" width=\"800\" height=\"400\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2023\/10\/git-submodules.webp\" alt=\"\" class=\"wp-image-1725\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2023\/10\/git-submodules.webp 800w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2023\/10\/git-submodules-300x150.webp 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2023\/10\/git-submodules-768x384.webp 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/figure>\n\n\n\n<p>Git submodules allow you to include one repository inside another. This is useful when you want fine-grained control over your dependencies, or in situations where a dependency manager is not suitable. Submodules are powerful tools, and it\u2019s worth understanding them properly before using them.<\/p>\n\n\n\n<p>In this article, we\u2019ll cover:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>What Git submodules are<\/li>\n\n\n\n<li>Common workflows with submodules<\/li>\n\n\n\n<li>What they are useful for<\/li>\n\n\n\n<li>When you shouldn&#8217;t use them<\/li>\n<\/ul>\n\n\n\n<p>At the end of the article, you\u2019ll also find links to further resources.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.aviator.co\/merge-queue\" target=\"_blank\" rel=\" noreferrer noopener\"><img decoding=\"async\" width=\"1940\" height=\"500\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/04\/aviator-mergequeue-blog-service-page-cta-photo-min-1.png\" alt=\"Mergequeue CTA\" class=\"wp-image-4920\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/04\/aviator-mergequeue-blog-service-page-cta-photo-min-1.png 1940w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/04\/aviator-mergequeue-blog-service-page-cta-photo-min-1-300x77.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/04\/aviator-mergequeue-blog-service-page-cta-photo-min-1-1024x264.png 1024w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/04\/aviator-mergequeue-blog-service-page-cta-photo-min-1-768x198.png 768w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2024\/04\/aviator-mergequeue-blog-service-page-cta-photo-min-1-1536x396.png 1536w\" sizes=\"(max-width: 1940px) 100vw, 1940px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Git submodules<\/h2>\n\n\n\n<p>Imagine you are working on a text editor. You\u2019ve implemented the basic features of viewing and editing files, and now you want to add syntax highlighting. There\u2019s a cool library on GitHub that does exactly what you want, but it hasn\u2019t been published to the dependency manager you use. How can you use it?<\/p>\n\n\n\n<p>This is a situation where Git submodules might come in handy. Submodules are a feature of Git that lets you include one repository inside another. This means that you can include the syntax highlighting library in your text editor\u2019s repo while keeping a link to the original repository so that you can receive upstream changes.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"800\" height=\"600\" src=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2023\/10\/editor-repository-structure.png\" alt=\"\" class=\"wp-image-1717\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2023\/10\/editor-repository-structure.png 800w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2023\/10\/editor-repository-structure-300x225.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2023\/10\/editor-repository-structure-768x576.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/figure>\n\n\n\n<p>The above diagram shows what your repository structure might look like when you use submodules. The <code>src<\/code> and <code>test<\/code> directories contain your own files, but <code>lib<\/code> contains the syntax highlighter library as a submodule.<\/p>\n\n\n\n<p>Submodules are entire Git repositories that are pinned to a specific commit. Your local copy of a repository containing a submodule will contain all of the files from the submodule, which means that you can treat it as if it were your own code. Submodules let you view, edit, and reference all of the files in the contained repository.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>text-editor\n\u251c\u2500\u2500 lib\n\u2502   \u2514\u2500\u2500 syntax-highlighter\n\u2502       \u251c\u2500\u2500 README.md\n\u2502       \u251c\u2500\u2500 docs\n\u2502       \u2502   \u2514\u2500\u2500 very-good-docs.md\n\u2502       \u2514\u2500\u2500 ...\n\u251c\u2500\u2500 src\n\u2502   \u251c\u2500\u2500 editor.py\n\u2502   \u2514\u2500\u2500 ...\n\u2514\u2500\u2500 test\n    \u2514\u2500\u2500 ...<\/code><\/pre>\n\n\n\n<p>Above is the file structure of our text editor repository after adding the syntax highlighting library as a submodule. All of the files from the submodule are on our filesystem and ready for us to edit them.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Workflows<\/h2>\n\n\n\n<p>Now that you\u2019ve seen what submodules can do, the following section will take you through how to use them.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Adding a submodule to your repository<\/h3>\n\n\n\n<p>Following on from the example earlier of a syntax highlighting library, imagine that the library you want to add is at the following URL:<\/p>\n\n\n\n<p><a href=\"https:\/\/www.github.com\/username\/syntax-highlighter\">https:\/\/www.github.com\/username\/syntax-highlighter<\/a><\/p>\n\n\n\n<p>You can add this library as a submodule to your repository by using the command:<\/p>\n\n\n\n<p><code>git submodule add https:\/\/www.github.com\/username\/syntax-highlighter lib\/syntax-highlighter<\/code><\/p>\n\n\n\n<p>This will add two new files to your repository, <code>.gitmodules<\/code> and <code>lib\/syntax-highlighter<\/code>. You can see these files using <code>git status<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>~\/src\/text-editor$ git status\nOn branch main\n\nNo commits yet\n\nChanges to be committed:\n  (use \"git rm --cached &lt;file&gt;...\" to unstage)\n     new file:   .gitmodules\n     new file:   lib\/syntax-highlighter<\/code><\/pre>\n\n\n\n<p><code>.gitmodules<\/code> is a simple text file that lists the submodules in your repository. You should commit this file so that other people working on your repository can also use the submodule.<\/p>\n\n\n\n<p><code>lib\/syntax-highlighter<\/code> is a bit more complicated. Git sees this path as a file, but your filesystem sees the path as a directory. You can output what Git sees by running <code>git diff --cached lib\/syntax-highlighter<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>~\/src\/text-editor$ git diff --cached lib\/syntax-highlighter\ndiff --git a\/lib\/syntax-highlighter b\/lib\/syntax-highlighter\nnew file mode 160000\nindex 0000000..ac8e080\n--- \/dev\/null\n+++ b\/lib\/syntax-highlighter\n@@ -0,0 +1 @@\n+Subproject commit ac8e080ae2ba4c582eb5842139ab7e5082b4cff0<\/code><\/pre>\n\n\n\n<p>As shown in the diff above, Git sees the submodule as a file containing the commit ID currently tracked by the submodule. By default, this will be the latest commit to the default branch, which is usually <code>main<\/code> on newer Git repositories and <code>master<\/code> on older ones.<\/p>\n\n\n\n<p>However, if you look at the submodule on the filesystem using something like <code>ls<\/code>, you\u2019ll see that it\u2019s a directory:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>~\/src\/example$ ls lib\/syntax-highlighter\nREADME.md  docs  src  test<\/code><\/pre>\n\n\n\n<p>What\u2019s more, this directory is actually a Git repository in its own right! You can run things like <code>git status<\/code> and even edit the code in it.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Cloning a repository that contains a submodule<\/h3>\n\n\n\n<p>Git stores each submodule as an entry in <code>.gitmodules<\/code> and a file in the repo that describes what commit the submodule points to. As a result, when you clone a repo, you need to do a little extra work to download the code for the submodule into your local copy.<\/p>\n\n\n\n<p>Let\u2019s say you\u2019ve cloned the text-editor repo from earlier:<\/p>\n\n\n\n<p><code>git clone https:\/\/github.com\/username\/text-editor<\/code><\/p>\n\n\n\n<p>If you were then to examine <code>lib\/syntax-highlighter<\/code>, you\u2019d find that it\u2019s just an empty directory.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>~\/src\/text-editor$ less lib\/syntax-highlighter\/\nlib\/syntax-highlighter\/ is a directory<\/code><\/pre>\n\n\n\n<p>To populate <code>lib\/syntax-highlighter<\/code> with the submodule\u2019s code, you need to run <code>git submodule update --init --recursive<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>~\/src\/text-editor$ git submodule update --init --recursive\nSubmodule 'lib\/syntax-highlighter' (https:\/\/github.com\/username\/syntax-highlighter.git) registered for path 'lib\/syntax-highlighter'\nCloning into '\/home\/username\/src\/text-editor\/lib\/syntax-highlighter'...\nSubmodule path 'lib\/syntax-highlighter': checked out '55086f1cb2ee8294d3354805be941171c287557d'<\/code><\/pre>\n\n\n\n<p>This is a convenient shorthand for <code>git submodule init<\/code> followed by <code>git submodule update<\/code>. If your submodules have submodules then this command will also initialize those recursively. <code>init<\/code> figures out where the submodule comes from and <code>update<\/code> downloads its contents.<\/p>\n\n\n\n<p>An alternative workflow is to use <code>git clone --recurse-submodules<\/code>. This is an even shorter shorthand that is equivalent to a <code>git clone<\/code>, <code>git submodule init<\/code>, and <code>git submodule update<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Editing a submodule&#8217;s code<\/h3>\n\n\n\n<p>Submodules are complete Git repositories in their own right. This means that you can use them exactly as you would any other Git repository. To illustrate this point, let\u2019s walk through making a change to a submodule in our repository.<\/p>\n\n\n\n<p>Imagine that you want to add a line to the syntax-highlighter library to let it support Python. We can make that change in our favorite text editor (possibly the one we\u2019re building!) and then see the change with <code>git diff<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>~\/src\/text-editor\/lib\/syntax-highlighter$ git diff\ndiff --git a\/src\/supported-languages.txt b\/src\/supported-languages.txt\nindex ad2c90d..f4311cb 100644\n--- a\/src\/supported-languages.txt\n+++ b\/src\/supported-languages.txt\n@@ -2,3 +2,4 @@ javascript\n markdown\n java\n c++\n+python<\/code><\/pre>\n\n\n\n<p>Note the path in the terminal prompt: <code>~src\/text-editor\/lib\/syntax-highlighter<\/code>. We are making this change inside the submodule, not inside the original syntax-highlighter repository.<\/p>\n\n\n\n<p>After making the change, we can do our usual <code>git add<\/code>, <code>git commit<\/code>, and voila! We have edited our submodule. You can see this change in the text-editor repository by running <code>git diff lib\/syntax-highlighter<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>~\/src\/text-editor$ git diff lib\/syntax-highlighter\/\ndiff --git a\/lib\/syntax-highlighter b\/lib\/syntax-highlighter\nindex 8b6e157..55086f1 160000\n--- a\/lib\/syntax-highlighter\n+++ b\/lib\/syntax-highlighter\n@@ -1 +1 @@\n-Subproject commit 8b6e157f0fb785c619b99373bb474e03b1b72f54\n+Subproject commit 55086f1cb2ee8294d3354805be941171c287557d<\/code><\/pre>\n\n\n\n<p>Note that this diff just updates the commit ID that the submodule refers to. The actual changes to the submodule are not recorded in the parent repository. This leads to a really important point: to make changes to a submodule, <strong>you need push access to the original repository<\/strong>. Otherwise, the changes would be reflected in your local copy of the submodule, but nowhere else.<\/p>\n\n\n\n<p>If you didn\u2019t create the submodule, and therefore don\u2019t have push access, that\u2019s ok! You just need to fork the original repository and then use your fork as the submodule\u2019s URL.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Pulling upstream changes into a submodule<\/h3>\n\n\n\n<p>Submodules maintain a link to the upstream repository that they originate from. You can use this link to pull upstream changes.<\/p>\n\n\n\n<p>Imagine that after you added Python support to the syntax highlighting library, you hear that the maintainers have added TypeScript support. This sounds like a useful feature to include in your text editor and so you want to pull their changes. The first step is to <code>cd<\/code> into the submodule and <code>fetch<\/code> the changes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>~\/src\/text-editor$ cd lib\/syntax-highlighter\/\n~\/src\/text-editor\/lib\/syntax-highlighter$ git fetch\nremote: Enumerating objects: 7, done.\nremote: Counting objects: 100% (7\/7), done.\nremote: Compressing objects: 100% (3\/3), done.\nremote: Total 4 (delta 0), reused 4 (delta 0), pack-reused 0\nUnpacking objects: 100% (4\/4), 419 bytes | 419.00 KiB\/s, done.\nFrom github.com\/username\/syntax-highlighter\n + 49301eb...54f7bbb main       -&gt; origin\/main<\/code><\/pre>\n\n\n\n<p>It\u2019s important to <code>cd<\/code> to the submodule directory first because, otherwise, you will fetch changes for your parent repository. The <code>git fetch<\/code> shows that <code>main<\/code> has been updated on the remote repository.<\/p>\n\n\n\n<p>The changes that we want to pull in are on the <code>main<\/code> branch, so we\u2019ll need to <code>merge<\/code> them into our own branch. We can use <code>git merge<\/code> for this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>~\/src\/text-editor\/lib\/syntax-highlighter$ git merge origin\/main\nAuto-merging src\/supported-languages.txt\nCONFLICT (content): Merge conflict in src\/supported-languages.txt\nAutomatic merge failed; fix conflicts and then commit the result.<\/code><\/pre>\n\n\n\n<p>Oh no! There\u2019s a merge conflict with our branch. Thankfully in this case it\u2019s quite small:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>javascript\nmarkdown\njava\nc++\n&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD\npython\n=======\ntypescript\n&gt;&gt;&gt;&gt;&gt;&gt;&gt; origin\/main<\/code><\/pre>\n\n\n\n<p>In this case, we want to keep both changes and so we can just delete the merge conflict markers. We can now add, commit and push this change to our remote.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>~\/src\/text-editor\/lib\/syntax-highlighter$ git add src\/\n~\/src\/text-editor\/lib\/syntax-highlighter$ git commit\n&#91;add-python 98d5210] Merge remote-tracking branch 'origin\/main' into add-python\n~\/src\/text-editor\/lib\/syntax-highlighter$ git push\nEnumerating objects: 10, done.\nCounting objects: 100% (10\/10), done.\nDelta compression using up to 12 threads\nCompressing objects: 100% (3\/3), done.\nWriting objects: 100% (4\/4), 500 bytes | 500.00 KiB\/s, done.\nTotal 4 (delta 0), reused 0 (delta 0)\nTo github.com\/username\/syntax-highlighter.git\n   55086f1..98d5210  add-python -&gt; add-python<\/code><\/pre>\n\n\n\n<p>The ability to edit the code of submodules is both their most powerful feature and their most dangerous. Maintaining your own branch tangential to the main branch of a library is incredibly useful, but be prepared to face merge conflicts.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What are submodules useful for?<\/h2>\n\n\n\n<p>Below are a couple of examples of when you might want to use submodules over a dependency manager or other solution.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Libraries not in your dependency manager<\/h3>\n\n\n\n<p>Not every library is available through a dependency manager, and no dependency manager has every library. If your dependency manager doesn\u2019t support a certain library, then submodules can help you include it in your project.<\/p>\n\n\n\n<p>In this case, you should weigh up the work of maintaining a submodule against the work of adding that library to your dependency management system. Remember that submodules need to be manually updated.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Editable libraries that track upstream<\/h3>\n\n\n\n<p>Dependency managers, for the most part, aren\u2019t designed for you to modify the dependencies that they manage. If you want to make changes to a library that you depend on, then submodules might be a good solution.<\/p>\n\n\n\n<p>Submodules keep a link to the upstream code. This means that you can still pull in the latest security and bug-fix updates from the library you depend on. If you were to just copy and paste the code into your repository, getting updates from upstream would become a lot harder.<\/p>\n\n\n\n<p>An alternative in this situation is to try and merge your changes to the upstream repository. However, this isn\u2019t always practical. There might be license issues, your changes might not be accepted, and even if they are you will likely have to wait a while before they get merged.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Internal libraries<\/h3>\n\n\n\n<p>It\u2019s not always OK to publish libraries that are developed within your organization externally due to intellectual property and copyright concerns. <a href=\"https:\/\/devops.stackexchange.com\/questions\/1898\/what-is-an-artifactory\">Internal package mirrors<\/a> are one solution to this problem, as they allow you to publish packages within your organization. Submodules can be a lot simpler to manage, however, and you should weigh up the cost of keeping a submodule up-to-date against the cost of maintaining a package mirror.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">When not to use submodules<\/h2>\n\n\n\n<p>Submodules are powerful, but they come with some caveats. For starters, submodules don\u2019t have automatic update mechanisms like dependency managers do.<\/p>\n\n\n\n<p>If you add a submodule to your project, then you become responsible for keeping it up to date, whereas if you install a dependency with a dependency manager, the dependency manager can automatically keep the package on the latest version.<\/p>\n\n\n\n<p>Git doesn\u2019t download the contents of a submodule by default. This is not obvious to developers who haven\u2019t worked with submodules before and can become a trip hazard for your project. If you use submodules in your project, then it\u2019s worth thoroughly documenting development workflows in <code>contributing.md<\/code> or similar.<\/p>\n\n\n\n<p>Submodules bring increased complexity to your development workflow, so it\u2019s only worth using them if you need to. If a dependency manager will satisfy your use case, then consider using it over submodules.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Resources<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/git-scm.com\/book\/en\/v2\/Git-Tools-Submodules\">https:\/\/git-scm.com\/book\/en\/v2\/Git-Tools-Submodules<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/git-scm.com\/docs\/git-submodule\">https:\/\/git-scm.com\/docs\/git-submodule<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/github.blog\/2016-02-01-working-with-submodules\/\">https:\/\/github.blog\/2016-02-01-working-with-submodules\/<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/www.aviator.co\/\" target=\"_blank\" rel=\"noreferrer noopener\">Aviator<\/a>: Automate your cumbersome processes<\/h2>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/www.aviator.co\/\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"727\" src=\"https:\/\/blog.aviator.co\/wp-content\/uploads\/2022\/08\/blog-cta-1024x727.png\" alt=\"\" class=\"wp-image-57\" srcset=\"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/08\/blog-cta-1024x727.png 1024w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/08\/blog-cta-300x213.png 300w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/08\/blog-cta-768x545.png 768w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/08\/blog-cta-1536x1090.png 1536w, https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2022\/08\/blog-cta-2048x1454.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Aviator automates tedious developer workflows by managing git Pull Requests (PRs) and continuous integration test (CI) runs to help your team avoid broken builds, streamline cumbersome merge processes, manage cross-PR dependencies, and handle flaky tests while maintaining their security compliance.<\/p>\n\n\n\n<p>There are 4 key components to Aviator:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>MergeQueue<\/strong>&nbsp;\u2013 an automated queue that manages the merging workflow for your GitHub repository to help protect important branches from broken builds. The Aviator bot uses GitHub Labels to identify Pull Requests (PRs) that are ready to be merged, validates CI checks, processes semantic conflicts, and merges the PRs automatically.<\/li>\n\n\n\n<li><strong>ChangeSets<\/strong>&nbsp;\u2013 workflows to synchronize validating and merging multiple PRs within the same repository or multiple repositories. Useful when your team often sees groups of related PRs that need to be merged together, or otherwise treated as a single broader unit of change.<\/li>\n\n\n\n<li><strong>TestDeck<\/strong>&nbsp;\u2013 a tool to automatically detect, take action on, and process results from flaky tests in your CI infrastructure.<\/li>\n\n\n\n<li><strong>Stacked PRs CLI<\/strong>&nbsp;\u2013 a command line tool that helps developers manage cross-PR dependencies. This tool also automates syncing and merging of stacked PRs. Useful when your team wants to promote a culture of smaller, incremental PRs instead of large changes, or when your workflows involve keeping multiple, dependent PRs in sync.<\/li>\n<\/ol>\n\n\n\n<p><a href=\"https:\/\/www.aviator.co\/\" target=\"_blank\" rel=\"noopener\" title=\"\">Try it for free.<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This article covers what Git submodules are, common workflows with submodules, what they are useful for, and when you shouldn&#8217;t use them.<\/p>\n","protected":false},"author":2,"featured_media":1725,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[301],"tags":[],"class_list":["post-1716","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorials-guides"],"blocksy_meta":{"styles_descriptor":{"styles":{"desktop":"","tablet":"","mobile":""},"google_fonts":[],"version":6}},"acf":[],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/www.aviator.co\/blog\/wp-content\/uploads\/2023\/10\/git-submodules.webp","post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/posts\/1716","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/comments?post=1716"}],"version-history":[{"count":8,"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/posts\/1716\/revisions"}],"predecessor-version":[{"id":4937,"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/posts\/1716\/revisions\/4937"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/media\/1725"}],"wp:attachment":[{"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/media?parent=1716"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/categories?post=1716"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.aviator.co\/blog\/wp-json\/wp\/v2\/tags?post=1716"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}