Git - Multiple Visual Studio Solutions In A Single Git Repository

Abstract

It is not possible to use VS2022 to create a single Git repository that contains multiple VS solutions. So, we turned to SourceTree and achieved this goal. The technical details are laid out in the article.

1. Problem

The problem I had was that I wanted to post the source code from one of my articles on GitHub so that users could easily download it. The problem with that was that the source code for one article is made of four Visual Studio C# solutions. I didn’t want to merge the four solutions into one. That would not be smart, since multiple VS solutions contained a project with the same name, the evolution of the code as I explained in the article. I wanted the user to get the whole source code for the article in “one clone”, easily. Here is my folder structure:

I opened VS2022 and I was stuck. VS2022 implies that the Git repository is per VS solution. I have multiple VS C# solutions that I want to package into one repository. What to do now?

2. Checking technology: Git Submodule or Git Subtree

For a moment I thought that part of Git technology, like Submodule or Subtree, would help. But, after carefully examining them, I discovered that they are not meant to be used for such purposes. I did not want to share a library code, and want to get everything down from GitHub in one shot. I did not see that you could create “a workplace” that would contain several repositories and treat them as one from the perspective of a “git clone” in Git.

3. Solution - Creating a Single repository in SourceTree

I figured that the best I can do is create Git repository on a higher lever directory, containing the four solutions I had. That way, I will fit four solutions into one Git repository. I knew immediately that I would have branches per repository, not per VS solution.

3.1 Creating repository

I checked Git options in VS2022 and figured out that they are limited, so I would need another Git tool. I decided to use Sourcetree to create a high-level directory repository.

DO NOT COMMIT ANYTHING YET! We need to set .gitignore file first. If you do not set .gitignore file first, all your project files, like binaries and intermediate build files, will be checked into the repository, and we do not want that.

3.2 Setting .gitignore

In order to emulate the work of VS2022, I copied two files generated by VS2022: files .gitignore and .gitattributes. These were created in another C# project, and I copied them into the root of my repository and checked them in.

We did this manually because we didn't use VS2022 to create the Git repository. In this case, VS2022 would automatically create .gitignore according to the project type you select. Since we took over the responsibility of creating the repository on ourselves by SourceTree, it was our responsibility to create the correct .gitignore file.

3.3 Checking in C# VS solutions files

Then, I committed all the Visual Studio solutions files into the repository. Because .gitignore is set, the commit will ignore binaries, etc.

3.4 Create GitHub repository

Next, I created my remote repository account on GitHub and pushed the files.

You can browse the repository on the remote side and verify that no binaries or other project files have been checked into the repository. If that has happened, something is wrong with your .gitignore file.

3.5 Merging unmergeable branches

The problem that I had that I am sure will happen again to me and to other people, was that I finished with two branches: main and master. The “main” branch is created by GitHub by default and there is a readme file there. The branch “master” is created by SourceTree by default, and my code (my four VS solutions) is in it.

There is no need to have two branches here. Let's merge them and get rid of one of them. Let us keep GitHub default branch “main” and delete “master."

But there is a problem when you try to merge those two branches:

It gives an error: “fatal: refusing to merge unrelated histories

Because our two branches do not have a common ancestor commit, SourceTree thinks we are doing something wrong. However, we know we are right, and want to force it.

I looked and it says in [1] that you can not resolve that from SourceTree GUI. So, we need GitBash to run the command line Git commands. Explanation of problem and instructions are at [2].
We need to run “git merge <branch-name> --allow-unrelated-histories."

So, you can open GitBash from SourceTree (Terminal button), and execute the command. You will be prompted to enter a commit comment in the separate text editor. Then the merge will continue.

Here is how merged branches look:

Push your changes to GitHub and verify that the “main” branch has now all your files:

3.6 Deleting unneeded branch

Now you can delete the “master” branch, both locally in SourceTree and remotely at GitHub. It should look like the below now. The branch history is preserved, but there is no branch “master:"

4 Verifying solution in VS2022

Now let's see how things look from the VS2022 side. First, we get the clone URL:

Then we clone the repository in VS2022.

Here is the result. We got all four solutions at once.

By clicking on some solution, we go to it:

By clicking on the button above, we can go back to the view of all four solutions.

That is what we wanted. The only issue is that all four solutions are on the same branch, the “main” branch. The best thing you can do is probably to create a separate branch for each solution and check the code changes there.

5. Conclusion

Most of my projects are in TFS, so I was surprised how easily mightly VS2022 got defeated by the simple idea to put multiple solutions into a single Git repository. Without an external tool like SourceTree or command line, GitBash it would not be possible to do it.

Regarding Git, I thought, isn’t it an open-source project? Can it be upgraded so it has a concept of a workspace that would contain multiple Git repositories? That would save us from the nasty situation that we have now, with all four solutions on the same branch. Proper links to Git community seem to be [3], [4] ... for those that have time for that.

6. References


Similar Articles