In the last chapter, we learn about the typical GitHub workflow; the majority of companies use a variation of this workflow for their day-to-day work. We also learned a lot about branches and how to use them. But there is one thing we didn’t get a chance to review: how to combine those two concepts. The answer is simple: Pull Requests and Code Reviews.
The previous chapter provided a lot of reasons why using a traditional approach to code management (everybody commits to the same branch) is a bad idea. But since we work alone in our current project, we don’t see the inconveniences yet. But they are here, and they take a lot of time to resolve; so, trust me, it’s better to follow the workflow.
This chapter will show you how to implement the workflow that was presented to us in the earlier chapter. We will use our newly created branches to introduce changes to older branches. We will also learn about code review and how to manage them.
Why use Pull Requests?
Many developers who don’t follow a particular workflow say that it’s a waste of time because it takes away precious development time. There is a truth in that statement because following the workflow means waiting for other people to review your code. But you have to keep in mind that you don’t have to wait around doing nothing while waiting for a review, you can directly go on and solve another issue! That’s why branches are so powerful in Version Control Systems ; you can work on multiple issues at the same time. With the workflow, you can begin to work on an issue, ask for some ideas or directive from your peers, and then work on another issue when waiting for responses. After you receive the necessary feedbacks, you can continue to work on the first issue and repeat this process until all the issues are resolved. Using the workflow will also let you begin working on an issue even if the information about what to do is not complete yet; you can work on an issue and stop for more info midway into it. And one last thing: having someone else reread your code is the best way to reduce bugs; the time you gain by not chasing bugs everywhere is greater than the time you gain by directly committing to master.
The GitHub workflow is also the preferred way of work of Open Source contributors. It would be very ugly if anyone could push commits directly to a branch without any review. Instead, each contributor has a working clone of the project and can propose changes that other contributors will review and discuss.
So, in conclusion, working using the GitHub workflow is the best way of working and using it will greatly reduce your bugs. And as we’ve seen in the last chapter, using branches is only the first step, so you have to use Pull Requests to complete the workflow. Let’s learn more about them!
Overview on Pull Requests
Pull Requests, as useful as they are, are a fairly easy-to-understand concept. Submitting a Pull Request, or PR, is just asking for permission to apply all the commits in a branch to another branch. But we’re moving too fast. Before learning about Pull Requests, we have to learn what a “pull” is.
Pull
In Git terminology, a pull is just the opposite of push (give yourself a high five if you guessed that!). Push takes your branch and copies all its commits to a remote branch and creates the branch if it doesn’t exist on the server yet. Pull is just that, but backward: it looks at a remote branch and copies the commits on it to your local repository. It’s just an exchange of commits: push if it’s from local to remote and pull if it’s from remote to local.
Since you have the same commits on your local repository and on GitHub, nothing happened. But once you start working with other people, you will have to pull their branches on your local machine to review their changes or simply review the changes on GitHub.
It’s basically it! Pulling is just copying commits from a remote branch to a local one. And don’t worry, you will have more occasions to play with git pull soon.
What does a PR do
Now that we know more about pulling, we have a clearer idea of what a Pull Request is. A PR is just asking for permission to execute a pull action on a remote repository. But pulling a branch is not enough for the action to be complete: you also have to merge the branches together.
Remember when we merged a patch branch into the development branch? A PR is just asking for permission to do that. You can do everything you want with your local branches, but when you deal with upstream branches (branches in the remote repository), you have to use a little bit of civility and ask for permission first. This assures that every fix committed in the main branches is properly tested and reviewed.
So, to put it together, a Pull Request is a request you make to get GitHub to perform those actions: pull your patching branch and merge it with another branch. For example, in our project, we have currently three local branches (master, develop, and improve-readme-description) and two remote branches (master and develop). If we made any new commits to improve-readme-description and we wanted to merge it with develop, we would open a PR. After the PR is accepted, GitHub will perform the following actions: pull the improve-readme-description branch and then merge it with the develop branch.
You might ask yourself: “If the endgame of a Pull Request is to merge branch, why not call it Merge Request?” Well, many people (including other Git hosting services like GitLab) call it Merge Request. It means the same thing. In this book, we will use the two terms interchangeably.
Create a Pull Request
Let’s get down to business! Creating a new PR is very easy; you just need two branches: one to work on and another to merge into. Let’s do it!
First, let’s create an issue to work on. So go to GitHub and create an issue called “Improve the app style.” Yes, we’ve had a similar issue previously, but since we’ve already solved that issue, we are going to open a new one. It’s not a good idea to recycle issues because it will make it harder to follow your progress.
As you can see on the confirmation message, Git directly shows you a link to follow so you can create a Pull Request. But let’s create a PR with another way: directly on GitHub.
As you change it, notice that the PR name has also changed; that’s because the PR name takes the last commit message as a default name. But you can change it if you want, especially if you have multiple commits in one PR. Remember one thing about PR name: it should be as clear and straight to the point as commit messages. Your PR name should respond to this question: “What will this PR do if I merge it?” So take a good care of your PR name and description so that the reviewers can know which problem you are trying to solve without reading your code.
Again, this view is very similar to its Issues counterpart, even the PR number follow the Issues number. The only difference is the button to merge the pull request. If you click this button, the PR will be accepted, and the branches will be merged. But don’t do that yet! Let’s play around with our PR before merging it.
Now that our PR is submitted, it’s time to review it! Put down your developer hat for a second and put on your tech lead hat, it’s time to do a Code Review!
Code Reviews
Code Reviews are one of the best features of GitHub. Long gone where the days where you had to schedule a one-on-one meeting with your Tech Lead so they could check your code. No need to send each other long chains of emails (with a long list of annoyed people on the Cc list) for each change request in the code. Now, everything is done in GitHub. Let’s see!
Give a Code Review
In Figure 12-9, you had a glimpse of the Code Review process. You saw all the changes done to the files compared to the current version but you couldn’t interact with them yet. In this section, you will learn how to review your co-contributors’ code.
This view should remind you of the git diff results, because it’s essentially the same thing. It shows you the differences between the versions in detail, which means that you will see what has been added, removed, or replaced.
Leave a review comment
The PR details page will show you the different comments left by the reviewer and also the general comments for the whole PR. Let’s resolve these comments.
Update a Pull Request
The comment left by the reviewer suggested that we should change some code before our PR is accepted. So, let’s do that! Let’s update our PR by pushing new commits to the patching branch.
Note
The patching branch is also called topic branch, because each branch should have its own topic to resolve.
Stage the file once again and commit the project with the message: “Make the list items unselectable.” Then, push the branch to GitHub again. Check the previous section if you are lost in this exercise. Hint: git push origin improve-app-style.
After each commit you push, GitHub will update the PR to reflect the changes applied to the branch; click “View changes” to review the new changes. You will once again arrive on the Code Review page but with a little twist: you will only notice the new changes, meaning the changes that you haven’t seen yet. This makes it easier for the reviewer to follow the progression of the PR.
Whether or not you want to delete the branch is up to you. Sometimes, teams don’t delete the branches until a tester has confirmed that all is well.
“But why isn’t my issue automatically closed?” you ask. That’s because the fix in the develop branch, which is not the default branch. Only fixes merged in the default branch (master) will close issues automatically. But since you are worried about that issue, let’s do a little exercise before we go to the next chapter.
EXERCISE: MERGE DEVELOP INTO MASTER
Go back to the project page
Open a PR to merge develop
Accept the PR and merge
Summary
Congratulations on getting your first PRs accepted! (but it would be more impressive if you didn’t accept them yourself). This chapter has been quite long, but you need to understand it completely to benefit from the awesome features of GitHub. For your next issues, open a PR instead of committing directly to master. And remember that in most professional settings, committing on master is not only discouraged but denied by default by GitHub. Each change must come from a Pull Request.
You should be comfortable using PR by now; if not, reread the first sections of this chapter. The one thing to remember is a pull request is just a fancy way of asking for permission to apply commits on a branch.
You may have some questions now: “What if somebody else pushed some changes in the base branch before I complete my PR?”, “What if someone else modified the same file as me?”, or “What if I’m tasked to resolve another issue while I’m working on a PR?” Those questions are very pertinent indeed; that’s why we’ll cover them in the next chapter. We will deal with Merge Conflicts and how to solve them. But before learning how to solve them, we will learn how to avoid them altogether! Let’s go!