GIT Submodules in Visual Studio
A submodule allows us to add a reference to another repository for re-use while allowing that submodule to maintain its separate version history.
NOTE: If you are well-versed in Git and do most of your commands in the bash, this article is not for you but for those who try to stay in the IDE as much as possible.
Imagine a life where you've decided to create a utility class library that will serve common logic to a range of company programs. This is ideal as it reuses code and allows for a single point of development. But then you need to distribute this utility library for consumption in other programs.
You may quickly find that Visual Studio does not give you the single DLL file you were hoping for, but instead builds a folder full of related DLLs and dependencies. To distribute this you would need to either distribute the whole folder or get a DLL bundler to help produce a single DLL (like ILRepack/ILMerge - not covered here). This is an article about repository control, so a single distributed DLL or folder definitely has its benefits when it comes to version control - every project has its own repo in the sky. If you are trying to distribute a black box/managed DLL file then this is probably what you want to do, but consider what you would also need to do in order to redistribute updates or newer versions. If a black box DLL solution is not a requirement then there are other ways.

Another way to skin this cat is to add a linked existing project to your consuming solution. The benefit is that now your consuming projects can troubleshoot/debug the utility class within their realm more easily. The double edged sword here is access. You can make changes in the utility project and they will automatically be seen in the consuming solutions (they are looking at the same code). In a multi-user environment this is bad as other users would need access to the files and could make unmanaged changes to the utility class code base. What happens if you are making changes as someone else is debugging or publishing? Additionally, without adjusting the solution scoped git ignore in Visual Studio, you will end up with duplicated commits in your GIT repository.

GIT submodules give a us a better way of dealing with this. A submodule allows us to add a reference to another repository for re-use while allowing that submodule to maintain its separate version history. Although we can't directly set this up in Visual Studio, it does respect the submodule and give us ways to work with them. The benefit here is that consuming projects can debug and make updates to the utility class in the scope of their consuming project. They can push these changes to the repository branches of the utility class for versioning control (pulls and conflict resolution are along for the ride). The drawback is that now there are multiple copies of the utility project out there potentially using large amounts of data. In a distributed multi-developer scenario this is probably less of a concern, but if a developer has several consuming projects or the library is large you should look at a hybrid approach - (the following note's for you).
NOTE: If you have a large library or are avoiding multiple copies, another approach would be to have the developer of the consuming project check out a branch of the utility solution. They can then link this as an existing project (as it sits on their machine), adjust the GIT ignore on each of these projects, and now they only have one copy of the utility class for all of their projects. Additionally, changes they make to their copy are only propagated through GIT controls.

Using Submodules With Visual Studio
Starting Point
The first step is to have repositories setup for both your consuming and utilities solutions. At this point your consuming solution should be fairly new with no references to the utility solution yet...we will walk through that here. The assumption is that you can also commit/push both projects to the remote. You should have GIT bash installed as Visual Studio can't add the submodule on its own.

Adding the Submodule
Open GIT bash to the root folder of your consuming project (usually as easy as right clicking once GIT is installed).

Now run the GIT submodule command.
git submodule add <url-to-UtilitiesRepo> UtilitiesRepoThese images provide some more insight into this command.


Notice that this copied the repository code into our project in a new folder we specified.
Referencing the Submodule
Now in our consuming project, it's time to reference our utility submodule. Visual Studio won't list the folder until we add it as a referenced project. Right click the Solution (not the project) and add the existing project.


Make sure you browse to the copied code in your consuming project and not where the original project is (if they are on the same computer). The submodule reference is for this copied code. After this project is added, add a project reference inside your consuming project.

If we now flip over to the Git changes tab, we will see that the submodule reference is part of our staged changes. We can push and commit this out to our repository. When it gets to our remote, there will just be a listing that shows theres a submodule link (it will not copy the code into the consuming project's repository).

Getting Visual Studio On Board
At this point, there isn't much difference in Visual Studio. In fact, if you make changes to code at this point you may not even see changes listed in the Git menu.

But after a restart, the Git menu will list 2 repositories we can select from, manage branches from, and push/pull from.

Have fun with that.