Skip to main content

Git for Authors

Section 4.1 Creating a Pull Request

A pull request is a way for a contributor to provide changes to your project, such as new material, suggestions for changes, or corrections, in an “embargoed” way. This is perfect when the collaborator is a junior partner in your project, or even a total stranger. As an overlord you retain control, and as a contributor you have total freedom to craft your contribution exactly as you think it should be, and to make it extremely easy for an overlord to accept. For the rest of this section, we will stop supposing the project is yours, but instead, we adopt the point-of-view of a collaborator. Here is the suggested setup.
  • As in Chapter 3 there is one “definitive” version of the project as a git repository. It resides on GitHub (see Appendix B). One or more people have control over the definitive repository (the overlords). You do not need to know who the overlords are. Everyone’s goal is to have their changes become part of the definitive repository.
  • Every person who wants to contribute to the project has a fork, which is a git repository under their own personal account on GitHub. (Those mysterious people who have control over the definitive repository: they also have their own forks in their own GitHub accounts.) A fork is a copy of the definitive repository, and your fork is completely under your control.
  • Everyone who wants to contribute to the project also has a copy of their fork on their own computer. (We now know of three copies of the project: definitive, your fork on GitHub, your fork on your computer.) We will refer to this as “the version on your laptop,” although your computer might be a desktop machine, or something in the cloud, or something else. (The technical term for “version on your laptop” is clone, but we will not use that terminology. Keep in mind that the version on your laptop was copied from your fork, not from the definitive repository.)
  • The repository on each contributors’s individual laptop knows about two repositories on GitHub:
    • Their own fork, which is called origin.
    • The definitive repository, which is called upstream.
    Both of these repositories are known and managed as remotes within the repository on the laptop.
To summarize, everyone has a repository on their laptop. Everyone has the same upstream remote: it is the definitive repository. Everyone has a different origin, which is their own personal fork (a repository) in their account on GitHub. Notice that in Chapter 3 the origin remote was the definitive repository, but now origin is a sort of intermediary between the repository on your laptop and upstream, the definitive repository. (See Appendix B for details on forking a project on GitHub and setting up your laptop with a copy.)
Once all of that is set up, you go through the exact same cycle every time you want to contribute changes to the project. You already know how to work with branches, and their usefullness in a personal project, or with a small group. Chapter 6 is devoted entirely to how you can work effectively with a branch.
In a big complicated project, like a calculus textbook, there are lots of different things that may need attention. Maybe you need to put in the solutions to the problems from Chapter 6, or maybe you need to add a new section on the chain rule to Chapter 4, or maybe you need to edit the introduction to Section 5.3.
With branches, you know that you could use your repository to productively work on all three tasks, switching between them at will. You would have three different branches, solutions-chap-6, chain-rule-section, intro-section5-3, and in each branch you would be doing something a bit different.
Why is this good? There are many reasons, two of which are: (i) You do not need to mess up the working version of the book, because you are just working on a copy, and (ii) independent changes can be evaluated independently. Item (ii) suggests the following principle.
This may seem silly if you are thinking in terms of a single person writing a book. But if the writing and editing is a group effort, and many people are contributing, it makes perfect sense for all changes to require at least two people: the person who wrote the new material, and the person who agreed to add that material to the definitive version. Notice that the sections of this chapter are organized exactly according to this principle.
So, you make a branch when you are about to start working on some aspect of the document (Principle 2.2.3). You may work on that branch for just an hour, or for several days, or off-and-on for months. You may switch to working on other branches. If it sounds confusing at first, it will not be confusing once you start doing it, and it is totally worth it. For example, suppose you have finished making the solutions to the problems for Chapter 6. Good, because now you can propose those changes to be included in the definitive repository, and it is no problem that you have not yet finished the other work you are going, because those tasks are on different branches. And if the overlords review your work promptly, that is nice, but if it takes them some time to do that, you are not hung up waiting for their feedback before you can go back to to editing your new section on the chain rule. Juggling several writing tasks has just become a whole lot easier.
One last bit of terminology: proposing that the changes in a branch go into the definitive version is called a pull request. As in, “I request that the overlords pull my changes into the definitive repository.” Once the authorities accept your pull request, the changes from your branch are now incorporated into the definitive repository and part of the official version of the project.
Now that we know the purpose and workflow of a pull request, and how to setup our laptop, let us describe the procedure of making a pull request. Notice that we are leveraging what you already know about branches from Chapter 2 and what you know about pushing and pulling changes from Chapter 3. You will go through the following recipe every time you want to contribute to a project where an overlord will review your contribution.
List 4.1.2. Creating a Pull Request
  1. git checkout master
    git pull upstream master
    Remember that upstream is the name your laptop has for the definitive repository. This checkout and pull will update your local master branch with all of the latest changes that constitute the official version of the project.
  2. git branch <branch_name>
    Initate a new branch, named branch_name. Previously your branch names were disposable, known only to you. They will now becone part of the public workflow for you and the overlords, so concoct something short but descriptive. (You can change this name before making it public, Chapter 6.)
  3. git checkout <branch_name>
    Switch to your new branch, where you are going to work (Principle 2.2.3).
  4. git add <file1> <file2> <file3>
    git commit -m "An informative message"
    Edit files, and accumulate new commits, just like before. When your branch is just the way you would like it to look, it is time to go public. Ready?
  5. git pull upstream master
    While on the <branch_name> branch, you are pulling in any new commits from the master branch of the definitive repository and merging them into your working branch.
    There is the very real possibility of a conflict in this merge. But you would much, much rather discover this yourself now, in the privacy of your own laptop, instead of an overlord getting all geared up to evaluate your public pull request and being immediately stymied by discovering there is a merge conflict that will simply be handed right back to you to resolve. When this happens, the overlord is only going to let you know about it, and then head off to evaluate somebody else’s pull request.
    When you do have a conflict in the merge, head out to List 5.0.2 in Chapter 5 for instructions on resolving it. Now you have done all you can. Your work is all packaged up nicely and consistent with the absolute latest changes in the definitive repository, so you are ready to go public.
  6. git push origin <branch_name>
    Remember that origin is the name your laptop has for your fork of the project in your GitHub account. Now your fork has a new branch, which you would like to see also incorporated into the definitive repository.
  7. Go to your fork on GitHub.
    Use your browser to visit your GitHub account, and locate your fork of the project. GitHub knows that you just put a new branch on that fork, so you should see a prominent green button on the right which says Compare & pull request.
    Click that button and you will see a page with a text box where you can describe the changes you have made. It is considered polite to describe where those changes can be seen (in the final product, not in the source files) so that the reviewer can take a look at the effect of your changes. For example, say something like “New exercises for Chapter 6, see page 88.”
    Click the green create pull request button and you are done. Easy, since GitHub knows who the overlords are and has already been in touch with them about your changes.
  8. git checkout master
    git pull upstream master
    You are ready to start on something new while you wait on the overlords, so these two commands will reset the repository on your laptop to be ready to begin on something new, and update your repository with the latest changes from the definitive repository.

What might happen next?

Hopefully someone with control over the definitive repository will accept your pull request. But maybe they want you to make some changes; perhaps they found a typo or other error. No problem: just checkout your branch again on your laptop, edit to make the corrections, save those changes as a new commit on the branch, and push your branch to your fork (origin). This is the same recipe as in List 4.1.2, except that you skip over the command that actually creates branch_name, since that branch already exists.
Your pull request will be automatically updated and the overlords notified. Notice that we are not changing any commits, just adding to, and extending the branch. And anybody can look and see the record of your original proposal and your response to the overlord’s request. There is a complete record of exactly what decisions were taken and git and GitHub make the mechanics of the collaboration between contributor and overlord very simple.
It may happen that you (the person who created the pull request) are also a person who has control over the definitive repository, i.e. an overlord. In that case you can actually go to the definitive version on GitHub and accept your own pull request. However, many projects adopt the policy that people are not supposed to accept their own pull request, so would frown on this. This sort of policy is a best practice, but is not enforced by git or GitHub, it is a social construct of the organization of your project.
Even if you never aspire to be an overlord, you will find reading the next section is helpful, since it is always a good idea to see what it is like when the shoe is on the other foot. It also explains what you should do as a contributor when the branch in your pull request has a conflict with the master branch due to some changes that were introduced to master between the time you pushed your branch and an overlord got interested in an evaluation.