Learning outcomes

  • Open a pull request from a branch and describe it so it can be reviewed

  • Review somebody else’s pull request and leave useful comments

  • Explain what a pull request adds that a plain merge does not

  • Apply the review rules used in this course

  • Decide whether a branch or a fork is needed, and open a pull request from a fork

What a pull request is

A pull request is a request to merge a branch, plus a place to discuss it before that happens. Technically it adds nothing to git — you could merge locally. What it adds is a moment where somebody else looks.

pr flow
git switch -c feature/attendance-export
# ... commits ...
git push -u origin feature/attendance-export
gh pr create --fill          # or open it in the web interface
gh pr view --web

Branch or fork: who is allowed to push?

A pull request always says the same thing: "please merge branch X of repository A into branch Y of repository B". Whether A and B are the same repository depends on one question — do you have write access?

Situation What you need

Your team’s project repository, you are a collaborator

a branch in that repository; you can push, so nothing else is required

Somebody else’s repository — the exercise repositories of this course, an open-source project, another team’s repo

a fork: your own copy under your account, because you cannot push to theirs

A fork is a copy of the repository on GitHub, under your own account, with a link back to the original. You have write access to your copy and none to the original — and that is exactly what makes the pull request necessary: it is the mechanism by which somebody without write access can still propose a change.

fork flow
Figure 1. Two repositories, two remotes, one pull request
gh repo fork htl-leonding-example/jg03-syp-git-basics --clone   # fork + clone
cd jg03-syp-git-basics

# after a fork made in the web interface instead:
git clone git@github.com:<you>/jg03-syp-git-basics.git
cd jg03-syp-git-basics
git remote add upstream git@github.com:htl-leonding-example/jg03-syp-git-basics.git

git remote -v          # origin = your fork, upstream = the original
git switch -c feature/exercise-3
# ... commits ...
git push -u origin feature/exercise-3
gh pr create --repo htl-leonding-example/jg03-syp-git-basics --fill

Two remotes, two jobs: origin is your fork — you push there. upstream is the original — you only ever read from it.

Keeping the fork in sync

A fork does not update itself. After a week your main is behind the original, and every branch you start from it carries that gap into the pull request.

git fetch upstream
git switch main
git merge upstream/main      # or, in one step:  gh repo sync
git push                     # your fork's main is level again
git switch -c feature/next   # start the next branch from here

Do this before you start a branch, not after the conflict.

In your own team project you are a collaborator, so a branch is enough and a fork would only add a second copy to keep in step. Fork when you cannot push — which in this course means the exercise repositories, and later every open-source contribution you make.

Writing a pull request others can review

The description answers three questions, in this order:

  1. What does this change, for the user of the system?

  2. Why this way? — the alternative you rejected, in one sentence

  3. How did you check it? — the test, the command, the screenshot

A pull request that says "fixes stuff" forces the reviewer to reconstruct all three. A description of five lines saves twenty minutes of someone else’s time.

Keep it small. A pull request of fifty lines gets a real review; one of two thousand gets "looks good to me", which is not a review, it is a signature.

Reviewing

Useless comment Useful comment

"This is wrong."

"If members is empty this divides by zero — line 42. Add a guard or return 0."

"I don’t like this name."

"`data` here is a list of bookings; bookings would save the next reader a lookup."

"LGTM" after ten seconds

"Checked the CSV export against the sample file; the date column is off by a day in the DST week."

Review the change, not the person. Say what you checked, so the author knows what was not checked. And approve only what you actually understood — an approval is a statement about your reading, not about your trust in the author.

Decisions

  • Everything reaches main through a pull request, including documentation.

  • Exercise repositories are forked; the project repository is not — there everybody is a collaborator and works on branches.

  • At least one review from another team member before merging.

  • CI must be green before merging. A red build is not merged "and fixed later".

  • Pull requests stay small enough to read in one sitting.

Pitfalls

  • Approving without reading. The review then certifies nothing, and everyone behaves as if it had.

  • A pull request that mixes a rename with a behaviour change. The diff hides the behaviour change inside three hundred renamed lines.

  • Answering review comments by force-pushing a rewritten branch. The reviewer loses the thread of what changed since their comment.

  • Leaving pull requests open for a week. The branch drifts from main and the merge becomes a conflict exercise.

  • Working on main of your own fork. It is your copy, so nothing stops you — and then the pull request contains every commit you ever made and cannot be synced with the original any more.

  • Forgetting the upstream remote. The fork then never catches up, and the pull request arrives with commits the original already has.

  • Opening the pull request against your own fork’s main instead of the original. GitHub preselects the original, but not after you have changed the base once.

Terminology

Deutsch English

Zusammenführungsantrag

pull request

Begutachtung, Durchsicht

review

Freigabe

approval

Rückmeldung

feedback

Änderungsumfang

scope of the change

Abspaltung, eigene Kopie

fork

Gegenstelle

remote

ursprüngliches Repository

upstream

Further reading