{"id":330180,"date":"2021-08-25T14:56:02","date_gmt":"2021-08-25T11:56:02","guid":{"rendered":"https:\/\/en.buradabiliyorum.com\/how-to-use-git-subtree-to-manage-multiple-project-repositories-cloudsavvy-it\/"},"modified":"2021-08-25T14:56:02","modified_gmt":"2021-08-25T11:56:02","slug":"how-to-use-git-subtree-to-manage-multiple-project-repositories-cloudsavvy-it","status":"publish","type":"post","link":"https:\/\/buradabiliyorum.com\/en\/how-to-use-git-subtree-to-manage-multiple-project-repositories-cloudsavvy-it\/","title":{"rendered":"#How To Use Git Subtree To Manage Multiple Project Repositories \u2013 CloudSavvy IT"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_85 counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-6a371b31d3add\" class=\"ez-toc-cssicon-toggle-label\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #dd3333;color:#dd3333\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #dd3333;color:#dd3333\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/label><input type=\"checkbox\"  id=\"ez-toc-cssicon-toggle-item-6a371b31d3add\" checked aria-label=\"Toggle\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-use-git-subtree-to-manage-multiple-project-repositories-cloudsavvy-it\/#The_Problem_of_Code_Reuse\" >The Problem of Code Reuse<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-use-git-subtree-to-manage-multiple-project-repositories-cloudsavvy-it\/#Setting_Up_Git_Subtree\" >Setting Up Git Subtree<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-use-git-subtree-to-manage-multiple-project-repositories-cloudsavvy-it\/#Using_Git_Subtree\" >Using Git Subtree<\/a><\/li><\/ul><\/nav><\/div>\n<p><strong>&#8220;#How To Use Git Subtree To Manage Multiple Project Repositories \u2013 CloudSavvy IT&#8221;<\/strong><\/p>\n<div id=\"article-content-area\">\n<img loading=\"lazy\" decoding=\"async\" class=\"type:primaryImage alignnone size-full wp-image-2266\" srcset=\"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2019\/10\/e713ed70-1.png?width=398&amp;trim=1,1&amp;bg-color=000&amp;pad=1,1 400w, https:\/\/www.cloudsavvyit.com\/p\/uploads\/2019\/10\/e713ed70-1.png?width=1198&amp;trim=1,1&amp;bg-color=000&amp;pad=1,1 1200w\" sizes=\"auto, 400w, 1200w\" src=\"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2019\/10\/e713ed70-1.png?width=1198&amp;trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Git logo\" width=\"700\" height=\"299\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>Programmers often reuse code. In fact, it\u2019s one of the core principles of any good codebase\u2014Don\u2019t Repeat Yourself (DRY). What if you want to use a shared project inside multiple other repositories? The\u00a0<code>git subtree<\/code>\u00a0command can help manage that.<\/p>\n<h2 role=\"heading\" aria-level=\"2\"><span class=\"ez-toc-section\" id=\"The_Problem_of_Code_Reuse\"><\/span>The Problem of Code Reuse<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Embedding projects inside other projects presents an issue; Project 1 and Project 2 are both connected to Git, but directly using the shared subproject for both of them isn\u2019t a good design choice. This is essentially forking the subproject to use it in two places, and it\u2019s going to be impossible to maintain an official version of the subproject.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-13946\" src=\"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2021\/08\/7fa11ed7.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"\" width=\"1200\" height=\"498\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>There are a few solutions to this problem, each with their own drawbacks.<\/p>\n<p>First, the most obvious solution is to make the subproject into a package, and distribute it on a package manager like NPM or NuGet. This works very well for things that are not updated or maintained often, and can afford to be distributed to their consumers in discreet version numbers. However, if you\u2019re changing this code on a regular basis, having to integrate, publish, and pull new versions of the project from a third party source simply does not work as well as having the code directly accessible. It also introduces complications for local development.<\/p>\n<p>The other solution is to use a\u00a0<em>monorepo<\/em>, one giant repository for all your code. This isn\u2019t as crazy as you might think, and works well if all your code is in the same domain; Google uses a monorepo for all their code, and Microsoft u<a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/dotnet\/runtime\/tree\/main\/src\/libraries\">ses one for all .NET assemblies<\/a> they maintain. This solves the problem, because if you modify code in the subproject, it will be updated whenever you re-build. In Visual Studio, this can be done easily with <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/docs.microsoft.com\/en-us\/visualstudio\/ide\/managing-references-in-a-project?view=vs-2019#project-to-project-references\">Project References<\/a>.<\/p>\n<p>However, there are many cases where you\u2019d want the best of both worlds\u2014maintaining it centrally as a package, but also allowing direct embedding and editing in multiple projects. For this, Git Subtree provides a solution.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-13949\" src=\"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2021\/08\/56ffd4a7.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"\" width=\"1200\" height=\"507\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>The core concept is pretty simple: you can have smaller Git repos, with their<\/p>\n<p>Usually, Git is smart enough to handle pushing and merging automatically, depending on which changes came from which subtree. It\u2019s good practice though to not mix commits between subtree code and main project code, as there are cases where you can <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/git-scm.com\/book\/en\/v2\/Git-Tools-Advanced-Merging#_subtree_merge\">run into a more complicated merge<\/a>\u00a0that requires you to use the underlying Git tools that <code>git subtree<\/code>\u00a0wraps.<\/p>\n<h2 role=\"heading\" aria-level=\"2\"><span class=\"ez-toc-section\" id=\"Setting_Up_Git_Subtree\"><\/span>Setting Up Git Subtree<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>If you just set up an empty project, and are going to set up subtrees, you\u2019ll need to make an initial commit\u2014even if it\u2019s empty\u2014or else Git will throw an error about an ambiguous HEAD. You can make an empty commit with the following command:<\/p>\n<pre>git commit --allow-empty -n -m \"Initial commit.\"<\/pre>\n<p>You\u2019ll want to add the remote for the subproject, and give it a name. You\u2019ll use this name to refer to it:<\/p>\n<pre>git remote add -f SubTreeName https:\/\/github.com\/user\/project.git<\/pre>\n<p>Then, you can add the subtree, at the given prefix. Use the <code>--squash<\/code>\u00a0command so that the entire subproject history is not stored in the main project.<\/p>\n<pre>git subtree add --prefix .Path\/To\/SubTree SubTreeName master --squash<\/pre>\n<h2 role=\"heading\" aria-level=\"2\"><span class=\"ez-toc-section\" id=\"Using_Git_Subtree\"><\/span>Using Git Subtree<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>When you need to pull, Git will only update the main project automatically, so you\u2019ll have to fetch the remote, and then use a subtree-specific pull command. It\u2019s a little lengthy, as you need to pass in the prefix, but gets the job done:<\/p>\n<pre>git fetch SubTreeName master<\/pre>\n<pre>git subtree pull --prefix .Path\/To\/SubTree SubTreeName SubTreeName master --squash<\/pre>\n<p>Note that you can fetch commits from the remote, but pulling them into the subtree, or pushing them to the remote, requires you to use <code>git subtree<\/code>\u00a0specifically.<\/p>\n<p>When it comes time to contribute back upstream, you\u2019ll need to use <code>git subtree push<\/code>:<\/p>\n<pre>git subtree push --prefix=.Path\/To\/SubTree SubTreeName master<\/pre>\n<\/div>\n<blockquote><p><strong><span style=\"color: #ff6600;\">If you liked the article, do not forget to share it with your friends. Follow us on\u00a0<span style=\"color: #ff0000;\"><a style=\"color: #ff0000;\" href=\"https:\/\/news.google.com\/publications\/CAAqBwgKMLG0nwswvr63Aw\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Google News<\/a><\/span>\u00a0too, click on the star and choose us from your favorites.<\/span><\/strong><\/p><\/blockquote>\n<blockquote>\n<p style=\"text-align: center;\">For forums sites go to <span style=\"color: #ff9900;\"><a style=\"color: #ff9900;\" href=\"https:\/\/forum.buradabiliyorum.com\/\" target=\"_blank\" rel=\"noopener\">Forum.BuradaBiliyorum.Com<\/a><\/span><\/strong><\/p>\n<\/blockquote>\n<blockquote>\n<p style=\"text-align: center;\"><strong>If you want to read more like this article, you can visit our <span style=\"color: #ff9900;\"><a style=\"color: #ff9900;\" href=\"https:\/\/en.buradabiliyorum.com\/technology\/\" target=\"_blank\" rel=\"noopener\">Technology category.<\/a><\/span><\/strong><\/p>\n<\/blockquote>\n<p><span style=\"color: black;\"><a style=\"color: #ff9900;\" href=\"https:\/\/www.cloudsavvyit.com\/13908\/how-to-use-git-subtree-to-manage-multiple-project-repositories\/\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8220;#How To Use Git Subtree To Manage Multiple Project Repositories \u2013 CloudSavvy IT&#8221; Programmers often reuse code. In fact, it\u2019s one of the core principles of any good codebase\u2014Don\u2019t Repeat Yourself (DRY). What if you want to use a shared project inside multiple other repositories? The\u00a0git subtree\u00a0command can help manage that. The Problem of Code&#8230;<\/p>\n","protected":false},"author":1,"featured_media":330181,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2019\/10\/e713ed70-1.png","fifu_image_alt":"","footnotes":""},"categories":[18],"tags":[],"class_list":["post-330180","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-technology"],"_links":{"self":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/330180","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/comments?post=330180"}],"version-history":[{"count":0,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/330180\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media\/330181"}],"wp:attachment":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media?parent=330180"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/categories?post=330180"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/tags?post=330180"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}