Git worktree vs submodule

Git worktree vs submodule

Git worktree vs submodule
Clean coder. Rock climber. Recently, I was in a situation in which I really needed two separate copies of my Git repository. I was about to make a full clone of the repository, but I decided to see if Git had a better solution. And in fact, Git introduced the worktree feature not too long ago as of version 2. All you need to do is set up a new worktree like this:. This will set up the directory. You can create this directory anywhere on the same filesystem, but it should be somewhere outside of your main repository directory! You can then proceed to use the worktree directory as usual, checking out branches, pushing upstream, etc. In a large project with very good test coverage, some test suites can take a long time to run—far beyond a convenient amount of time to sit and wait for them to finish. Many IDEs allow opening multiple projects at once, but each must be in its own directory. You could git clone two entirely separate repositories, but worktrees are better:. I frequently keep an extra worktree around just for running tests. I get around this by creating local temporary branches, like so:. I use the TEMP prefix to emphasize that the branch is temporary my shell prompt includes the name of the current branch, so this practically yells it at me. What you really need is to see both versions simultaneously so you can compare things side-by-side or even run both versions at the same time. You can easily check out a previously tagged version or any arbitrary commit in a worktree. Switching branches may also have undesired side effects depending on your project for example, causing an IDE to re-index. Everybody has probably had the experience of a build failure because a co-worker forgot to include some files with a commit. It could be that they forgot to add the files to Git, or perhaps some. If the build works for them but not for you, then you may be missing some files. One way to find out is to test it against a working copy that you know to be clean. Since worktrees give you a clean checkout, they can be used to verify that all of the files that need to be included have been added to Git.

Git submodule

During development of DbLocalizationProvider I had single repository in GitHub containing more that one package as result of the build. Initially there was just a EPiServer package to add support for database driven localization resources. Later realized that there is actually not so much to do to add support for Asp. Net Mvc. NET Framework applications and later also for. NET Core applications. As you can see there might be some issue with having multiple purpose packages with different life-cycles and versions located in single Git repository. So decided to split whole code-base into git submodules and setup separate repositories for each of the sub-systems. This is a blog post about the stuff I had to do. It's important to understand where each module ends and where next begins as you be referencing each other through sort of NuGet package references. Decision has to be made around type locations - where each type should go and which project will be used where. Actually for development purposes using ordinary project reference is much more preferred way to work with. This gives nicer debugger experience for developer without any hustle to enable symbols and be able to "step into" the package source code. Now when you have decided module boundaries it's time to create repositories for each of the module. After we have main module repository available, we can create new one for Asp. Net Mvc aspnet packages. Now tricky part is that I would like to include source from main repository as part of the solution - like normal projects. Then I would be able to debug it through, change and adjust on-demand if needed, etc. We need to " include " projects from main repository into aspnet repository. This is achievable by "linking" main repository content into aspnet. Keep in mind that linking is possible by pointing to some directory under which linked repository content will be "cloned". Information about just added submodule is written in. This is very important to remember that submodule linking sets included submodule into detached HEAD state. Meaning that when working with submodules - this rare git case becomes norm. As you would like to refer to particular commit and not tracking branch, which is essentially a moving target. You want to "lock down" yourself to specific version of the submodule. This applies only to. Once you have linked main under aspnet - you need to make couple of changes for the IDE to understand new structure. Adding reference to NuGet package in Asp. Net Mvc repository Visual Studio will create following reference hint path:. Which looks quite good when working in Asp. Net Mvc repository. However, this will become problem when we will link aspnet repository one level up - in epi.

Git subtree vs submodule

By using our site, you acknowledge that you have read and understand our Cookie PolicyPrivacy Policyand our Terms of Service. The dark mode beta is finally here. Change your preferences any time. Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information. Your main project will still track the hashes of the HEAD of the submodule even if --remote is used though. With git submodules you typically want to separate a large repository into smaller ones. The way of referencing a submodule is maven-style - you are referencing a single commit from the other submodule repository. That way you have to have access to both repositories for the complete build. With git subtree you integrate another repository in yours, including its history. So after integrating it, the size of your repository is probably bigger so this is no strategy to keep repositories smaller. After the integration there is no connection to the other repository, and you don't need access to it unless you want to get an update. So this strategy is more for code and history reuse - I personally don't use it. Learn more. Differences between git submodule and subtree Ask Question. Asked 4 years, 8 months ago. Active 3 years, 1 month ago. Viewed 78k times. What are the conceptual differences between using git submodule and subtree? What are the typical scenarios for each? Nathan H Nathan H This may not answer all your questions but is interesting reading on the subject: blogs. Similar question is stackoverflow. Active Oldest Votes. You keep only references in your parent repo gitlinksspecial entries in the index What if I want the links to always point to the HEAD of the external repo? See an example in this answer. VonC VonC k gold badges silver badges bronze badges. I see the submodule followship behavior is also mentioned in your other anwer. In that case I think you mean to say that always pointing to the HEAD of a submodule is accomplished by using both add -b and --remote thereafter on the update commands, as per the submodule update documentation. In that case, is the -b really still required for following HEAD of master? Then it has little to do with enabling --remote - --remote works also if -b hasn't been used on add. In both cases the update will cause a commit in the parent repo housing the submodule, so the links do not really "always point to the HEAD" in a very automatic way Feng Feng 3, 1 1 gold badge 10 10 silver badges 9 9 bronze badges. The conceptual difference is: With git submodules you typically want to separate a large repository into smaller ones. Niklas P Niklas P 2, 2 2 gold badges 12 12 silver badges 16 16 bronze badges. But with git subtree you still can also push - if you wanted - right? FranklinYu Why would he not know that? NiklasP - can you elaborate on "reference the new commit in the main repository"? That's the one step I'm not clear on how to execute and therefore "changed reference" isn't something I understand either. Maciek Rek Maciek Rek 1 1 gold badge 7 7 silver badges 17 17 bronze badges. JBramble I should probably mention that it's done with the SourceTree app eg: git -c diff.

Git work-tree

This is a common topic while managing Git repositories. Sometimes, you need to have one or many repositories withing another repository. The laziest way to do it is having a monorepo. A Git monorepo is when a team develops multiple projects, related or not, in a single Git repo, in order to make it easy to share code between different projects. As example, if you have a library that you want to use in different projects, you just put it in its own folder and reference in your projects:. This is very easy to do. To do so, Git have two buildin features to make this work, Git submodules and Git subtrees. We can think of submodules as a kind of link that points to another repository. As example, imagine we are starting a repo for a web application. This repo will contain both server-side and client-side code. Now, imagine we will add Pikaday as a submodule, since we will need it in our web app. Doing that is as simple as doing:. It contains what submodules we have and its clone path. Internally, Git stores the submodule as a simple text file, with the exact commit ref it points to:. This means that the Pikaday source was not commited to the repository when we did the commit. Remember, a Git submodule is just a link to a specific ref in another repository. In order to have that, they will have to run:. There are many gotchas you have to be aware when dealing with submodules. One of them is that Git often keep your submodules checked in detached heads. Imagine we want to make a change in the Pikaday repo. First, we need to make sure we are checked in a branch often master :. Another gotcha: even after making changes to Pikaday, we have to manually update the ref in the outer repo:. These and other problems make many people prefer subtrees over submodules, which we will see next.

Git worktree remove

Visual Studio now treats Git submodules and Git worktrees like normal repos. Please note that you still cannot do anything that requires multi-repo support such as viewing files in a parent repo and a submodule at the same time. If you would like multi-repo support, please vote on UserVoice. Ever delete a branch on the server, only to see it listed in your local list of branches? The best way to make sure your local list of branches is up-to-date is to use the --prune option when you fetch. Pruning on fetch removes local tracking branches that no longer exist on the server. Another common Git practice is to rebase your changes rather than create a merge commit when you pull. Rebasing helps keep your commit history linear and easy to follow. Log in to join the discussion. Sasha Rosenbaum Senior Program Manager. Edward Thomson Principal Program Manager. Erin Dormier Principal Program Manager. Gloridel Morales Senior Program Manager. Anisha Pindoria Senior Program Manager. Learn more about Azure DevOps. Azure DevOps Feature Timeline. DevOps at Microsoft. Visual Studio blog. This site uses cookies for analytics, personalized content and ads. By continuing to browse this site, you agree to this use. Learn more. December 8th, Schaub December 15,

Git config worktree

Git worktree vs submodule
In this post I explain why. Every organisation has code that is shared between projects, and submodules and subtrees prevent us from duplicating code across those projects, avoiding the many problems that arise if we have multiple versions of the same code. The simplest way to think of subtrees and submodules is that a subtree is a copy of a repository that is pulled into a parent repository while a submodule is a pointer to a specific commit in another repository. It also means that subtrees are much easier for other people to come and pull, as they are just part of the parent repository. Both the advantage and disadvantage of submodules is that they can and should be treated as a repository of their own. They will need to be committed to separately, and can be branched separately. You may already be able to see some of the issues that can occur if you ignore the fact that the submodule needs to be kept up to date:. Any changes from the last committed submodule commit will be listing as modified, and can be included in the next commit to the parent repository. The only difference between making changes to code within a submodule directory and a regular directory is that we must commit and push to the submodule repository before then moving up a directory and committing the pointer to the new submodule commit and pushing that to the remote of the parent repository. When the contents of a submodule folder have been modified they appear as a single line if we run git status in the parent repository:. This output from git status can be confusing, because it looks like only a single file has changed, when in fact there could be massive changes within the submodule directory. If I move up a directory, I will then be back in the parent repository, and I will see that the submodule has a new commit:. So I need to make sure that after a submodule commit I also push:. That may seem quite convoluted, but we are dealing with two separate repositories, so there is always going to be twice as much work. The order in which you commit and push changes when working with submodules is so important that I consider it the golden rule of modifying submodules…. Always commit and push the submodule changes first, before then committing the submodule change in the parent repository. Without following this rule you can get into a confusing state in which the parent repository is pointing to a submodule commit that only exists on your local machine. Issues with submodules tend to arise due to the poor tooling. This stale submodule can cause the entire project to get into a mess. If you define an alias which runs git submodule update after every single git pull then you will be safe, but a newbie is unlikely to do this. The first is the squashing down of the entire history of the remote repository that we are cloning:. And as with submodules, this is both an advantage and a disadvantage. The command will also create a similar set of commits to the earlier add. Things get really tricky when we need to push commits back to the original repository. This is understandable because our repository has no knowledge of the original repository, and has to figure out how to prepare the changes so that they can be applied to the remote before it can push. In my experience how long this takes to run depends on the amount of history in the parent repository, your OS, and your machine. After so many issues with submodules I had high hopes for subtrees, but was quite disappointed. For a start there is very little documentation. In my opinion subtrees are not a direct replacement for submodules. The way I believe you should split your shared code between subtrees and submodules is this:. View all posts by Martin Owen. That is, a clone of a module with a subtree gets the subtree with no knowledge or further action needed but with a submodule one has to either use —recursive on the clone command or issue a submodule init and update after cloning the parent. I thought subtree was a better choice, after took two days used it for one of our big project, I encountered exactly same problem you mentioned. I took advice from the Mercurial camp on subrepos. Then you get the benefit of getting everything in mostly one go yet with less risk of losing changes. You can also control who has write access to the submodules repo so as to avoid collisions. This is by far the best information I could find on submodules vs. Many thanks for taking the effort to document your experience.

Git submodule update

Apr Posted by Amber. It is not uncommon at all when working on any kind of larger-scale project with Git to find yourself wanting to share code between multiple different repositories — whether it be some core system among multiple different products built on top of that system, or perhaps a shared utility library between projects. This means that if someone else updates the recorded version of a submodule and you pull their latest changes in the parent repository, your submodule repository will still be pointing to the old version of the submodule. When you invoke git submodule update it looks in the parent repository for a SHA for each submodule, goes into those submodules, and checks out the corresponding SHAs. If you then make changes in the submodule and commit then, Git will happily create the commit… and leave you still with a detached HEAD. See where this is going yet? Say you merge in some more changes which happen to include another submodule update. Submodules acting as almost completely independent repositories has another catch, too — you have to push changes from both the submodule and the parent repository to share with others. Push changes from the submodule and not the parent repository? No one knows to use your new submodule changes. Push changes from the parent repository and not the submodule? So if submodules are such a pain, what are the alternatives? Which one is best for you depends on your priorities. Repo is a tool created by Google to manage the rather large Android project, which is spread across multiple different Git project repositories. It essentially works by providing a way to check out multiple projects Git repositories in parallel based on a manifest file which basically serves the purpose that a parent repository does for Git submodules — tracking which submodule commits go together. It also provides a way to submit an atomic changeset that includes changes to multiple different projects. Gitslave is a wrapper around Git that multiplexes git commits into multiple repositories. If you commit, all of your repositories create a commit, and so on. Of course, this can get rather hectic if you have a large number of projects and start running into things like merge conflicts in 5 different repositories. Posted on April 28,in Software Development and tagged git. Bookmark the permalink. What you should be doing is checking out to a specific TAG in your submodule. This will alleviate Submodules are for things such as commonly reused libraries, not for some afternoon hack attack someone threw up all over the repository. The real meat of your comment though seems to be your specification regarding separate versioned packages. I actually agree with you — that is the use case that submodules actually work for. We used submodules for a while in our team.

Git worktree move

Git worktree vs submodule
A git repository can support multiple working trees, allowing you to check out more than one branch at a time. With git worktree add a new working tree is associated with the repository. This new working tree is called a "linked working tree" as opposed to the "main working tree" prepared by "git init" or "git clone". When you are done with a linked working tree, remove it with git worktree remove. If a working tree is deleted without using git worktree removethen its associated administrative files, which reside in the repository see "DETAILS" belowwill eventually be removed automatically see gc. If a linked working tree is stored on a portable device or network share which is not always mounted, you can prevent its administrative files from being pruned by issuing the git worktree lock command, optionally specifying --reason to explain why the working tree is locked. The new working directory is linked to the current repository, sharing everything except working directory specific files such as HEAD, index, etc. If the branch exists in multiple remotes and one of them is named by the checkout. Set it to e. See also checkout. List details of each worktree. The main worktree is listed first, followed by each of the linked worktrees. The output details include if the worktree is bare, the revision currently checked out, and the branch currently checked out or detached HEAD if none. If a working tree is on a portable device or network share which is not always mounted, lock it to prevent its administrative files from being pruned automatically. This also prevents it from being moved or deleted. Optionally, specify a reason for the lock with --reason. Move a working tree to a new location. Note that the main working tree or linked working trees containing submodules cannot be moved. Remove a working tree. Only clean working trees no untracked files and no modification in tracked files can be removed. Unclean working trees or ones with submodules can be removed with --force. The main working tree cannot be removed. This option overrides these safeguards. To add a missing but locked working tree path, specify --force twice. To remove a locked working tree, specify --force twice. By default, -b refuses to create a new branch if it already exists. With adddetach HEAD in the new working tree. See "Sparse checkout" in git-read-tree[1]. This can also be set up as the default behaviour by using the worktree. See "--track" in git-branch[1] for details. Keep the working tree locked after creation. This is the equivalent of git worktree lock after git worktree addbut without race condition. With listoutput in an easy-to-parse format for scripts. This format will remain stable across Git versions and regardless of user configuration.

Git subtree tutorial

I thought the following notes might be useful to other folks making the leap as well. At Crowd Favorite we write modular code for example: lots of lean, targeted WordPress plugins instead of few complex plugins for a number of reasons:. To support this approach we previously made extensive use of SVN externals in our projects. Often times active development would be happening on a specific project and within one or more of the externals within the project to support a new feature, etc. With SVN externals, the included externals are automatically updated to the latest version on every update unless you —exclude-submodules. With a standard SVN checkout, all of your externals get populated and are ready to go right away. With Git submodules, an additional step is required after a git clone. From inside the newly cloned repo at the top levelyou have to initialize and update the submodules:. Git submodules work in a somewhat similar fashion in that you need to commit the changes to the submodule first; but there are also some additional steps involved. Make sense? Basically, you commit to the Git submodule separately just like you used to commit to your SVN external. This is useful for situations where multiple people are updating a project that is being used as a submodule by multiple parent projects. That way when bugs or issues are found they are logged against the proper version of the package in question. When questions about a submodule version arise does it include feature X? Hopefully this helps you get your head around the differences between SVN externals and Git submodules. Overall I like the implementation of Git submodules better now that I understand what they are trying to do. In fact, many of our plugins interoperate by implementing hooks and filters in the same manner WordPress core does. As previously noted here, our careers page is a little differentand we believe in a healthy work-life balance. This post is part of the thread: Version Control — an ongoing story on this site. View the thread timeline for more context on this post. Thankfully with Git 1. This is equivalent to running git submodule update --init --recursive immediately after the clone is finished. Enjoyed the article, gave you a tip by starting a tip jar for you. At Crowd Favorite we write modular code for example: lots of lean, targeted WordPress plugins instead of few complex plugins for a number of reasons: it enables code reuse DRY smaller bits of code are easier to maintain, update, debug, etc. Submodules require extra steps when cloning With a standard SVN checkout, all of your externals get populated and are ready to go right away. From inside the newly cloned repo at the top levelyou have to initialize and update the submodules: git submodule update --init --recursive This step will get all if your submodules setup, pointing to the proper refs, etc. View March 5, Alex replied:. Very cool, that definitely makes things easier. Adding a Git alias for this now! View March 6, Boris R. View May 15, Ross McKay. View July 18, Excellent, just the kick start I was looking for. And for WordPress plugins too! #Commitmas Follow-Up Git worktree with Igor Galic (@hirojin)

Posted in yir

thoughts on “Git worktree vs submodule

Leave a Reply

Your email address will not be published. Required fields are marked *