If you have worked on projects in a team environment, or if you need a place to keep your own code safe, then you’ll agree that using a source control solution is essential. It doesn’t matter if it’s a large enterprise solution or a small Pet project, Visual Studio makes it extremely easy for developers to use Git and GitHub.
Git is a tool that developers install locally on their machine. GitHub is an online service that stores code safely that has been pushed to it from computers using the Git tool.
In 2018, Microsoft acquired GitHub for $7.5 billion in Microsoft stock. This acquisition of GitHub brought about changes to their pricing tiers. Previously, developers could only create public repos on the free tier. In January 2019, however, GitHub announced that developers can now create unlimited private repositories on the free tier.
This is great, especially if you are working on a side project that you do not want to share with anyone just yet. In this chapter, we will be looking at using Git and GitHub inside Visual Studio 2022. We will see how to
Create a GitHub account
Create and clone a repository
Commit changes to a repository
Create a branch from your code
Create and handle pull requests
These are all things that developers will do on a daily basis when working with Git and GitHub. While the process might change slightly if you use a different source control strategy, the concepts remain the same.
Create a GitHub Account
Let’s start off with creating a GitHub account. Point your browser to www.github.com, as shown in Figure 5-1, and create an account by clicking the signup button.
Enter a username (Figure 5-1), email address, and password. GitHub then checks your password to verify that it does not appear on a list of known compromised passwords. If all checks out, a confirmation code is sent to your email address. After verifying your email address, GitHub will take you through a short personalization process before finally offering you an option to sign up for the Team account or continuing with the free account.
After entering your details, you will be taken to your dashboard. You can continue using the free account, but there is also the option to upgrade to a Pro account. The free subscription offers the basics suitable for most developers, while the pro subscription offers several more features. The free subscription is very generous and will appeal to most developers. The free subscription includes the following, among others:
Unlimited public and private repositories
Three collaborators for private repositories
Issues
Project tables and boards
Pages and wikis for public repos
GitHub Actions (2000 minutes/month) or free for public repos
The pro subscription, on the other hand, offers more which includes
Unlimited public and private repositories
Unlimited collaborators
Issues
Project tables and boards
Repository insights
Automatic code review assignment
GitHub Actions (3000 minutes/month) or free for public repos
GitHub Team on the other hand allows a team of developers to collaborate on projects, and GitHub bills for GitHub Team on a per-user basis.
After creating your account on GitHub, you will be sent a welcome email with additional information and links to get you started. GitHub uses repositories to store your code, and you would create a repository for each project you want to work on. Clicking the Create repository button will take you to the Create a new repository page. If not, you can access your repositories from the menu under your profile image. This will take you to your repositories page from where you can create your first repository as seen in Figure 5-2.
The next logical step is to create a repository for your new project. Let’s have a look at that in the next section.
Create and Clone a Repository
Visual Studio 2022 makes it extremely easy to create a repository on GitHub. I have created a simple Windows Forms application called PetProject in Visual Studio that just contains some boilerplate code. This is only temporary. Before I start writing actual code, I want to set up my GitHub repo. From the menu in Visual Studio, select Git and click Create Git Repository as seen in Figure 5-3.
You will then be presented with the Create a Git repository window as seen in Figure 5-4. The window will default the local path to the path that your project is currently saved in. I always add a README file to my repos and keep the rest set to the default options regarding the license template and .gitignore template.
Because I already have a GitHub account, the Account drop-down will default to that account. If you do not have a GitHub account, you can add a GitHub account from the drop-down. When you click Add a GitHub account, you will be taken to your account on GitHub to authorize Visual Studio as seen in Figure 5-5.
After authorizing Visual Studio, you will be prompted for your GitHub password and then redirected back to Visual Studio where the Create a Git repository window will display the connected GitHub account as seen in Figure 5-6.
You can now click the Create and Push button that will create the repo on GitHub for you. This will also create a new local Git repository for your solution. Open up the Output Window (Ctrl+Alt+O) from the View menu and click Output. Here, you will see that a new local Git repository has been created (Figure 5-7).
It is important to remember that this project is now under source control using Git. Remember that we mentioned earlier that Git is the source control plumbing, the tool that developers install locally on their machines.
If you never want a backup of your code in the cloud, or never want to collaborate with other developers, you can just use Git. This is, however, a quite unlikely scenario, especially now that GitHub allows you free private repositories.
Therefore, you pushed your code to a GitHub repository after connecting your account. You can see that the repository has been created for you by going to your GitHub account as seen in Figure 5-8.
There you will see the Private PetProject repo you just pushed from Visual Studio.
Next to the Solution Explorer, you will see the Git Changes tab as seen in Figure 5-9. Currently, there are no changes in our project to commit.
Make some UI or code changes to your project, and you will see that the Git Changes window will be updated to display all the changes that have not been committed to your Git repo as seen in Figure 5-10.
Enter a commit message as seen in Figure 5-11 and then click the drop-down arrow next to the Commit All button.
Here, you can see the options for committing your code as seen in Figure 5-12. You can simply commit all your changes, commit and push to the remote repo, commit to the remote repo and do a sync, or stash your code.
We are just going to commit the changes without pushing to the remote repo.
Remember, the Commit All will create the changes locally. Nothing will be created on the remote GitHub repo yet.
After clicking the Commit All option, the Git Changes tab will tell you that the changes were committed locally and display the commit ID (in this case, c3371328) as seen in Figure 5-13.
You might want to commit locally while working on code, and you are not quite ready to push the changes to the remote. This is a nice workflow to follow. Make some changes, commit locally with a specific commit message, make some more changes, commit again with another commit message, and so on.
Note
Each commit message and ID will also be visible on GitHub along with the files that have changed.
When you have completed the changes, and committed everything locally, you can push these changes to the remote repo by clicking the Push arrow as seen in Figure 5-14.
Doing this will push the changes to GitHub, and you will be notified in the Git Changes tab that your changes have been pushed to the remote repo on GitHub as seen in Figure 5-15.
If you go to your GitHub repository, you will see that the code you pushed is displayed in your repo (Figure 5-16) along with the commit message entered earlier in Figure 5-11.
It is also nice to remember that if you have made changes to a file that you have not committed yet and want to change the file back to the state it was since the last commit, you can undo these changes easily. As seen in Figure 5-17, I have made some changes to the README file that I no longer want.
By right-clicking the file as seen in Figure 5-18 and selecting Git ➤ Undo Changes from the context menu, you can revert the file back to the state it was after the last commit.
This is nice, especially when you have made some debug-specific changes to a config file that you do not want to commit to source control.
Cloning a Repository
What I want to do now is have another colleague of mine contribute to my project. Seeing as this is a private repository, I need to invite him to collaborate. In GitHub, go to the settings tab in your repository. Then click Collaborators as seen in Figure 5-19.
The free account can have three collaborators, so this will be using one of your allotted collaborators. You can now add collaborators to your repository by searching for their GitHub username and adding them as a collaborator. In this example, I will add myself as a collaborator. I will now receive a notification in my inbox that @acsharpdev wants me to work on his project with him (Figure 5-20).
Once I accept the invitation, I will have push access to the project. The @acsharpdev user will now see me as a collaborator under the collaborator’s tab in GitHub. To start working on the code, I need to clone the repository to my local machine. Start Visual Studio, and then click the Clone a repository option under the Get started section of the Visual Studio start screen (Figure 5-21).
This will take you to the Clone a repository screen as seen in Figure 5-22.
From this screen, you can enter the repository location to get the code from, but because I am a collaborator on this GitHub project, I can simply click the GitHub option (Figure 5-22).
This will display the Open from GitHub screen (Figure 5-23).
It is here that I will see the project that I have been invited to under the Collaborator repositories. Select the project, ensure that the local path is correct, and click the Clone button. The Visual Studio project is then cloned to my local machine. In previous versions of Visual Studio, you would see the repo in the Team Explorer window. Opening Team Explorer in Visual Studio 2022, you will see that the Git features have moved to their own window (Figure 5-24).
I now have cloned the repository to my local machine, and I can now collaborate with @acsharpdev on his project and share my changes with him easily.
Create a Branch from Your Code
A new feature needs to be added to the Pet project. It would be better for me to work on the changes to the project in an isolated manner. To do this, I can create a branch in Git. A branch allows me to make changes to the code without changing the code in the main branch, also called the master branch. In Visual Studio, I can see that I am currently working on the master branch if I look at the bottom-right status bar in Visual Studio (Figure 5-25).
To create a new branch, click the current branch to open the Branches view (Figure 5-26).
I will now create a local branch in Visual Studio. To do this, click the New Branch button in the Branches view.
I can now give my new branch a suitable name (Figure 5-27) and tell it to create the branch from the master branch. I keep the Checkout branch selected to check out my new branch and click the Create button.
As seen in Figure 5-28, my new local branch is created and checked out. When I look at the bottom-right status bar in Visual Studio, I see that the new feature branch is checked out (Figure 5-29).
This means that from now on, all changes made to the code will stay in this branch. Let’s add some new code to the project.
As seen in Figure 5-30, I have added a new class called CoolFeatureClass that contains the new code I added. I must now commit the changes to my branch. In the Git Changes tab, I can see the code that I have changed in my branch (Figure 5-31).
You can see that the SuperCoolFeature branch is still selected. Under the changes section, you will see all the files that I have changed. Before you commit your code, you need to add a suitable commit message. Then I can click the drop-down next to the Commit All button and select Commit All and Push (Figure 5-32).
This will commit the changes to the local repo and then push them to the remote repo. If you click the SuperCoolFeature branch and view the Remotes tab, you will see that your feature branch has been pushed to GitHub (Figure 5-33).
The code is now safely on the GitHub repo. How do I get my changes into the master branch? For this, we will be creating a pull request.
Creating and Handling Pull Requests
The term pull request might sound strange to some folks that aren’t used to working with a source control system. The “pull” means to request that your code be pulled into the main working branch of the source code. Some developers also refer to a pull request as a merge request.
In Visual Studio, we can easily create a pull request. By doing this, we are telling the team that our code is ready to be peer-reviewed and, if it’s good, merged into the main master branch.
You will remember that in the previous section, we created a branch and added all our new features to the branch. Then we committed those changes to Git (locally) before pushing them up to GitHub.
To create a pull request, click the Git menu in Visual Studio and select GitHub ➤ New Pull Request.
You will see that (Figure 5-34) you are taken to GitHub where you can now create a pull request by clicking the “Create pull request” button. Before doing that, select a reviewer (in this case, the acsharpdev user) and enter some pull request details (Figure 5-35).
When you have added all the required details, you click the Create pull request button. This pull request will now go to the acsharpdev user where he can review my code, add comments, and hopefully approve my changes.
When the pull request is successfully created, you will see the pull request by going to the Pull requests tab on GitHub (Figure 5-36).
On the other side of the continent, the acsharpdev user has just finished working on some code and sees my pull request on GitHub under the Review requests tab (Figure 5-37).
He can now click the pull request that I created to view the details (Figure 5-38).
By clicking the Files changed tab (Figure 5-39), he can see that I only added a new class called CoolFeatureClass.
Clicking the new class I added, John will not see a diff (because this is a new class), but he is still able to review the code.
Hovering your mouse over the code, you will see a plus sign appear (Figure 5-40).
Clicking the plus sign will allow him to add a comment to the code I have added (Figure 5-41). Once the comments have been added, I can see these in the pull request I created on GitHub (Figure 5-42).
This allows me to see the comments John added and take any action if needed. I can now reply to the comment as seen in Figure 5-43.
He can now click the Resolve conversation button under the Conversation tab and then approve the pull request (Figure 5-44).
When the conversation is resolved, the pull request can be merged into the master branch. For this, we need to click the Merge pull request button on GitHub to do the merge as seen in Figure 5-45.
Looking at Figure 5-46, you will see that we have three options when clicking the Merge pull request drop-down. These are
Create a merge commit
Squash and merge
Rebase and merge
The default option is Create a merge commit and will take the commits from the pull request and merge them into the master branch creating a new commit in a merge commit. Squashing is a lot like rebasing a branch, because you can take a multiple commit pull request and squash it down into a single commit. Rebasing, on the other hand, provides a way to keep the Git history clean by taking the feature branch and “transplant” the commits on top of the master branch.
After the merge is complete in GitHub, I can safely delete my SuperCoolFeature branch as seen in Figure 5-47.
I can now switch to my master branch and pull the changes to get the new feature into my local master branch. Switch to your master branch by clicking the branch name in the bottom-right toolbar of Visual Studio and selecting master from there.
Then, click the Fetch arrow in the Git Changes tab and then on the incoming link. There I will see all the incoming commits as seen in Figure 5-48.
Notice that the branch displayed under Branches is the master branch. This is because we switched to our local master branch in Git. The new feature was merged with the remote master branch on GitHub by the acsharpdev user a few minutes ago. I need to pull those changes into my local master branch to get it up to date. To do this, I click the Pull arrow next to the Fetch arrow in the Git Changes tab.
Fetch only downloads the changes from the remote repository (GitHub) but does not integrate the code into your local branch. Fetch just really shows you what changes there are that need to be merged into your local branch.
Pull is used to update your local branch with the latest changes on the remote repository. This merge might potentially result in merge conflicts that you need to resolve before continuing.
After the pull has completed and the changes have been merged into my local master branch, my Solution Explorer will show the new class I added earlier to my feature branch, in my local master (Figure 5-49).
At this point, because the changes have been merged into the master branch, and my local master branch has been updated, I can safely delete the feature branch I created earlier.
Using pull requests allows developers to have a lot more control over the code that gets merged into the main working branch of the project. Using branches allows me to make changes to the code in an isolated manner without risking the stability of the master branch.
Working with Stashes
Sometimes, you might be working on some changes, and you continue to make a whole range of changes without noticing that you are working on the wrong branch.
In Figure 5-50, you can see that we are currently working on the master branch. I should be making all my changes on the NewFeatures branch. This is a very easy mistake to make (perhaps not with the master branch), especially if you are working in several different branches in your code.
Switching to the Git Changes tab, I notice that I have made all my changes on the master branch (Figure 5-51) instead of on the correct NewFeatures branch.
Enter a world of pain, because I now need to backtrack everything I did and remove the code and then go and apply these to the correct branch. This is where stashes come in very handy.
Stashing takes all the changes I have made and puts them away locally (Figure 5-52). It then reverts all the changes I had made to the master branch. This means that I have my master branch back to the way it was before the changes were made.
When I stash my changes, they appear under the Stashes section (Figure 5-53).
I can then go and switch to the correct branch as seen in Figure 5-54.
With my correct branch selected (Figure 5-55), I can view the changes, apply them, pop them, or drop the changes. The options are
Apply – Apply the changes to the branch and keep the stash.
Pop – Apply the changes to the branch and drop the stash.
Drop – This will delete the stash without applying anything.
Stashing allows me to pause the changes I was working with and carry on with something else for a while. Another great example of using stashes is when I am working on a branch, and I need to make a bug fix. I can stash my changes which will revert the code in my branch. Then I can make the bug fix and push that up to the remote repo before popping my stash back to my branch. Stashing allows developers to be very flexible when working with code changes.
Multi-repo Support
A new feature in Visual Studio 2022 is multi-repo support. You can now work in a single solution, with projects hosted in different Git repositories.
At the time of writing this book, multi-repo support had to be enabled from the Preview Features section in the Options window as seen in Figure 5-56.
I have two repositories in GitHub: one for my web application and a second for a Web API project as seen in Figure 5-57. With the multi-repo support option enabled, I can now open my web application in Visual Studio 2022 and then add an existing project by right-clicking the solution and selecting Add ➤ Existing Project and selecting my Web API project.
As seen in Figure 5-58, both my projects across both repositories are loaded in Visual Studio, and the repo in the status bar shows that I am working with two repositories.
As seen in Figure 5-59, I can make changes in both repositories and commit all these changes locally by clicking the Commit All Repos button.
Once these changes are committed locally, I can’t just push them as seen in Figure 5-60. To accomplish this, I need to select the repos individually from the Repos drop-down (Figure 5-61) and push the changes one by one.
Having the ability to work with multiple repositories in Visual Studio is convenient because I no longer need to open a separate instance of Visual Studio to work on a different repository.
Compare Branches
Visual Studio 2022 now allows you to compare branches. This provides a convenient way to see the differences between the two branches you are comparing and will be helpful before creating a pull request, before merging, or even when choosing to delete a branch.
As seen in Figure 5-62, when I click the currently checked out branch (NewFeatures), I can see that I also have a branch called master. To compare the NewFeatures branch with the master branch, right-click the master branch and select Compare with Current Branch from the context menu as seen in Figure 5-63.
Visual Studio will then display a diff between the two branches you selected to compare as seen in Figure 5-64.
I am now able to see exactly what is different between the two branches without leaving Visual Studio.
I can also use the diff configuration options gear in the top-right corner to switch to an inline diff view as seen in Figure 5-65.
Check Out Commit
Visual Studio allows you to check out a specific commit. This can be beneficial because it allows you to go back in time to a previous point in your repo’s history if you need to test a specific section of code. You can also do this for a remote branch, and it saves you from having to create a local branch if you are not planning on adding any new code to it. To do this, open the Git Repository window by selecting the View menu and clicking Git Repository as seen in Figure 5-66.
You can also hold down Ctrl+O, Ctrl+R to open the Git Repository which can be seen in Figure 5-67.
To check out a specific commit, right-click the commit in the Git Repository window as seen in Figure 5-68 and select Checkout (--detach) from the context menu.
Visual Studio now displays a confirmation window (Figure 5-69) to inform you that by checking out this commit, you will be in a detached HEAD state. In other words, your repo’s HEAD will be pointing to a specific commit instead of a branch.
The status bar of Visual Studio will now show that you are currently pointed to a specific commit instead of to a branch (Figure 5-70).
You can now run your tests and modify code as required. You can even commit your code if required. To get back to your branch, simply select it from the branch selector in the Visual Studio status bar.
Line Staging
Also known as interactive staging, line-staging support is helpful when splitting changes across different commits. To enable this Preview Feature, ensure that the Enable line-staging option is enabled from the Preview Features section in the Options window as seen in Figure 5-71.
To see line staging in action, make some changes to one of your files, and then view the file in the Git Changes window as seen in Figure 5-72.
Next, double-click the file that you want to apply line staging to. Visual Studio will display a diff view of the selected file, allowing you to hover over the lines that you want to stage, and stage them individually as seen in Figure 5-73.
Line staging also supports side-by-side and inline diff modes. Being able to stage specific lines of code is a nice feature and allows developers to be quite flexible when committing code.
Summary
Microsoft has added a lot of new features and enhancements to Visual Studio 2022. We had a look at cloning repositories, creating branches, and handling pull requests. Multi-repo support is a fantastic new feature, and being able to compare commits, check out specific commits, and stage specific lines of code without leaving Visual Studio makes for a welcome productivity enhancement. I hope that you will continue exploring Visual Studio and embracing the rich set of features it provides.