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 really 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 2019. We will see how to
Create a GitHub account
Create and clone a repository
How to commit changes to a repository
Create a branch from your code
Creating and handling 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, and create an account by clicking the signup button.
Enter a username (Figure 5-1), e-mail address, and password. After entering your details, you will need to select a subscription. GitHub offers two subscriptions, the free subscription that offers the basics suitable for most developers and a pro subscription. The free subscription is very generous and will appeal to most developers. The free subscription includes
Unlimited public and private repositories
Three collaborators for private repositories
Issues and bug tracking
Project management
The pro subscription, on the other hand, offers more but will be more suited to large teams of developers in an organization. The pro subscription includes
Unlimited public and private repositories
Unlimited collaborators
Issues and bug tracking
Project management
Advanced tools and insights
This will allow a team of developers to work on a private repository for a nominal monthly subscription.
After creating your account on GitHub, you will be sent an e-mail to verify your account with. Clicking the link in this e-mail will take you back to GitHub, 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
Before you start, you need to see if you have installed the GitHub extension for Visual Studio. To do this, you need to run the Visual Studio Installer. To find the Visual Studio Installer, search for it in Windows, or find it under the Windows start menu as seen in Figure 5-3.
Sometimes, the Visual Studio Installer needs to update before running, so you need to give it a few minutes to do this depending on the speed of your Internet connection.
When the Visual Studio Installer has launched, you will see an option to modify your installation of Visual Studio. Click Modify and have a look at the installation details for Visual Studio. The GitHub extension for Visual Studio should be displayed under the Individual components. If you don’t see the GitHub extension here, you will need to install it. To do this, change to the Individual components tab, and check the option to install the GitHub extension for Visual Studio under Code tools.
Once you have installed the GitHub extension, start Visual Studio and open up your solution. For this example, I have just created a small project called MyPetProject as seen in Figure 5-5.
To get started adding this to a new repository, right-click the solution, and click Add Solution to Source Control as seen in Figure 5-6.
This will then create a new 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.
It is, therefore, the logical next step to push your code to a GitHub repository. To do this, you need to open the GitHub tab as seen in Figure 5-8.
If you do not see the GitHub tab, click the View menu, then click Other Windows, and then click GitHub. The tab will tell you that the repository is not yet in GitHub. Change to the Team Explorer tab as seen in Figure 5-9. If you do not see the Team Explorer tab (Ctrl+, Ctrl+M), go to the View menu, and click Team Explorer.
With Team Explorer now open, you will see your local Git repository created earlier on. Under the Hosted Service Providers, you will see the option to sign up to GitHub or connect to GitHub. We have already created a GitHub account in the previous section, so here we will only be connecting to GitHub. Click the Connect link to open up the Connect to GitHub screen as seen in Figure 5-10.
Once you have connected to GitHub, change to the Synchronization section of the Team Explorer window by clicking the Connect header and selecting Sync from the drop-down menu (Figure 5-11).
The Synchronization screen is now displayed as seen in Figure 5-12.
From this screen, we will be publishing our code to GitHub.
If you do not see the option to publish to GitHub, then restart Visual Studio, and go to the Synchronization tab again. The option to publish to GitHub should be displayed after the restart.
To start the process, click the Publish to GitHub button (refer to Figure 5-12). This will then display the publish settings as seen in Figure 5-13.
Here we can select the account we want to use. In my case, it is the account that I created in the previous section and the one that I signed in to my GitHub account with earlier (refer to Figure 5-10).
The repository name should be pre-populated for you from your local repository. You can also add an optional description. Importantly, be sure to check the private repository checkbox if you want to keep your code private. When you are ready, click the Publish button.
Note that if you have two-factor authentication set up, you will be prompted at this point to provide the authentication code from your authenticator application on your mobile phone.
After the repository has been published to GitHub, you will see the new repository if you view your GitHub repositories online as seen in Figure 5-14.
I have some staged changes in my repo. Now I want to commit my code to my new GitHub repository. Switch to the Changes view in Team Explorer, and enter a commit message, and click the Commit Staged button (Figure 5-15).
This will commit the changes locally (Figure 5-16).
Remember, your commit is to your local Git repo. To push the changes to our GitHub repository, change to the Sync view. Do this by clicking the Changes header to view the drop-down menu, and select Sync as seen in Figure 5-17.
The Synchronization view is now displayed (Figure 5-18). Here you will see all the outgoing commits that are yet to be pushed to the server.
Clicking Push will send all the code to the GitHub repository. On GitHub, if you view the code for the repository, you will see the latest changes displayed there.
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. In this example, John has invited me to collaborate on his Pet Project. I will now receive a notification in my inbox that John 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. John 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 or check out code option under the Get started section of the Visual Studio start screen (Figure 5-21).
This will take you to the Clone or check out code screen (Figure 5-22).
From this screen, you can enter the repository location to get the code from, but because I am a collaborator on John’s 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 John invited me 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 and displayed in my Team Explorer (Figure 5-24).
I can now collaborate with John on his Pet project and share my changes with him easily.
Create a Branch from Your Code
John has a new feature that needs to be added to his 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, switch to the Branches view in Team Explorer (Figure 5-26).
I will now create a local branch in Visual Studio. To do this, click the New Branch link 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 Branch 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 particular 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 Team Explorer, change to the Changes view. This will show me all 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 you 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 switch to the Branches view in Team Explorer and expand the remotes/origin folder, you will see that your feature branch has been pushed to the server (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 the server on GitHub.
To create a pull request, change to the GitHub tab. If you do not see the GitHub tab, click the View menu, then click Other Windows, and then click GitHub.
You will see that (Figure 5-34) you can now create a pull request by clicking the “Create a pull request” link. Clicking the pull request link will bring you to a section where you can fill in your 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 John where he can review my code, add comments, and hopefully approve my changes.
When the pull request is successfully created, you will see the notification in Visual Studio.
On the other side of the continent, John has just finished working on some code and sees my pull request in his GitHub tab in Visual Studio (Figure 5-37).
Seeing and approving pull requests in Visual Studio are brand new to 2019. If you are using an older version of Visual Studio, you will need to handle all pull requests in GitHub online.
John can now click the pull request that I created to view the details (Figure 5-38).
In Figure 5-38, John can see that I only added a new class called CoolFeatureClass. He can also see that the .csproj file has changed.
Clicking the .csproj file will display the diff between the file in master and the file in the pull request (Figure 5-39). In fact, John can do this with every file that has been modified. This way, he can clearly see what code has changed and do a review of the code I have added.
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, John will see a plus sign appear (Figure 5-40).
Clicking the plus sign will allow John to add a comment to the code I have added. Once the comments have been added, I can see these in the pull request in Visual Studio (Figure 5-42).
Under Reviewers in Visual Studio, I can see that John has added a comment. I can click the comment to view the details of it (Figure 5-43).
This allows me to see the comments John added and take any action if needed. Referring back to Figure 5-38, John can now click the Add your review link under Reviewers and then approve the pull request (Figure 5-44).
When John clicks the Approve link, the pull request is approved, and we can now merge the changes into the master branch. For this, we need to go to GitHub to do the merge.
By clicking the View on GitHub link (Figure 5-45), John will be taken to GitHub to perform the merge. GitHub will open on the pull request page where he can see the comments that were added. From there he can merge the changes into the master branch (Figure 5-46).
After the merge is complete in GitHub, I can safely delete my branch. When I go and refresh my GitHub tab, I will see that the Pull Request has been merged into the master branch.
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.
You can also switch to the Branches view in Team Explorer and double click the local master branch to switch to it. Then, under the Synchronization tab in Team Explorer, I will see all the incoming commits as seen in Figure 5-48.
Notice that the branch displayed 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 John 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 link.
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 allow developers to have a lot more control over the code that gets merged into the main working branch of the project. Using branches allow 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 actually 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 changes tab in Team Explorer, 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 server before popping my stash back to my branch. Stashing allows developers to be very flexible when working with code changes.