Git-Mastery: Lessons

Tour 9: Working with Pull Requests

Target Usage: To contribute to a project using GitHub's pull request mechanism.

Motivation: Pull Request (PR) is the most common way to contribute to a project hosted on GitHub.

Lesson plan:

To propose a contribution to a GitHub project, you can create a pull request.

   T9L1. Creating Pull Requests covers that part.

Another way to contribute to a GitHub project is by giving your inputs via a pull request review.

   T9L2. Reviewing Pull Requests covers that part.

If you have appropriate level of access to a GitHub repo, you can merge pull requests.

   T9L3. Merging Pull Requests covers that part.

T9L1. Creating Pull Requests


To propose a contribution to a GitHub project, you can create a pull request.

This lesson covers that part.

A pull request (PR for short) is a mechanism for contributing code to a remote repo i.e., "I'm requesting you to pull my proposed changes to your repo". It's feature provided by RCS platforms such as GitHub. For this to work, the two repos must have a shared history. The most common case is sending PRs from a fork to its repo.

Suppose you want to propose some changes to a GitHub repo (e.g., samplerepo-pr-practice) as a pull request (PR).

HANDS-ON: Create a PR from the main branch

preparation samplerepo-pr-practice is an unmonitored repo that we have created for you to practice working with PRs.

  • Fork that repo onto your GitHub account.
  • Clone it onto your computer.
  • Commit some changes (e.g., add a new file with some contents) onto the main branch.
  • Push the branch you updated (i.e., main branch or the new branch) to your fork, as explained here.

1 Go to your fork on GitHub.

2 Click on the Pull requests tab followed by the New pull request button. This will bring you to the Compare changes page.

3 Specify the target repo and the branch that should receive your PR, using the base repository and base dropdowns. e.g.,
base repository: se-edu/samplerepo-pr-practice base: main

Normally, the default value shown in the dropdown is what you want but in case your fork has , the default may not be what you want.

4 Indicate which repo:branch contains your proposed code, using the head repository and compare dropdowns. e.g.,
head repository: myrepo/samplerepo-pr-practice compare: main

5 Verify the proposed code: Verify that the diff view in the page shows the exact change you intend to propose. If it doesn't, as necessary.

6 Submit the PR:

  • Click the Create pull request button.
  • Fill in the PR name and description e.g.,
    Name: Add an introduction to the README.md
    Description:
    Add some paragraph to the README.md to explain ...
    Also add a heading ...
    
  • If you want to indicate that the PR you are about to create is 'still work in progress, not yet ready', click on the dropdown arrow in the Create pull request button and choose Create draft pull request option.
  • Click the Create pull request button to create the PR.
  • Go to the receiving repo to verify that your PR appears there in the Pull requests tab.

done!

The next step of the PR lifecycle is the PR review. The members of the repo that received your PR can now review your proposed changes.

  • If they like the changes, they can merge the changes to their repo, which also closes the PR automatically.
  • If they don't like it at all, they can simply close the PR too i.e., they reject your proposed change.
  • In most cases, they will add comments to the PR to suggest further changes. When that happens, GitHub will notify you.

You can update the PR along the way too. Suppose PR reviewers suggested a certain improvement to your proposed code. To update your PR as per the suggestion, you can simply modify the code in your local repo, commit the updated code to the same branch as before, and push to your fork as you did earlier. The PR will auto-update accordingly.

Sending PRs using the main branch is less common than sending PRs using separate branches. For example, suppose you wanted to propose two bug fixes that are not related to each other. In that case, it is more appropriate to send two separate PRs so that each fix can be reviewed, refined, and merged independently. But if you send PRs using the main branch only, both fixes (and any other change you do in the main branch) will appear in the PRs you create from it.

It is possible to create PRs within the same repo too e.g., you can create a PR from branch feature-x to the main branch, within the same repo. Doing so will allow the code to be reviewed by other developers (using PR review mechanism) before it is merged.

DETOUR: Creating PRs from Other Branches

To create another PR while the current PR is still under review, you can create a new branch, add your new proposed change in that branch, and create a new PR using that branch instead of the main branch.

Steps for creating a PR from another branch is similar to how you created one from the main branch, except when sending the PR you should choose the other branch in place of the main branch.


DETOUR: Resolving Merge Conflicts in PRs

Merge conflicts can happen in ongoing PRs, when the receiving branch of the upstream repo has been updated in a way that the PR code conflicts with the latest version of that branch. GitHub indicates such conflicts with the message This branch has conflicts that must be resolved.

Here is the standard way to fix this problem:

  1. Pull the main branch from the upstream repo to your local repo.
    git checkout main
    git pull upstream main
    
  2. In the local repo, attempt to merge the main branch (that you updated in the previous step) onto the PR branch, in order to bring over the new code in the main branch to your PR branch.
    git checkout pr-branch  # assuming pr-branch is the name of branch in the PR
    git merge main
    
  3. The merge you are attempting will run into a merge conflict, due to the aforementioned conflicting code in the main branch. Resolve the conflict manually (this topic is covered elsewhere), and complete the merge.
  4. Push the PR branch to your fork. As the updated code in that branch no longer is conflicting with the main branch, the merge conflict alert in the PR will go away automatically.


T9L2. Reviewing Pull Requests


Another way to contribute to a GitHub project is by giving your inputs via a pull request review.

This lesson covers that part.

PR reviews are a collaborative process in which project members examine and provide feedback on PRs submitted to a remote repo. After an initial review, the reviewer may suggest improvements or identify issues, prompting the submitter to refine and update their code in the PR. This review-refine-update cycle can repeat several times, with reviewers reassessing each new iteration until all feedback is addressed and the code meets the team’s expectations. Once approved, the PR can be merged, making the changes an official part of the codebase.

HANDS-ON: Review a PR

Preparation If you do not have access to a PR that you can review, you can create one for yourself as follows:

  • Create a branch in a repo that you have forked and cloned (e.g., samplerepo-pr-practice).
  • Do some changes in the branch.
  • Push the branch to the remote repo.
  • Create a PR within your fork, from the new branch to the main branch.

1 Locate the PR:

  • Go to the GitHub page of the repo.
  • Click on the Pull requests tab.
  • Click on the PR you want to review.

2Read the PR description. It might contain information relevant to reviewing the PR.

3Click on the Files changed tab to see the diff view.

You can use the following setting to try the two different views available and pick the one you like.

4Add review comments:

  • Hover over the line you want to comment on and click on the icon that appears on the left margin. That should create a text box for you to enter your comment.
    • To give a comment related to multiple lines, click-and-drag the icon. The result will look like this:
  • Enter your comment.
    • This page @SE-EDU/guides has some best practices PR reviewers can follow.
    • To suggest an in-line code change, click on this icon:

      After that, you can proceed to edit the suggestion code block generated by GitHub (as seen in the screenshot above).
      The comment will look like this to the viewers:

  • After typing in the comment, click on the Start a review button (not the Add single comment button. This way, your comment is saved but not visible to others yet. It will be visible to others only when you have finished the entire review.

  • Repeat the above steps to add more comments.

5Submit the review:

  • When there are no more comments to add, click on the Review changes button (on the top right of the diff page).
  • Type in an overall comment about the PR, if any. e.g.,
    Overall, I found your code easy to read for the most part except a few places
    where the nesting was too deep. I noted a few minor coding standard violations
    too. Some of the classes are getting quite long. Consider splitting into
    smaller classes if that makes sense.
    
    LGTM is often used in such overall comments, to indicate Looks good to me (or Looks good to merge).
    nit (as in nit-picking) is another such term, used to indicate minor flaws e.g., LGTM. Just a few nits to fix..
  • Choose Approve, Comment, or Request changes option as appropriate and click on the Submit review button.

done!


T9L3. Merging Pull Requests


If you have appropriate level of access to a GitHub repo, you can merge pull requests.

This lesson covers that part.

A project member with sufficient access to the remote repo can merge a PR, incorporating proposed changes into the main codebase. Merging a PR is similar to performing a Git merge in a local repo, except that it occurs in the remote repository.

HANDS-ON: Merge a PR

Preparation If you would like to try merging a PR yourself, you can create a dummy PR in the following manner.

  • Create a branch in a repo that you have forked and cloned (e.g., samplerepo-pr-practice).
  • Do some changes in the branch.
  • Push the branch to the remote repo.
  • Create a PR within your fork, from the new branch to the main branch.

1 Locate the PR to be merged in your repo's GitHub page.

2 Click on the Conversation tab and scroll to the bottom. You'll see a panel containing the PR status summary.

3 If the PR is not merge-able in the current state, the Merge pull request will not be green. Here are the possible reasons and remedies:

  • Problem: The PR code is out-of-date, indicated by the message This branch is out-of-date with the base branch. That means the repo's main branch has been updated since the PR code was last updated.
    • If the PR author has allowed you to update the PR and you have sufficient permissions, GitHub will allow you to update the PR simply by clicking the Update branch on the right side of the 'out-of-date' error message. If that option is not available, post a message in the PR requesting the PR author to update the PR.
  • Problem: There are merge conflicts, indicated by the message This branch has conflicts that must be resolved. That means the repo's main branch has been updated since the PR code was last updated, in a way that the PR code conflicts with the current main branch. Those conflicts must be resolved before the PR can be merged.
    • If the conflicts are simple, GitHub might allow you to resolve them using the Web interface.
    • If that option is not available, post a message in the PR requesting the PR author to update the PR.

4 Merge the PR by clicking on the Merge pull request button, followed by the Confirm merge button. You should see a Pull request successfully merged and closed message after the PR is merged.

  • You can choose between three merging options by clicking on the down-arrow in the Merge pull request button. If you are new to Git and GitHub, the Create merge commit option is recommended.

done!

After a PR is merged, you need to sync other related repos. Merging a PR simply merges the code in the upstream remote repository in which it was merged. The PR author (and other members of the repo) needs to pull the merged code from the upstream repo to their local repos and push the new code to their respective forks to sync the fork with the upstream repo.


At this point: Now you can contribute to a GitHub project by creating reviewing, and even merging PRs in a GitHub repository.

What's next: Tour 10: Managing Git-Based Projects