© Mariot Tsitoara  2020
M. TsitoaraBeginning Git and GitHubhttps://doi.org/10.1007/978-1-4842-5313-7_12

12. Better Project Management: Pull Requests

Mariot Tsitoara1 
(1)
Antananarivo, Madagascar
 

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.

The syntax is very similar too:
$ git pull <remote_name> <branch_name>
So, for example, if you wanted to get the commits from the master branch on GitHub, you would have to execute the command while checking out the master branch:
$ git pull origin master
Make sure to always be on the branch corresponding on the one you are pulling before running any command. So, in this case, you have to check out master before running git pull. After executing the command, you will get a result like mine as shown in Figure 12-1.
../images/484631_1_En_12_Chapter/484631_1_En_12_Fig1_HTML.jpg
Figure 12-1

Pulling master from origin

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.

After you’ve created the issue, it’s time to go back to your Terminal because each PR begins with a branch. We are going to create a branch named “improve-app-style” from the latest development branch, which is develop. As we saw in the last chapter, the way to create a new branch from another is to check out the source branch and execute the branch creation command. So, we have to execute those commands one after another:
$ git checkout develop
$ git branch improve-app-style
$ git checkout improve-app-style
After executing those three commands, you will find yourself with the new branch checked out, just like in Figure 12-2.
../images/484631_1_En_12_Chapter/484631_1_En_12_Fig2_HTML.jpg
Figure 12-2

Creation of a new branch

Within our newly created branch, let’s work on the issue. Open index.html and replace its contents to
<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>TODO list</title>
        <style>
            h1 {
                text-align:center;
            }
            h3 {
                text-transform: uppercase;
            }
            ul {
                margin: 0;
                padding: 0;
            }
            ul li {
                cursor: pointer;
                position: relative;
                padding: 12px 8px 12px 40px;
                background: #eee;
                font-size: 18px;
                transition: 0.2s;
            }
            ul li:nth-child(odd) {
                background: #f9f9f9;
            }
            ul li:hover {
                background: #ddd;
            }
        </style>
    </head>
    <body>
        <h1>TODO list</h1>
        <h3>Todo</h3>
        <ul>
            <li>Buy a hat for the bat</li>
            <li>Clear the fogs for the frogs</li>
            <li>Bring a box to the fox</li>
        </ul>
        <h3>Done</h3>
        <ul>
            <li>Put the mittens on the kittens</li>
        </ul>
    </body>
</html>
Then, stage the file and prepare to commit. Put something very simple as a commit message, no need to reference the issue; we’ll do this later. As a commit message, you can simply put: “Add basic color changes on item rows.” As usual, you will get a confirmation message as shown in Figure 12-3 after the commit.
../images/484631_1_En_12_Chapter/484631_1_En_12_Fig3_HTML.jpg
Figure 12-3

Commit confirmation

Now it’s time to push it to GitHub. As we’ve previously seen, we will have to use the git push command, followed by the remote name and the branch name. So the command will be
$ git push origin improve-app-style
After you’ve pushed your branch to GitHub, you will get another familiar confirmation message. You can check Figure 12-4 for an example of this.
../images/484631_1_En_12_Chapter/484631_1_En_12_Fig4_HTML.jpg
Figure 12-4

Pushing the branch to GitHub

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.

Go to your project page and look for something different in the presentation. After a recent push to a new branch, your project page should like the one shown in Figure 12-5.
../images/484631_1_En_12_Chapter/484631_1_En_12_Fig5_HTML.jpg
Figure 12-5

Project page after a recent push

As you can see, there is a new call to action on the page, right above the list of branches. It shows the name of the branch that you just created and a big button for creating a PR. Click the button to continue; you should get to the Pull Request creation form, just like in Figure 12-6.
../images/484631_1_En_12_Chapter/484631_1_En_12_Fig6_HTML.jpg
Figure 12-6

Pull request creation form

You can note that the PR creation form is very similar to the issue creation form. On the right, you can find the same information about assignees and labels; they work exactly the same. On the bottom of the page, you can see the commits to be applied by the Pull Request; and if you scroll down, you’ll find the differences between the versions. Check Figure 12-7 for an example of this.
../images/484631_1_En_12_Chapter/484631_1_En_12_Fig7_HTML.jpg
Figure 12-7

Differences between versions

But you might ask yourself why there are two commits to be applied. It’s because of the target branch. If you examine Figure 12-6 closely, you’ll find that the base branch for the PR is master. This is not what we want, as we are targeting the develop branch. Go ahead and change the base branch to develop. After you change it, the page will reload, and you’ll get a different result, shown in Figure 12-8.
../images/484631_1_En_12_Chapter/484631_1_En_12_Fig8_HTML.jpg
Figure 12-8

Pull Request on develop

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.

You can expand your PR explanation on the description textbox, and don’t hesitate to provide more information about the changes. You should put the keywords to closing issues there. Check Figure 12-9 for an example of this.
../images/484631_1_En_12_Chapter/484631_1_En_12_Fig9_HTML.jpg
Figure 12-9

A completed Pull Request

Once you are ready, click “Create pull request” to get it done; you will arrive at a page similar to the one shown in Figure 12-10.
../images/484631_1_En_12_Chapter/484631_1_En_12_Fig10_HTML.jpg
Figure 12-10

Your new Pull Request

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.

You can see in Figure 12-10 that the PR page has many sections, just like the Issues page. You have to click “Files changed” to begin the Code Review. You will then arrive at a page similar to the one shown in Figure 12-11.
../images/484631_1_En_12_Chapter/484631_1_En_12_Fig11_HTML.jpg
Figure 12-11

The Code Review section

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

Now, let’s pretend to review this code. During code reviews, you can comment on the whole changes or a specific piece of code. For example, let’s put a comment on the “ul li” CSS definition on line 17. As you move around your cursor on the code review change, a little “plus” icon follows it. It means that you can comment there. Let’s do that. Place your cursor on line 17, and when the “plus” icon shows, click it. It will open a small comment section like in Figure 12-12.
../images/484631_1_En_12_Chapter/484631_1_En_12_Fig12_HTML.jpg
Figure 12-12

A code review on a line

As always, you can make all kinds of comments on this section with the help of Markdown syntax. For this example, we are going to put this comment: “Make the list items unselectable for a cleaner UX. Use `user-select: none`.” You should check the preview before you leave the comment, just like in Figure 12-13.
../images/484631_1_En_12_Chapter/484631_1_En_12_Fig13_HTML.jpg
Figure 12-13

Comment preview

If you are satisfied with your comment, click “Start a review” to go to the next step. The comment will show on the Review page, and there will also be a reply button on the comment, just like the result shown in Figure 12-14.
../images/484631_1_En_12_Chapter/484631_1_En_12_Fig14_HTML.jpg
Figure 12-14

The posted comment

Using this button, the developer can discuss the comment with the reviewer before beginning to rework on the PR. You can make more comments if you want, because comments are essentially what constitute a Code Review. If you are satisfied, click the “Finish your review” button on the top of the page. You will again be greeted with a small section, just like the one shown in Figure 12-15.
../images/484631_1_En_12_Chapter/484631_1_En_12_Fig15_HTML.jpg
Figure 12-15

Finishing the review

Upon finishing the review, you will get three choices: Comment, Approve, or Request changes. Since it’s our own Pull Request, we cannot approve or request change on it, so we’ll just choose the default option, which is a general feedback on the changes. Let’s put: “Don't forget to take account different browsers” as a comment and submit the review. You will once again go back to the PR details page as shown in Figure 12-16.
../images/484631_1_En_12_Chapter/484631_1_En_12_Fig16_HTML.jpg
Figure 12-16

Your completed Code Review

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.

Open index.html once again and change its contents to this:
<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>TODO list</title>
        <style>
            h1 {
                text-align:center;
            }
            h3 {
                text-transform: uppercase;
            }
            ul {
                margin: 0;
                padding: 0;
            }
            ul li {
                cursor: pointer;
                position: relative;
                padding: 12px 8px 12px 40px;
                background: #eee;
                font-size: 18px;
                transition: 0.2s;
                -webkit-user-select: none;
                -moz-user-select: none;
                -ms-user-select: none;
                user-select: none;
            }
            ul li:nth-child(odd) {
                background: #f9f9f9;
            }
            ul li:hover {
                background: #ddd;
            }
        </style>
    </head>
    <body>
        <h1>TODO list</h1>
        <h3>Todo</h3>
        <ul>
            <li>Buy a hat for the bat</li>
            <li>Clear the fogs for the frogs</li>
            <li>Bring a box to the fox</li>
        </ul>
        <h3>Done</h3>
        <ul>
            <li>Put the mittens on the kittens</li>
        </ul>
    </body>
</html>

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 you pushed the branch, go back to the PR page again. You will notice a new comment on the details page. Check Figure 12-17 for an example of this.
../images/484631_1_En_12_Chapter/484631_1_En_12_Fig17_HTML.jpg
Figure 12-17

New changes detected by GitHub

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.

Since we don’t have any additional comments, go ahead and click “Finish review” and then give a general comment. In a work environment, you won’t review your own code so the Approve choice would be available. But since we’re working alone, just give a general comment like “Good job!” since the developer worked really hard. The general comment will appear on the PR details page just like in Figure 12-18.
../images/484631_1_En_12_Chapter/484631_1_En_12_Fig18_HTML.jpg
Figure12-18

A final comment has been made

Now, we can safely merge our branch to the base branch because our code is properly reviewed. Click the big green button to accept and merge the PR. You will be asked for a confirmation before the branch is merged. After you confirm it, the branches will be merged and the PR closed. You can even delete the source branch if you want, just as Figure 12-19 shows.
../images/484631_1_En_12_Chapter/484631_1_En_12_Fig19_HTML.jpg
Figure 12-19

Pull Request accepted

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

Let’s pretend a tester tested our new feature and said that it was okay to release. So, we have to merge develop into master. The exercise is
  • 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!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.223.106.100